From ef8e97b15adba1796f14e6dd5e2ff6302c31ee18 Mon Sep 17 00:00:00 2001 From: Fabian Stamm Date: Tue, 9 Dec 2025 17:48:44 +0100 Subject: [PATCH] Fix typescript not generating ESM and add default values for rust types! --- Cargo.lock | 2 +- Cargo.toml | 2 +- libjrpc/src/compile.rs | 1 + libjrpc/src/targets/mod.rs | 4 ++++ libjrpc/src/targets/rust.rs | 12 +++++++++++- libjrpc/src/targets/typescript.rs | 8 ++------ src/main.rs | 4 ++-- src/test.rs | 14 +++++++++++--- 8 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c976db9..f6bac48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -561,7 +561,7 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jrpc-cli" -version = "0.1.2" +version = "0.1.3" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 65fc17d..3aa514c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "jrpc-cli" -version = "0.1.2" +version = "0.1.3" [workspace] resolver = "2" diff --git a/libjrpc/src/compile.rs b/libjrpc/src/compile.rs index 11261aa..2cae040 100644 --- a/libjrpc/src/compile.rs +++ b/libjrpc/src/compile.rs @@ -88,6 +88,7 @@ impl CompileContext { pub fn write_file(&self, filename: &str, content: &str) -> Result<()> { let res_path = self.output_folder.clone().join(filename); let res_dir = res_path.parent().context("Path has no parent!")?; + log::debug!("Writing to file {:?}", res_path); std::fs::create_dir_all(res_dir)?; std::fs::write(res_path, content)?; Ok(()) diff --git a/libjrpc/src/targets/mod.rs b/libjrpc/src/targets/mod.rs index 720585d..5dad36e 100644 --- a/libjrpc/src/targets/mod.rs +++ b/libjrpc/src/targets/mod.rs @@ -4,6 +4,7 @@ use std::{ }; use anyhow::Result; +use log::debug; use crate::{ compile::{Compile, CompileContext}, @@ -51,6 +52,7 @@ pub fn compile(ir: IR, output: &str) -> Result<()> { for step in ir.steps.iter() { match step { crate::ir::Step::Type(definition) => { + debug!("Generating type {}", definition.name); match compiler.generate_type(&mut ctx, &definition) { Ok(_) => (), Err(err) => { @@ -59,6 +61,7 @@ pub fn compile(ir: IR, output: &str) -> Result<()> { } } crate::ir::Step::Enum(definition) => { + debug!("Generating enum {}", definition.name); match compiler.generate_enum(&mut ctx, &definition) { Ok(_) => (), Err(err) => { @@ -67,6 +70,7 @@ pub fn compile(ir: IR, output: &str) -> Result<()> { } } crate::ir::Step::Service(definition) => { + debug!("Generating service {}", definition.name); match compiler.generate_service(&mut ctx, &definition) { Ok(_) => (), Err(err) => { diff --git a/libjrpc/src/targets/rust.rs b/libjrpc/src/targets/rust.rs index b978c43..d338513 100644 --- a/libjrpc/src/targets/rust.rs +++ b/libjrpc/src/targets/rust.rs @@ -463,7 +463,17 @@ impl Compile for RustCompiler { self.add_dependencies(&mut f, &definition.depends)?; - f.a0("#[derive(Clone, Debug, Serialize, Deserialize)]"); + let only_optional = definition + .fields + .iter() + .find(|f| !f.typ.is_optional()) + .is_none(); + + let derive_default_none = if only_optional { ", Default" } else { "" }; + f.a0(format!( + "#[derive(Clone, Debug, Serialize, Deserialize{})]", + derive_default_none + )); f.a0(format!("pub struct {} {{", definition.name)); for field in definition.fields.iter() { f.a(1, "#[allow(non_snake_case)]"); diff --git a/libjrpc/src/targets/typescript.rs b/libjrpc/src/targets/typescript.rs index 751ea65..c154583 100644 --- a/libjrpc/src/targets/typescript.rs +++ b/libjrpc/src/targets/typescript.rs @@ -435,12 +435,8 @@ import {{ VerificationError }} from \"./ts_base{esm}\"; } impl Compile for TypeScriptCompiler { - fn new(options: &BTreeMap) -> Result { - let flavour = options - .get("flavour") - .cloned() - .unwrap_or_else(|| "node".to_string()); - info!("TypeScript target initialized with flavour: {}", flavour); + fn new(_options: &BTreeMap) -> Result { + info!("TypeScript target initialized with flavour: {}", F::name()); Ok(TypeScriptCompiler { flavour: std::marker::PhantomData, }) diff --git a/src/main.rs b/src/main.rs index 8a7b93e..6119ee5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use libjrpc::{ targets::{ csharp::CSharpCompiler, rust::RustCompiler, - typescript::{Node, TypeScriptCompiler}, + typescript::{Node, TypeScriptCompiler, ESM}, }, FileProcessor, }; @@ -66,7 +66,7 @@ pub fn main() -> Result<()> { libjrpc::targets::compile::>(ir, output_dir)? } "ts-esm" => { - libjrpc::targets::compile::>(ir, output_dir)? + libjrpc::targets::compile::>(ir, output_dir)? } "csharp" => libjrpc::targets::compile::(ir, output_dir)?, _ => { diff --git a/src/test.rs b/src/test.rs index 847f193..eea8ae2 100644 --- a/src/test.rs +++ b/src/test.rs @@ -6,12 +6,12 @@ use std::{ #[test] fn compare_tools() { - let targets = vec!["rust"]; + let targets = vec!["js-esm"]; for target in targets { std::fs::remove_dir_all("./tests").unwrap(); std::fs::create_dir_all("./tests").unwrap(); - Command::new("cargo") + let result1 = Command::new("cargo") .arg("run") .arg("--") .arg("compile") @@ -26,7 +26,11 @@ fn compare_tools() { .wait() .unwrap(); - Command::new("node") + if !result1.success() { + panic!("Failed to generate Rust code"); + } + + let result2 = Command::new("node") .arg("JsonRPC/lib/jrpc.js") .arg("compile") .arg("--verbose") @@ -40,6 +44,10 @@ fn compare_tools() { .wait() .unwrap(); + if !result2.success() { + panic!("Failed to generate JavaScript code"); + } + let rust_files = walkdir::WalkDir::new("tests/rust") .into_iter() .map(|e| e.unwrap())