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

Language specific configs #53

Merged
merged 4 commits into from
Sep 26, 2023
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
33 changes: 29 additions & 4 deletions Cargo.lock

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

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ rustdoc-args = ["--cfg", "docsrs"]

[features]
default = []
javascript = ["specta/typescript"]
javascript = ["specta/javascript"]
typescript = ["specta/typescript"]

[dependencies]
Expand Down Expand Up @@ -46,3 +46,6 @@ members = [
specta = { version = "=2.0.0-rc.2" }
serde = "1.0.188"
tauri = "1.4.1"

[patch.crates-io]
specta = { git = "https://github.com/oscartbeaumont/specta", rev = "efdd024fd1ab2a569ffe9d7fc484c419eb6ef9c5" }
2 changes: 1 addition & 1 deletion examples/custom-plugin/plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
.invoke_handler(plugin_utils.invoke_handler)
.setup(move |app| {
let app = app.clone();
(plugin_utils.setup)(&app.clone());
(plugin_utils.setup)(&app);

std::thread::spawn(move || loop {
RandomNumber(rand::random()).emit_all(&app).unwrap();
Expand Down
38 changes: 17 additions & 21 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
impl EventCollection {
pub fn register<E: Event>(&mut self) {
if !self.0.insert(E::SID) {
panic!("Event {} registered twice!", E::NAME)

Check warning on line 30 in src/event.rs

View workflow job for this annotation

GitHub Actions / clippy

`panic` should not be present in production code

warning: `panic` should not be present in production code --> src/event.rs:30:13 | 30 | panic!("Event {} registered twice!", E::NAME) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#panic note: the lint level is defined here --> src/lib.rs:111:43 | 111 | #![warn(clippy::all, clippy::unwrap_used, clippy::panic | ^^^^^^^^^^^^^
}

if !self.1.insert(E::NAME) {
panic!("Another event with name {} is already registered!", E::NAME)

Check warning on line 34 in src/event.rs

View workflow job for this annotation

GitHub Actions / clippy

`panic` should not be present in production code

warning: `panic` should not be present in production code --> src/event.rs:34:13 | 34 | panic!("Another event with name {} is already registered!", E::NAME) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#panic
}
}
}
Expand All @@ -51,7 +51,7 @@
);
}

pub fn get_or_manage<'a, R: Runtime>(handle: &'a impl Manager<R>) -> tauri::State<'a, Self> {
pub fn get_or_manage<R: Runtime>(handle: &impl Manager<R>) -> tauri::State<'_, Self> {
if handle.try_state::<Self>().is_none() {
handle.manage(Self::default());
}
Expand All @@ -78,7 +78,7 @@
.expect("Failed to read EventRegistry")
.get(&sid)
.copied()
.unwrap_or_else(|| panic!("Event {name} not found in registry!"))

Check warning on line 81 in src/event.rs

View workflow job for this annotation

GitHub Actions / clippy

`panic` should not be present in production code

warning: `panic` should not be present in production code --> src/event.rs:81:28 | 81 | .unwrap_or_else(|| panic!("Event {name} not found in registry!")) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#panic
}

macro_rules! make_handler {
Expand Down Expand Up @@ -146,7 +146,7 @@
{
let meta = get_meta!(handle);

handle.listen_global(&meta.wrap_with_plugin(Self::NAME), make_handler!(handler))
handle.listen_global(meta.wrap_with_plugin(Self::NAME), make_handler!(handler))
}

fn once_global<F, R: Runtime>(handle: &impl Manager<R>, handler: F) -> EventHandler
Expand All @@ -156,7 +156,7 @@
{
let meta = get_meta!(handle);

handle.once_global(&meta.wrap_with_plugin(Self::NAME), make_handler!(handler))
handle.once_global(meta.wrap_with_plugin(Self::NAME), make_handler!(handler))
}

// Window functions
Expand Down Expand Up @@ -198,7 +198,7 @@
{
let meta = get_meta!(window);

window.listen(&meta.wrap_with_plugin(Self::NAME), make_handler!(handler))
window.listen(meta.wrap_with_plugin(Self::NAME), make_handler!(handler))
}

fn once<F>(window: &Window<impl Runtime>, handler: F) -> EventHandler
Expand All @@ -208,7 +208,7 @@
{
let meta = get_meta!(window);

window.once(&meta.wrap_with_plugin(Self::NAME), make_handler!(handler))
window.once(meta.wrap_with_plugin(Self::NAME), make_handler!(handler))
}
}

Expand All @@ -217,11 +217,7 @@
pub typ: DataType,
}

pub(crate) type CollectEventsTuple = (
EventCollection,
Result<Vec<EventDataType>, specta::ExportError>,
specta::TypeMap,
);
pub(crate) type CollectEventsTuple = (EventCollection, Vec<EventDataType>, specta::TypeMap);

#[macro_export]
macro_rules! collect_events {
Expand All @@ -233,19 +229,19 @@
let mut type_map = Default::default();

let event_data_types = [$(
<$event as ::specta::Type>::reference(
::specta::DefOpts {
type_map: &mut type_map,
parent_inline: false
},
&[]
).map(|typ| $crate::EventDataType {
name: <$event as $crate::Event>::NAME,
typ
})
$crate::EventDataType {
name: <$event as $crate::Event>::NAME,
typ: <$event as ::specta::Type>::reference(
::specta::DefOpts {
type_map: &mut type_map,
parent_inline: false
},
&[]
).inner
}
),+]
.into_iter()
.collect::<Result<Vec<_>, _>>();
.collect::<Vec<_>>();

(collection, event_data_types, type_map)
}};
Expand Down
37 changes: 18 additions & 19 deletions src/js.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use crate::{
js_ts::{self, ExportConfig}, EventDataType, ExportLanguage, NoCommands, NoEvents, PluginBuilder,
};
use crate::*;
use heck::ToLowerCamelCase;
use indoc::formatdoc;
use specta::{
functions::FunctionDataType,
ts::{self, js_doc, TsExportError},
TypeMap,
js::{self, ExportError},
};
use tauri::Runtime;

Expand All @@ -19,13 +16,21 @@ pub fn builder<TRuntime: Runtime>() -> PluginBuilder<Language, NoCommands<TRunti

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

pub type ExportConfig = crate::ExportConfig<specta::js_ts::ExportConfig>;

impl ExportLanguage for Language {
type Config = specta::js_ts::ExportConfig;

fn run_format(path: PathBuf, cfg: &ExportConfig) {
cfg.inner.run_format(path).ok();
}

/// Renders a collection of [`FunctionDataType`] into a JavaScript string.
fn render_commands(
commands: &[FunctionDataType],
type_map: &TypeMap,
cfg: &ExportConfig,
) -> Result<String, TsExportError> {
) -> Result<String, ExportError> {
let commands = commands
.iter()
.map(|function| {
Expand All @@ -36,7 +41,7 @@ impl ExportLanguage for Language {
.into_iter()
.chain(function.docs.iter().map(|s| s.to_string()))
.chain(function.args.iter().flat_map(|(name, typ)| {
ts::datatype(&cfg.inner, typ, type_map).map(|typ| {
js::datatype(&cfg.inner, typ, type_map).map(|typ| {
let name = name.to_lower_camel_case();

format!("@param {{ {typ} }} {name}")
Expand All @@ -46,7 +51,7 @@ impl ExportLanguage for Language {
.map(Into::into)
.collect::<Vec<_>>();

js_doc(&vec)
js::js_doc(&vec)
};

Ok(js_ts::function(
Expand All @@ -57,7 +62,7 @@ impl ExportLanguage for Language {
&js_ts::command_body(cfg, function, false),
))
})
.collect::<Result<Vec<_>, TsExportError>>()?
.collect::<Result<Vec<_>, ExportError>>()?
.join(",\n");

Ok(formatdoc! {
Expand All @@ -72,14 +77,14 @@ impl ExportLanguage for Language {
events: &[EventDataType],
type_map: &TypeMap,
cfg: &ExportConfig,
) -> Result<String, TsExportError> {
) -> Result<String, ExportError> {
if events.is_empty() {
return Ok(Default::default());
}

let (events_types, events_map) = js_ts::events_data(events, cfg, type_map)?;

let events = js_doc(
let events = js::js_doc(
&[].into_iter()
.chain(["@type {typeof __makeEvents__<{".to_string()])
.chain(events_types)
Expand All @@ -104,17 +109,11 @@ impl ExportLanguage for Language {
events: &[EventDataType],
type_map: &TypeMap,
cfg: &ExportConfig,
) -> Result<String, TsExportError> {
) -> Result<String, ExportError> {
let dependant_types = type_map
.values()
.filter_map(|v| v.as_ref())
.map(|v| {
ts::named_datatype(&cfg.inner, v, type_map).map(|typ| {
let name = v.name();

js_doc(&[format!("@typedef {{ {typ} }} {name}").into()])
})
})
.map(|v| js::typedef_named_datatype(&cfg.inner, v, type_map))
.collect::<Result<Vec<_>, _>>()
.map(|v| v.join("\n"))?;

Expand Down
48 changes: 12 additions & 36 deletions src/js_ts.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
use std::{borrow::Cow, path::PathBuf};
use std::borrow::Cow;

use heck::ToLowerCamelCase;
use indoc::formatdoc;
use specta::{
functions::FunctionDataType,
ts::{self, TsExportError},
DataType, TypeMap,
};
use specta::{functions::FunctionDataType, js_ts::ExportError, ts, DataType, TypeMap};

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

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::js_ts::ExportConfig>;

pub fn render_all_parts<T: ExportLanguage>(
pub fn render_all_parts<T: ExportLanguage<Config = specta::js_ts::ExportConfig>>(
commands: &[FunctionDataType],
events: &[EventDataType],
type_map: &TypeMap,
cfg: &ExportConfig,
dependant_types: &str,
globals: &str,
) -> Result<String, TsExportError> {
) -> Result<String, ExportError> {
let commands = T::render_commands(commands, type_map, cfg)?;
let events = T::render_events(events, type_map, cfg)?;

Expand Down Expand Up @@ -106,7 +103,7 @@ pub fn handle_result(
function: &FunctionDataType,
type_map: &TypeMap,
cfg: &ExportConfig,
) -> Result<String, TsExportError> {
) -> Result<String, ExportError> {
Ok(match &function.result {
DataType::Result(t) => {
let (t, e) = t.as_ref();
Expand Down Expand Up @@ -150,7 +147,7 @@ pub fn events_types(
events: &[EventDataType],
cfg: &ExportConfig,
type_map: &TypeMap,
) -> Result<Vec<String>, TsExportError> {
) -> Result<Vec<String>, ExportError> {
events
.iter()
.map(|event| {
Expand All @@ -167,39 +164,18 @@ pub fn events_data(
events: &[EventDataType],
cfg: &ExportConfig,
type_map: &TypeMap,
) -> Result<(Vec<String>, String), TsExportError> {
) -> Result<(Vec<String>, String), ExportError> {
Ok((
events_types(events, cfg, type_map)?,
events_map(events, cfg),
))
}

/// The configuration for the generator
#[derive(Default, Clone)]
pub struct ExportConfig {
/// The name of the plugin to invoke.
///
/// If there is no plugin name (i.e. this is an app), this should be `None`.
pub(crate) plugin_name: PluginName,
/// The specta export configuration
pub(crate) inner: specta::ts::ExportConfig,
pub(crate) path: Option<PathBuf>,
pub(crate) header: Cow<'static, str>,
}

impl ExportConfig {
/// Creates a new [`ExportConfiguration`] from a [`specta::ts::ExportConfiguration`]
pub fn new(config: specta::ts::ExportConfig) -> Self {
impl From<specta::js_ts::ExportConfig> for ExportConfig {
fn from(config: specta::js_ts::ExportConfig) -> Self {
Self {
inner: config,
header: CRINGE_ESLINT_DISABLE.into(),
..Default::default()
..Self::new(config)
}
}
}

impl From<specta::ts::ExportConfig> for ExportConfig {
fn from(config: specta::ts::ExportConfig) -> Self {
Self::new(config)
}
}
Loading
Loading