Skip to content

Commit

Permalink
Merge pull request #120 from anatawa12/throw-error-of-result
Browse files Browse the repository at this point in the history
feat: an option to throw error of result
  • Loading branch information
oscartbeaumont authored Aug 4, 2024
2 parents 52228c6 + 07d6293 commit cc11448
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 16 deletions.
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

0 comments on commit cc11448

Please sign in to comment.