Skip to content

Commit

Permalink
upgrade Tauri & Specta
Browse files Browse the repository at this point in the history
  • Loading branch information
oscartbeaumont committed Jul 30, 2024
1 parent 4815678 commit 3fde2c1
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 99 deletions.
34 changes: 30 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]

[features]
javascript = ["specta/typescript", "specta/js_doc"]
typescript = ["specta/typescript", "specta/js_doc"]
javascript = ["dep:specta-typescript"]
typescript = ["dep:specta-typescript"]

[dependencies]
# Public
specta = { workspace = true, features = ["function"] }
specta-typescript = { workspace = true, optional = true }
specta-util = { workspace = true }
tauri-specta-macros = { version = "=2.0.0-rc.5", path = "./macros" }
serde = "1"
serde_json = "1"
Expand All @@ -45,3 +47,10 @@ members = [
[workspace.dependencies]
tauri = { version = "=2.0.0-beta.25" }
specta = { version = "=2.0.0-rc.16" }
specta-util = { version = "0.0.3" }
specta-typescript = { version = "0.0.3" }

[patch.crates-io]
specta = { path = "../specta/specta" }
specta-util = { path = "../specta/specta-util" }
specta-typescript = { path = "../specta/specta-typescript" }
2 changes: 2 additions & 0 deletions examples/app/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ specta = { workspace = true }
serde = { version = "1.0", features = ["derive"] }
tauri = { workspace = true, features = [] }
tauri-specta = { path = "../../../", features = ["typescript", "javascript"] }
specta-util = { workspace = true }
specta-typescript = { workspace = true }
tauri-plugin-os = "^2.0.0-beta.3"
thiserror = "1"

Expand Down
8 changes: 6 additions & 2 deletions examples/app/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
)]

use serde::{Deserialize, Serialize};
use specta::{Type, TypeCollection};
use specta::Type;
use specta_util::TypeCollection;
use tauri_specta::*;
use thiserror::Error;

Expand Down Expand Up @@ -129,7 +130,10 @@ fn main() {
])
.events(tauri_specta::collect_events![crate::DemoEvent, EmptyEvent])
.types(TypeCollection::default().register::<Custom>())
.config(specta::ts::ExportConfig::default().formatter(specta::ts::formatter::prettier))
.config(
specta_typescript::ExportConfig::default()
.formatter(specta_typescript::formatter::prettier),
)
.types(TypeCollection::default().register::<Testing>())
.statics(StaticCollection::default().register("universalConstant", 42))
.header("/* These are my Tauri Specta Bindings! */");
Expand Down
25 changes: 2 additions & 23 deletions macros/src/collect_commands.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use proc_macro2::Ident;
use quote::quote;
use syn::{
parse::{Parse, ParseStream},
Expand All @@ -8,33 +7,19 @@ use syn::{
};

pub struct Input {
type_map: Option<Ident>,
paths: Punctuated<Path, Token![,]>,
}

mod kw {
syn::custom_keyword!(type_map);
}

impl Parse for Input {
fn parse(input: ParseStream) -> syn::Result<Self> {
Ok(Self {
type_map: {
if input.peek(kw::type_map) && input.peek2(Token![:]) {
input.parse::<kw::type_map>()?;
input.parse::<Token![:]>()?;
Some(input.parse()?)
} else {
None
}
},
paths: Punctuated::parse_terminated(input)?,
})
}
}

pub fn proc_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let Input { type_map, paths } = parse_macro_input!(input as Input);
let Input { paths } = parse_macro_input!(input as Input);

let tauri_paths = paths.iter().map(|p| {
let Path {
Expand All @@ -47,18 +32,12 @@ pub fn proc_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
quote!(#leading_colon #(#segments)::*)
});

let type_map = type_map
.map(|i| quote!(#i))
.unwrap_or_else(|| quote!(::specta::r#type::TypeMap::default()));

let body = quote! {(
::specta::function::collect_functions![type_map; #paths],
::specta::function::collect_functions![#paths],
::tauri::generate_handler![#(#tauri_paths),*],
)};

quote! {{
let mut type_map = #type_map;

#body
}}
.into()
Expand Down
23 changes: 13 additions & 10 deletions src/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use crate::*;
use heck::ToLowerCamelCase;
use indoc::formatdoc;
use js_ts::unraw;
use specta::{function::FunctionDataType, js_doc, ts};
use specta::datatype;
use specta_typescript as ts;
use specta_typescript::js_doc;
use tauri::Runtime;

/// Implements [`ExportLanguage`] for JS exporting
Expand All @@ -14,7 +16,7 @@ pub fn builder<TRuntime: Runtime>() -> Builder<Language, NoCommands<TRuntime>, N

pub const GLOBALS: &str = include_str!("./globals.js");

type Config = specta::ts::ExportConfig;
type Config = specta_typescript::ExportConfig;

pub type ExportConfig = crate::ExportConfig<Config>;

Expand All @@ -28,7 +30,7 @@ impl ExportLanguage for Language {

/// Renders a collection of [`FunctionDataType`] into a JavaScript string.
fn render_commands(
commands: &[FunctionDataType],
commands: &[datatype::Function],
type_map: &TypeMap,
cfg: &ExportConfig,
) -> Result<String, Self::Error> {
Expand All @@ -40,15 +42,15 @@ impl ExportLanguage for Language {

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

if let Some(d) = &function.deprecated {
if let Some(d) = function.deprecated() {
builder.push_deprecated(d);
}

if !function.docs.is_empty() {
builder.extend(function.docs.split("\n"));
if !function.docs().is_empty() {
builder.extend(function.docs().split("\n"));
}

builder.extend(function.args.iter().flat_map(|(name, typ)| {
builder.extend(function.args().flat_map(|(name, typ)| {
ts::datatype(&cfg.inner, typ, type_map).map(|typ| {
let name = unraw(name).to_lower_camel_case();

Expand All @@ -62,8 +64,9 @@ impl ExportLanguage for Language {

Ok(js_ts::function(
&jsdoc,
&function.name.to_lower_camel_case(),
&js_ts::arg_names(&function.args),
&function.name().to_lower_camel_case(),
// TODO: Don't `collect` the whole thing
&js_ts::arg_names(&function.args().cloned().collect::<Vec<_>>()),
None,
&js_ts::command_body(cfg, function, false),
))
Expand Down Expand Up @@ -112,7 +115,7 @@ impl ExportLanguage for Language {
}

fn render(
commands: &[FunctionDataType],
commands: &[datatype::Function],
events: &[EventDataType],
type_map: &TypeMap,
statics: &StaticCollection,
Expand Down
56 changes: 32 additions & 24 deletions src/js_ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ use std::borrow::Cow;

use heck::ToLowerCamelCase;
use indoc::formatdoc;
use specta::{function::FunctionDataType, ts, ts::ExportError, DataType, TypeMap};
use specta::{datatype, DataType, TypeMap};
use specta_typescript as ts;
use specta_typescript::ExportError;

use crate::{EventDataType, ExportLanguage, ItemType, StaticCollection};

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

pub type ExportConfig = crate::ExportConfig<specta::ts::ExportConfig>;
pub type ExportConfig = crate::ExportConfig<specta_typescript::ExportConfig>;

pub fn render_all_parts<T: ExportLanguage<Config = specta::ts::ExportConfig>>(
commands: &[FunctionDataType],
pub fn render_all_parts<T: ExportLanguage<Config = specta_typescript::ExportConfig>>(
commands: &[datatype::Function],
events: &[EventDataType],
type_map: &TypeMap,
statics: &StaticCollection,
Expand Down Expand Up @@ -107,9 +109,9 @@ fn return_as_result_tuple(expr: &str, as_any: bool) -> String {
)
}

pub fn maybe_return_as_result_tuple(expr: &str, typ: &Option<DataType>, as_any: bool) -> String {
pub fn maybe_return_as_result_tuple(expr: &str, typ: Option<&DataType>, as_any: bool) -> String {
match typ {
Some(DataType::Result(_)) => return_as_result_tuple(expr, as_any),
// Some(DataType::Result(_)) => return_as_result_tuple(expr, as_any),
Some(_) => format!("return {expr};"),
None => format!("{expr};"),
}
Expand Down Expand Up @@ -142,34 +144,40 @@ fn tauri_invoke(name: &str, arg_usages: Option<String>) -> String {
}

pub fn handle_result(
function: &FunctionDataType,
function: &datatype::Function,
type_map: &TypeMap,
cfg: &ExportConfig,
) -> Result<String, ExportError> {
Ok(match &function.result {
Some(DataType::Result(t)) => {
let (t, e) = t.as_ref();

format!(
"Result<{}, {}>",
ts::datatype(&cfg.inner, t, type_map)?,
ts::datatype(&cfg.inner, e, type_map)?
)
}
Ok(match &function.result() {
// Some(DataType::Result(t)) => {
// let (t, e) = t.as_ref();

// format!(
// "Result<{}, {}>",
// ts::datatype(&cfg.inner, t, type_map)?,
// ts::datatype(&cfg.inner, e, type_map)?
// )
// }
Some(t) => ts::datatype(&cfg.inner, t, type_map)?,
None => "void".to_string(),
})
}

pub fn command_body(cfg: &ExportConfig, function: &FunctionDataType, as_any: bool) -> String {
pub fn command_body(cfg: &ExportConfig, function: &datatype::Function, as_any: bool) -> String {
let name = cfg
.plugin_name
.map(|n| n.apply_as_prefix(&function.name, ItemType::Command))
.unwrap_or_else(|| function.name.to_string());
.map(|n| n.apply_as_prefix(&function.name(), ItemType::Command))
.unwrap_or_else(|| function.name().to_string());

maybe_return_as_result_tuple(
&tauri_invoke(&name, arg_usages(&arg_names(&function.args))),
&function.result,
&tauri_invoke(
&name,
arg_usages(&arg_names(
// TODO: Don't collect
&function.args().cloned().collect::<Vec<_>>(),
)),
),
function.result(),
as_any,
)
}
Expand Down Expand Up @@ -218,8 +226,8 @@ pub fn events_data(
))
}

impl From<specta::ts::ExportConfig> for ExportConfig {
fn from(config: specta::ts::ExportConfig) -> Self {
impl From<specta_typescript::ExportConfig> for ExportConfig {
fn from(config: specta_typescript::ExportConfig) -> Self {
Self {
header: CRINGE_ESLINT_DISABLE.into(),
..Self::new(config)
Expand Down
Loading

0 comments on commit 3fde2c1

Please sign in to comment.