Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: an option to throw error of result #120

Merged
merged 3 commits into from
Aug 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/custom-plugin/app/src-tauri/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fn main() {
tauri_build::build()
tauri_build::build()
}
14 changes: 12 additions & 2 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ use std::{
path::Path,
};

use crate::{
event::EventRegistryMeta, Commands, ErrorHandlingMode, EventRegistry, Events, LanguageExt,
};
use serde::Serialize;
use specta::{
datatype::{DataType, Function},
NamedType, SpectaID, Type, TypeMap,
};
use tauri::{ipc::Invoke, Manager, Runtime};

use crate::{event::EventRegistryMeta, Commands, EventRegistry, Events, LanguageExt};

/// Builder for configuring Tauri Specta in your application.
///
/// # Example
Expand Down Expand Up @@ -55,6 +56,7 @@ pub struct Builder<R: Runtime = tauri::Wry> {
plugin_name: Option<&'static str>,
commands: Commands<R>,
command_types: Vec<Function>,
error_handling: ErrorHandlingMode,
events: BTreeMap<&'static str, DataType>,
event_sids: BTreeSet<SpectaID>,
types: TypeMap,
Expand All @@ -67,6 +69,7 @@ impl<R: Runtime> Default for Builder<R> {
plugin_name: None,
commands: Commands::default(),
command_types: Default::default(),
error_handling: Default::default(),
events: Default::default(),
event_sids: Default::default(),
types: TypeMap::default(),
Expand Down Expand Up @@ -147,6 +150,12 @@ impl<R: Runtime> Builder<R> {
self
}

/// Set the error handling mode for the generated bindings.
pub fn error_handling(mut self, error_handling: ErrorHandlingMode) -> Self {
self.error_handling = error_handling;
self
}

// TODO: Maybe method to merge in a `TypeCollection`

// TODO: Should we put a `.build` command here to ensure it's immutable from now on?
Expand Down Expand Up @@ -185,6 +194,7 @@ impl<R: Runtime> Builder<R> {
language.render(&crate::ExportContext {
// TODO: Don't clone stuff
commands: self.command_types.clone(),
error_handling: self.error_handling,
events: self.events.clone(),
type_map: self.types.clone(),
constants: self.constants.clone(),
Expand Down
5 changes: 3 additions & 2 deletions src/lang/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ fn render_commands(ts: &Typescript, cfg: &ExportContext) -> Result<String, Expor
.iter()
.map(|function| {
let jsdoc = {
let ret_type = js_ts::handle_result(function, &cfg.type_map, ts)?;
let ret_type =
js_ts::handle_result(function, &cfg.type_map, ts, cfg.error_handling)?;

let mut builder = js_doc::Builder::default();

Expand Down Expand Up @@ -70,7 +71,7 @@ fn render_commands(ts: &Typescript, cfg: &ExportContext) -> Result<String, Expor
// TODO: Don't `collect` the whole thing
&js_ts::arg_names(&function.args().cloned().collect::<Vec<_>>()),
None,
&js_ts::command_body(&cfg.plugin_name, function, false),
&js_ts::command_body(&cfg.plugin_name, &function, false, cfg.error_handling),
))
})
.collect::<Result<Vec<_>, ExportError>>()?
Expand Down
32 changes: 23 additions & 9 deletions src/lang/js_ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use specta::{
use specta_typescript::{self as ts};
use specta_typescript::{ExportError, Typescript};

use crate::{apply_as_prefix, ExportContext, ItemType, LanguageExt};
use crate::{apply_as_prefix, ErrorHandlingMode, ExportContext, ItemType, LanguageExt};

const DO_NOT_EDIT: &str = "// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually.";

Expand Down Expand Up @@ -104,9 +104,15 @@ pub fn maybe_return_as_result_tuple(
expr: &str,
typ: Option<&FunctionResultVariant>,
as_any: bool,
error_handling: ErrorHandlingMode,
) -> String {
match typ {
Some(FunctionResultVariant::Result(_, _)) => return_as_result_tuple(expr, as_any),
Some(FunctionResultVariant::Result(_, _)) => match error_handling {
ErrorHandlingMode::Throw => {
format!("return {expr};")
}
ErrorHandlingMode::Result => return_as_result_tuple(expr, as_any),
},
Some(FunctionResultVariant::Value(_)) => format!("return {expr};"),
None => format!("{expr};"),
}
Expand Down Expand Up @@ -141,15 +147,21 @@ pub fn handle_result(
function: &datatype::Function,
type_map: &TypeMap,
cfg: &Typescript,
error_handling: ErrorHandlingMode,
) -> Result<String, ExportError> {
Ok(match &function.result() {
Some(FunctionResultVariant::Result(t, e)) => {
format!(
"Result<{}, {}>",
ts::datatype(cfg, &FunctionResultVariant::Value(t.clone()), type_map)?,
ts::datatype(cfg, &FunctionResultVariant::Value(e.clone()), type_map)?
)
}
Some(FunctionResultVariant::Result(t, e)) => match error_handling {
ErrorHandlingMode::Result => {
format!(
"Result<{}, {}>",
ts::datatype(cfg, &FunctionResultVariant::Value(t.clone()), type_map)?,
ts::datatype(cfg, &FunctionResultVariant::Value(e.clone()), type_map)?
)
}
ErrorHandlingMode::Throw => {
ts::datatype(cfg, &FunctionResultVariant::Value(t.clone()), type_map)?
}
},
Some(FunctionResultVariant::Value(t)) => {
ts::datatype(cfg, &FunctionResultVariant::Value(t.clone()), type_map)?
}
Expand All @@ -161,6 +173,7 @@ pub fn command_body(
plugin_name: &Option<&'static str>,
function: &datatype::Function,
as_any: bool,
error_handling: ErrorHandlingMode,
) -> String {
let name = plugin_name
.as_ref()
Expand All @@ -177,6 +190,7 @@ pub fn command_body(
),
function.result(),
as_any,
error_handling,
)
}

Expand Down
4 changes: 2 additions & 2 deletions src/lang/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn render_commands(ts: &Typescript, cfg: &ExportContext) -> Result<String, Expor
})
.collect::<Result<Vec<_>, _>>()?;

let ret_type = js_ts::handle_result(function, &cfg.type_map, ts)?;
let ret_type = js_ts::handle_result(function, &cfg.type_map, ts, cfg.error_handling)?;

let docs = {
let mut builder = js_doc::Builder::default();
Expand All @@ -64,7 +64,7 @@ fn render_commands(ts: &Typescript, cfg: &ExportContext) -> Result<String, Expor
&function.name().to_lower_camel_case(),
&arg_defs,
Some(&ret_type),
&js_ts::command_body(&cfg.plugin_name, function, true),
&js_ts::command_body(&cfg.plugin_name, function, true, cfg.error_handling),
))
})
.collect::<Result<Vec<_>, ExportError>>()?
Expand Down
11 changes: 11 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ pub struct Events(BTreeMap<&'static str, fn(&mut TypeMap) -> (SpectaID, DataType
pub struct ExportContext {
pub plugin_name: Option<&'static str>,
pub commands: Vec<datatype::Function>,
pub error_handling: ErrorHandlingMode,
pub events: BTreeMap<&'static str, DataType>,
pub type_map: TypeMap,
pub constants: HashMap<Cow<'static, str>, serde_json::Value>,
Expand Down Expand Up @@ -288,6 +289,16 @@ pub(crate) fn apply_as_prefix(plugin_name: &str, s: &str, item_type: ItemType) -
)
}

/// The mode which the error handling is done in the bindings.
#[derive(Debug, Default, Copy, Clone)]
pub enum ErrorHandlingMode {
/// Errors will be thrown
Throw,
/// Errors will be returned as a Result enum
#[default]
Result,
}

#[doc(hidden)]
pub mod internal {
//! Internal logic for Tauri Specta.
Expand Down