From 8cf96595d7928950d45a9024f2fcc55eae8e0ab0 Mon Sep 17 00:00:00 2001 From: Oscar Beaumont Date: Thu, 1 Aug 2024 16:26:20 +0800 Subject: [PATCH] Cleanup `LanguageExt` --- src/lang/js.rs | 175 ++++++++++++++++++++++++---------------------- src/lang/js_ts.rs | 7 +- src/lang/ts.rs | 133 ++++++++++++++++++----------------- src/lib.rs | 10 --- 4 files changed, 163 insertions(+), 162 deletions(-) diff --git a/src/lang/js.rs b/src/lang/js.rs index 6277ed7..8698ac7 100644 --- a/src/lang/js.rs +++ b/src/lang/js.rs @@ -1,6 +1,6 @@ use heck::ToLowerCamelCase; use specta::datatype::FunctionResultVariant; -use specta_typescript::js_doc; +use specta_typescript::{js_doc, ExportError, Typescript}; use crate::{ExportContext, LanguageExt}; @@ -9,97 +9,104 @@ use super::js_ts; const GLOBALS: &str = include_str!("./globals.js"); impl LanguageExt for specta_jsdoc::JSDoc { - fn render_commands(&self, cfg: &ExportContext) -> Result { - let commands = cfg - .commands + fn render(&self, cfg: &ExportContext) -> Result { + let dependant_types = cfg + .type_map .iter() - .map(|function| { - let jsdoc = { - let ret_type = js_ts::handle_result(function, &cfg.type_map, &self.0)?; - - let mut builder = js_doc::Builder::default(); - - if let Some(d) = function.deprecated() { - builder.push_deprecated(d); - } - - if !function.docs().is_empty() { - builder.extend(function.docs().split("\n")); - } - - builder.extend(function.args().flat_map(|(name, typ)| { - specta_typescript::datatype( - &self.0, - &FunctionResultVariant::Value(typ.clone()), - &cfg.type_map, - ) - .map(|typ| { - let name = name.to_lower_camel_case(); - - format!("@param {{ {typ} }} {name}") - }) - })); - builder.push(&format!("@returns {{ Promise<{ret_type}> }}")); - - builder.build() - }; - - Ok(js_ts::function( - &jsdoc, - &function.name().to_lower_camel_case(), - // TODO: Don't `collect` the whole thing - &js_ts::arg_names(&function.args().cloned().collect::>()), - None, - &js_ts::command_body(&cfg.plugin_name, function, false), - )) - }) - .collect::, Self::Error>>()? - .join(",\n"); - - Ok(format!( - r#"export const commands = {{ - {commands} -}}"# - )) - } + .map(|(_sid, ndt)| js_doc::typedef_named_datatype(&self.0, ndt, &cfg.type_map)) + .collect::, _>>() + .map(|v| v.join("\n"))?; - fn render_events(&self, cfg: &ExportContext) -> Result { - if cfg.events.is_empty() { - return Ok(Default::default()); - } + js_ts::render_all_parts::( + cfg, + &dependant_types, + GLOBALS, + &self.0.header, + render_commands(&self.0, cfg)?, + render_events(&self.0, cfg)?, + ) + } +} - let (events_types, events_map) = - js_ts::events_data(&cfg.events, &self.0, &cfg.plugin_name, &cfg.type_map)?; +fn render_commands(ts: &Typescript, cfg: &ExportContext) -> Result { + let commands = cfg + .commands + .iter() + .map(|function| { + let jsdoc = { + let ret_type = js_ts::handle_result(function, &cfg.type_map, ts)?; + + let mut builder = js_doc::Builder::default(); + + if let Some(d) = function.deprecated() { + builder.push_deprecated(d); + } + + if !function.docs().is_empty() { + builder.extend(function.docs().split("\n")); + } + + builder.extend(function.args().flat_map(|(name, typ)| { + specta_typescript::datatype( + ts, + &FunctionResultVariant::Value(typ.clone()), + &cfg.type_map, + ) + .map(|typ| { + let name = name.to_lower_camel_case(); + + format!("@param {{ {typ} }} {name}") + }) + })); + builder.push(&format!("@returns {{ Promise<{ret_type}> }}")); + + builder.build() + }; + + Ok(js_ts::function( + &jsdoc, + &function.name().to_lower_camel_case(), + // TODO: Don't `collect` the whole thing + &js_ts::arg_names(&function.args().cloned().collect::>()), + None, + &js_ts::command_body(&cfg.plugin_name, function, false), + )) + }) + .collect::, _>>()? + .join(",\n"); + + Ok(format!( + r#"export const commands = {{ + {commands} + }}"# + )) +} - let events = { - let mut builder = js_doc::Builder::default(); +fn render_events(ts: &Typescript, cfg: &ExportContext) -> Result { + if cfg.events.is_empty() { + return Ok(Default::default()); + } - builder.push("@type {typeof __makeEvents__<{"); - builder.extend(events_types); - builder.push("}>}"); + let (events_types, events_map) = + js_ts::events_data(&cfg.events, ts, &cfg.plugin_name, &cfg.type_map)?; - builder.build() - }; + let events = { + let mut builder = js_doc::Builder::default(); - Ok(format! { - r#" -{events} -const __typedMakeEvents__ = __makeEvents__; + builder.push("@type {typeof __makeEvents__<{"); + builder.extend(events_types); + builder.push("}>}"); -export const events = __typedMakeEvents__({{ -{events_map} -}})"# - }) - } + builder.build() + }; - fn render(&self, cfg: &ExportContext) -> Result { - let dependant_types = cfg - .type_map - .iter() - .map(|(_sid, ndt)| js_doc::typedef_named_datatype(&self.0, ndt, &cfg.type_map)) - .collect::, _>>() - .map(|v| v.join("\n"))?; + Ok(format! { + r#" + {events} + const __typedMakeEvents__ = __makeEvents__; - js_ts::render_all_parts::(self, cfg, &dependant_types, GLOBALS, &self.0.header) - } + export const events = __typedMakeEvents__({{ + {events_map} + }})"# + }) } diff --git a/src/lang/js_ts.rs b/src/lang/js_ts.rs index af86f90..0a3849a 100644 --- a/src/lang/js_ts.rs +++ b/src/lang/js_ts.rs @@ -18,16 +18,13 @@ use crate::{apply_as_prefix, 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."; pub fn render_all_parts( - language: &L, cfg: &ExportContext, dependant_types: &str, globals: &str, header: &str, + commands: String, + events: String, ) -> Result { - let commands = language.render_commands(&cfg)?; - let events = language.render_events(&cfg)?; - - // TODO: Bring this back let constants = cfg .constants .iter() diff --git a/src/lang/ts.rs b/src/lang/ts.rs index 0b15024..7f911dd 100644 --- a/src/lang/ts.rs +++ b/src/lang/ts.rs @@ -1,91 +1,98 @@ use crate::{lang::js_ts, ExportContext, LanguageExt}; use heck::ToLowerCamelCase; use specta::datatype::FunctionResultVariant; -use specta_typescript as ts; +use specta_typescript::{self as ts, Typescript}; use specta_typescript::{js_doc, ExportError}; const GLOBALS: &str = include_str!("./globals.ts"); impl LanguageExt for specta_typescript::Typescript { - fn render_commands(&self, cfg: &ExportContext) -> Result { - let commands = cfg - .commands + fn render(&self, cfg: &ExportContext) -> Result { + let dependant_types = cfg + .type_map .iter() - .map(|function| { - let arg_defs = function - .args() - .map(|(name, typ)| { - ts::datatype( - self, - &FunctionResultVariant::Value(typ.clone()), - &cfg.type_map, - ) - .map(|ty| format!("{}: {}", name.to_lower_camel_case(), ty)) - }) - .collect::, _>>()?; + .map(|(_sid, ndt)| ts::export_named_datatype(&self, ndt, &cfg.type_map)) + .collect::, _>>() + .map(|v| v.join("\n"))?; + + js_ts::render_all_parts::( + cfg, + &dependant_types, + GLOBALS, + &self.header, + render_commands(self, cfg)?, + render_events(self, cfg)?, + ) + } +} - let ret_type = js_ts::handle_result(function, &cfg.type_map, self)?; +fn render_commands(ts: &Typescript, cfg: &ExportContext) -> Result { + let commands = cfg + .commands + .iter() + .map(|function| { + let arg_defs = function + .args() + .map(|(name, typ)| { + ts::datatype( + ts, + &FunctionResultVariant::Value(typ.clone()), + &cfg.type_map, + ) + .map(|ty| format!("{}: {}", name.to_lower_camel_case(), ty)) + }) + .collect::, _>>()?; - let docs = { - let mut builder = js_doc::Builder::default(); + let ret_type = js_ts::handle_result(function, &cfg.type_map, ts)?; - if let Some(d) = &function.deprecated() { - builder.push_deprecated(d); - } + let docs = { + let mut builder = js_doc::Builder::default(); - if !function.docs().is_empty() { - builder.extend(function.docs().split("\n")); - } + if let Some(d) = &function.deprecated() { + builder.push_deprecated(d); + } - builder.build() - }; - Ok(js_ts::function( - &docs, - &function.name().to_lower_camel_case(), - &arg_defs, - Some(&ret_type), - &js_ts::command_body(&cfg.plugin_name, function, true), - )) - }) - .collect::, ExportError>>()? - .join(",\n"); + if !function.docs().is_empty() { + builder.extend(function.docs().split("\n")); + } + + builder.build() + }; + Ok(js_ts::function( + &docs, + &function.name().to_lower_camel_case(), + &arg_defs, + Some(&ret_type), + &js_ts::command_body(&cfg.plugin_name, function, true), + )) + }) + .collect::, ExportError>>()? + .join(",\n"); - Ok(format! { - r#" + Ok(format! { + r#" export const commands = {{ {commands} }}"# - }) - } + }) +} - fn render_events(&self, cfg: &ExportContext) -> Result { - if cfg.events.is_empty() { - return Ok(Default::default()); - } +fn render_events(ts: &Typescript, cfg: &ExportContext) -> Result { + if cfg.events.is_empty() { + return Ok(Default::default()); + } - let (events_types, events_map) = - js_ts::events_data(&cfg.events, self, &cfg.plugin_name, &cfg.type_map)?; + let (events_types, events_map) = + js_ts::events_data(&cfg.events, ts, &cfg.plugin_name, &cfg.type_map)?; - let events_types = events_types.join(",\n"); + let events_types = events_types.join(",\n"); - Ok(format! { - r#" + Ok(format! { + r#" export const events = __makeEvents__<{{ {events_types} }}>({{ {events_map} }})"# - }) - } - - fn render(&self, cfg: &ExportContext) -> Result { - let dependant_types = cfg - .type_map - .iter() - .map(|(_sid, ndt)| ts::export_named_datatype(&self, ndt, &cfg.type_map)) - .collect::, _>>() - .map(|v| v.join("\n"))?; - - js_ts::render_all_parts::(self, cfg, &dependant_types, GLOBALS, &self.header) - } + }) } diff --git a/src/lib.rs b/src/lib.rs index 182f190..5f3efc7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -192,20 +192,10 @@ pub struct ExportContext { /// - [`specta_typescript::Typescript`] /// - [`specta_jsdoc::JSDoc`] pub trait LanguageExt: Language { - fn render_commands(&self, cfg: &ExportContext) -> Result; - fn render_events(&self, cfg: &ExportContext) -> Result; fn render(&self, cfg: &ExportContext) -> Result; } impl LanguageExt for &L { - fn render_commands(&self, cfg: &ExportContext) -> Result { - (*self).render_commands(cfg) - } - - fn render_events(&self, cfg: &ExportContext) -> Result { - (*self).render_events(cfg) - } - fn render(&self, cfg: &ExportContext) -> Result { (*self).render(cfg) }