From 0d7284829ec10d88588ccd3c5e95008ba0b14610 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 23 Oct 2024 12:10:41 +0200 Subject: [PATCH 01/54] wip: dotnet client gen --- Cargo.lock | 12 + Cargo.toml | 1 + rs/client-gen-dotnet/Cargo.toml | 19 + rs/client-gen-dotnet/src/ctor_generators.rs | 178 +++++++++ rs/client-gen-dotnet/src/events_generator.rs | 97 +++++ rs/client-gen-dotnet/src/helpers.rs | 50 +++ rs/client-gen-dotnet/src/io_generators.rs | 128 +++++++ rs/client-gen-dotnet/src/lib.rs | 176 +++++++++ rs/client-gen-dotnet/src/mock_generator.rs | 64 ++++ rs/client-gen-dotnet/src/root_generator.rs | 53 +++ .../src/service_generators.rs | 141 +++++++ rs/client-gen-dotnet/src/type_generators.rs | 289 ++++++++++++++ rs/client-gen-dotnet/tests/generator.rs | 237 ++++++++++++ .../snapshots/generator__basic_works.snap | 104 ++++++ .../snapshots/generator__basic_works.snap.new | 15 + .../snapshots/generator__events_works.snap | 116 ++++++ .../snapshots/generator__external_types.snap | 86 +++++ .../tests/snapshots/generator__full.snap | 266 +++++++++++++ .../tests/snapshots/generator__full.snap.new | 27 ++ .../generator__full_with_sails_path.snap | 206 ++++++++++ .../generator__multiple_services.snap | 128 +++++++ .../snapshots/generator__nonzero_works.snap | 86 +++++ .../snapshots/generator__rmrk_works.snap | 351 ++++++++++++++++++ 23 files changed, 2830 insertions(+) create mode 100644 rs/client-gen-dotnet/Cargo.toml create mode 100644 rs/client-gen-dotnet/src/ctor_generators.rs create mode 100644 rs/client-gen-dotnet/src/events_generator.rs create mode 100644 rs/client-gen-dotnet/src/helpers.rs create mode 100644 rs/client-gen-dotnet/src/io_generators.rs create mode 100644 rs/client-gen-dotnet/src/lib.rs create mode 100644 rs/client-gen-dotnet/src/mock_generator.rs create mode 100644 rs/client-gen-dotnet/src/root_generator.rs create mode 100644 rs/client-gen-dotnet/src/service_generators.rs create mode 100644 rs/client-gen-dotnet/src/type_generators.rs create mode 100644 rs/client-gen-dotnet/tests/generator.rs create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap.new create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__full.snap create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap diff --git a/Cargo.lock b/Cargo.lock index caa86f2c..9c57bafb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6183,6 +6183,18 @@ dependencies = [ "sails-idl-parser", ] +[[package]] +name = "sails-client-gen-dotnet" +version = "0.6.1" +dependencies = [ + "anyhow", + "convert_case 0.6.0", + "genco", + "insta", + "parity-scale-codec", + "sails-idl-parser", +] + [[package]] name = "sails-idl-gen" version = "0.6.1" diff --git a/Cargo.toml b/Cargo.toml index 8789d8b8..c90ca293 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ members = [ "rs", "rs/cli", "rs/client-gen", + "rs/client-gen-dotnet", "rs/idl-gen", "rs/idl-meta", "rs/idl-parser", diff --git a/rs/client-gen-dotnet/Cargo.toml b/rs/client-gen-dotnet/Cargo.toml new file mode 100644 index 00000000..459cf811 --- /dev/null +++ b/rs/client-gen-dotnet/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "sails-client-gen-dotnet" +description = "Rust .NET client generator for the Sails framework" +documentation = "https://docs.rs/sails-client-gen" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +anyhow.workspace = true +convert-case.workspace = true +genco.workspace = true +parity-scale-codec.workspace = true +sails-idl-parser.workspace = true + +[dev-dependencies] +insta.workspace = true diff --git a/rs/client-gen-dotnet/src/ctor_generators.rs b/rs/client-gen-dotnet/src/ctor_generators.rs new file mode 100644 index 00000000..326899e6 --- /dev/null +++ b/rs/client-gen-dotnet/src/ctor_generators.rs @@ -0,0 +1,178 @@ +use crate::{ + helpers::*, io_generators::generate_io_struct, type_generators::generate_type_decl_code, +}; +use convert_case::{Case, Casing}; +use genco::prelude::*; +use rust::Tokens; +use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; + +pub(crate) struct CtorFactoryGenerator<'a> { + service_name: &'a str, + sails_path: &'a str, + tokens: Tokens, + io_tokens: Tokens, +} + +impl<'a> CtorFactoryGenerator<'a> { + pub(crate) fn new(service_name: &'a str, sails_path: &'a str) -> Self { + Self { + service_name, + sails_path, + tokens: Tokens::new(), + io_tokens: Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> Tokens { + let service_name_snake = self.service_name.to_case(Case::Snake); + quote! { + $(self.tokens) + $['\n'] + pub mod $(service_name_snake)_factory { + use super::*; + pub mod io { + use super::*; + use $(self.sails_path)::calls::ActionIo; + $(self.io_tokens) + } + } + } + } +} + +impl<'a, 'ast> Visitor<'ast> for CtorFactoryGenerator<'a> { + fn visit_ctor(&mut self, ctor: &'ast Ctor) { + quote_in! {self.tokens => + pub struct $(self.service_name)Factory { + #[allow(dead_code)] + remoting: R, + } + + impl $(self.service_name)Factory { + #[allow(unused)] + pub fn new(remoting: R) -> Self { + Self { + remoting, + } + } + } + + impl traits::$(self.service_name)Factory for $(self.service_name)Factory $("{") + type Args = R::Args; + }; + + visitor::accept_ctor(ctor, self); + + quote_in! { self.tokens => + $['\r'] $("}") + }; + } + + fn visit_ctor_func(&mut self, func: &'ast CtorFunc) { + let fn_name = func.name(); + let fn_name_snake = fn_name.to_case(Case::Snake); + let fn_name_snake = fn_name_snake.as_str(); + + for doc in func.docs() { + quote_in! { self.tokens => + $['\r'] $("///") $doc + }; + } + + quote_in! { self.tokens => + $['\r'] fn $fn_name_snake$("(")&self, + }; + + visitor::accept_ctor_func(func, self); + + let args = encoded_args(func.params()); + + let service_name_snake = self.service_name.to_case(Case::Snake); + let params_type = format!("{service_name_snake}_factory::io::{fn_name}"); + + quote_in! { self.tokens => + $(")") -> impl Activation { + RemotingAction::<_, $params_type>::new(self.remoting.clone(), $args) + } + }; + + let route_bytes = path_bytes(fn_name).0; + let struct_tokens = generate_io_struct(fn_name, func.params(), None, route_bytes.as_str()); + + quote_in! { self.io_tokens => + $struct_tokens + }; + } + + fn visit_func_param(&mut self, func_param: &'ast FuncParam) { + let type_decl_code = generate_type_decl_code(func_param.type_decl()); + quote_in! { self.tokens => + $(func_param.name()): $(type_decl_code), + }; + } +} + +pub(crate) struct CtorTraitGenerator { + service_name: String, + tokens: Tokens, +} + +impl CtorTraitGenerator { + pub(crate) fn new(service_name: String) -> Self { + Self { + service_name, + tokens: Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> Tokens { + self.tokens + } +} + +impl<'ast> Visitor<'ast> for CtorTraitGenerator { + fn visit_ctor(&mut self, ctor: &'ast Ctor) { + quote_in! {self.tokens => + #[allow(dead_code)] + pub trait $(&self.service_name)Factory $("{") + type Args; + }; + + visitor::accept_ctor(ctor, self); + + quote_in! {self.tokens => + $['\r'] $("}") + }; + } + + fn visit_ctor_func(&mut self, func: &'ast CtorFunc) { + let fn_name = func.name(); + let fn_name_snake = fn_name.to_case(Case::Snake); + let fn_name_snake = fn_name_snake.as_str(); + + if fn_name_snake == "new" { + quote_in! {self.tokens => + #[allow(clippy::new_ret_no_self)] + #[allow(clippy::wrong_self_convention)] + }; + } + + quote_in! {self.tokens => + $['\r'] fn $fn_name_snake$("(")&self, + }; + + visitor::accept_ctor_func(func, self); + + quote_in! {self.tokens => + $(")") -> impl Activation; + }; + } + + fn visit_func_param(&mut self, func_param: &'ast FuncParam) { + let type_decl_code = generate_type_decl_code(func_param.type_decl()); + + quote_in! { self.tokens => + $(func_param.name()): $(type_decl_code), + }; + } +} diff --git a/rs/client-gen-dotnet/src/events_generator.rs b/rs/client-gen-dotnet/src/events_generator.rs new file mode 100644 index 00000000..f94591b4 --- /dev/null +++ b/rs/client-gen-dotnet/src/events_generator.rs @@ -0,0 +1,97 @@ +use crate::helpers::{method_bytes, path_bytes}; +use genco::prelude::*; +use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; + +pub(crate) struct EventsModuleGenerator<'a> { + service_name: &'a str, + path: &'a str, + sails_path: &'a str, + tokens: rust::Tokens, +} + +impl<'a> EventsModuleGenerator<'a> { + pub(crate) fn new(service_name: &'a str, path: &'a str, sails_path: &'a str) -> Self { + Self { + service_name, + path, + sails_path, + tokens: rust::Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> rust::Tokens { + self.tokens + } +} + +impl<'a, 'ast> Visitor<'ast> for EventsModuleGenerator<'a> { + fn visit_service(&mut self, service: &'ast Service) { + let events_name = format!("{}Events", self.service_name); + let (service_path_bytes, _) = path_bytes(self.path); + let event_names_bytes = service + .events() + .iter() + .map(|e| method_bytes(e.name()).0) + .collect::>() + .join("], &["); + + quote_in! { self.tokens => + $['\n'] + #[allow(dead_code)] + #[cfg(not(target_arch = "wasm32"))] + pub mod events $("{") + use super::*; + use $(self.sails_path)::events::*; + #[derive(PartialEq, Debug, Encode, Decode)] + #[codec(crate = $(self.sails_path)::scale_codec)] + pub enum $(&events_name) $("{") + }; + + visitor::accept_service(service, self); + + quote_in! { self.tokens => + $['\r'] $("}") + }; + + quote_in! { self.tokens => + impl EventIo for $(&events_name) { + const ROUTE: &'static [u8] = &[$service_path_bytes]; + const EVENT_NAMES: &'static [&'static [u8]] = &[&[$event_names_bytes]]; + type Event = Self; + } + + pub fn listener>>(remoting: R) -> impl Listener<$(&events_name)> { + RemotingListener::<_, $(&events_name)>::new(remoting) + } + } + + quote_in! { self.tokens => + $['\r'] $("}") + }; + } + + fn visit_service_event(&mut self, event: &'ast ServiceEvent) { + if let Some(type_decl) = event.type_decl().as_ref() { + for doc in event.docs() { + quote_in! { self.tokens => + $['\r'] $("///") $doc + }; + } + + let type_decl_code = crate::type_generators::generate_type_decl_code(type_decl); + if type_decl_code.starts_with('{') { + quote_in! { self.tokens => + $['\r'] $(event.name()) $(type_decl_code), + }; + } else { + quote_in! { self.tokens => + $['\r'] $(event.name())($(type_decl_code)) , + }; + } + } else { + quote_in! { self.tokens => + $['\r'] $(event.name()), + }; + } + } +} diff --git a/rs/client-gen-dotnet/src/helpers.rs b/rs/client-gen-dotnet/src/helpers.rs new file mode 100644 index 00000000..b58f8ab3 --- /dev/null +++ b/rs/client-gen-dotnet/src/helpers.rs @@ -0,0 +1,50 @@ +use parity_scale_codec::Encode; +use sails_idl_parser::ast::FuncParam; + +pub(crate) fn path_bytes(path: &str) -> (String, usize) { + if path.is_empty() { + (String::new(), 0) + } else { + let service_path_bytes = path.encode(); + let service_path_encoded_length = service_path_bytes.len(); + let mut service_path_bytes = service_path_bytes + .into_iter() + .map(|x| x.to_string()) + .collect::>() + .join(","); + + service_path_bytes.push(','); + + (service_path_bytes, service_path_encoded_length) + } +} + +pub(crate) fn method_bytes(fn_name: &str) -> (String, usize) { + let route_bytes = fn_name.encode(); + let route_encoded_length = route_bytes.len(); + let route_bytes = route_bytes + .into_iter() + .map(|x| x.to_string()) + .collect::>() + .join(","); + + (route_bytes, route_encoded_length) +} + +pub(crate) fn encoded_fn_args(params: &[FuncParam]) -> String { + params + .iter() + .map(|a| a.name()) + .collect::>() + .join(", ") +} + +pub(crate) fn encoded_args(params: &[FuncParam]) -> String { + if params.len() == 1 { + return params[0].name().to_owned(); + } + + let arg_names = encoded_fn_args(params); + + format!("({arg_names})") +} diff --git a/rs/client-gen-dotnet/src/io_generators.rs b/rs/client-gen-dotnet/src/io_generators.rs new file mode 100644 index 00000000..70823ab2 --- /dev/null +++ b/rs/client-gen-dotnet/src/io_generators.rs @@ -0,0 +1,128 @@ +use crate::helpers::*; +use crate::type_generators::generate_type_decl_with_path; +use genco::prelude::*; +use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; + +pub(crate) struct IoModuleGenerator<'a> { + path: &'a str, + sails_path: &'a str, + tokens: rust::Tokens, +} + +impl<'a> IoModuleGenerator<'a> { + pub(crate) fn new(path: &'a str, sails_path: &'a str) -> Self { + Self { + path, + sails_path, + tokens: rust::Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> rust::Tokens { + quote!( + $['\n'] + pub mod io { + use super::*; + use $(self.sails_path)::calls::ActionIo; + $(self.tokens) + } + ) + } +} + +impl<'a, 'ast> Visitor<'ast> for IoModuleGenerator<'a> { + fn visit_service(&mut self, service: &'ast Service) { + visitor::accept_service(service, self); + } + + fn visit_service_func(&mut self, func: &'ast ServiceFunc) { + let fn_name = func.name(); + let (service_path_bytes, _) = path_bytes(self.path); + let (route_bytes, _) = method_bytes(fn_name); + + let struct_tokens = generate_io_struct( + fn_name, + func.params(), + Some(func.output()), + format!("{service_path_bytes}{route_bytes}").as_str(), + ); + + quote_in! { self.tokens => + $struct_tokens + }; + } +} + +pub(crate) fn generate_io_struct( + fn_name: &str, + fn_params: &[FuncParam], + fn_output: Option<&TypeDecl>, + route_bytes: &str, +) -> rust::Tokens { + let params_len = fn_params.len(); + let mut struct_param_tokens = rust::Tokens::new(); + let mut encode_call_args = rust::Tokens::new(); + let mut encode_call_names = rust::Tokens::new(); + for func_param in fn_params { + let type_decl_code = + generate_type_decl_with_path(func_param.type_decl(), "super".to_owned()); + quote_in! { struct_param_tokens => + $(&type_decl_code), + }; + quote_in! { encode_call_args => + $(func_param.name()): $(&type_decl_code), + }; + quote_in! { encode_call_names => + $(func_param.name()), + }; + } + + let param_tokens = match params_len { + 0 => quote!(()), + 1 => quote!($(generate_type_decl_with_path(fn_params[0].type_decl(), "super".to_owned()))), + _ => quote!(($struct_param_tokens)), + }; + + let func_output = fn_output.map_or("()".to_owned(), |output| { + generate_type_decl_with_path(output, "super".to_owned()) + }); + + let encode_call_tokens = match params_len { + 0 => quote!( + impl $fn_name { + #[allow(dead_code)] + pub fn encode_call() -> Vec { + <$fn_name as ActionIo>::encode_call(&()) + } + } + ), + 1 => quote!( + impl $fn_name { + #[allow(dead_code)] + pub fn encode_call($encode_call_args) -> Vec { + <$fn_name as ActionIo>::encode_call(&$(fn_params[0].name())) + } + } + ), + _ => quote!( + impl $fn_name { + #[allow(dead_code)] + pub fn encode_call($encode_call_args) -> Vec { + <$fn_name as ActionIo>::encode_call(&($encode_call_names)) + } + } + ), + }; + + quote! { + pub struct $fn_name (()); + + $encode_call_tokens + + impl ActionIo for $fn_name { + const ROUTE: &'static [u8] = &[$route_bytes]; + type Params = $param_tokens; + type Reply = $func_output; + } + } +} diff --git a/rs/client-gen-dotnet/src/lib.rs b/rs/client-gen-dotnet/src/lib.rs new file mode 100644 index 00000000..6d83d9fc --- /dev/null +++ b/rs/client-gen-dotnet/src/lib.rs @@ -0,0 +1,176 @@ +use anyhow::{Context, Result}; +use convert_case::{Case, Casing}; +use root_generator::RootGenerator; +use sails_idl_parser::ast::visitor; +use std::{collections::HashMap, ffi::OsStr, fs, io::Write, path::Path}; + +mod ctor_generators; +mod events_generator; +mod helpers; +mod io_generators; +mod mock_generator; +mod root_generator; +mod service_generators; +mod type_generators; + +const SAILS: &str = "sails_rs"; + +pub struct IdlPath<'a>(&'a Path); +pub struct IdlString<'a>(&'a str); +pub struct ClientGenerator<'a, S> { + sails_path: Option<&'a str>, + mocks_feature_name: Option<&'a str>, + external_types: HashMap<&'a str, &'a str>, + no_derive_traits: bool, + idl: S, +} + +impl<'a, S> ClientGenerator<'a, S> { + pub fn with_mocks(self, mocks_feature_name: &'a str) -> Self { + Self { + mocks_feature_name: Some(mocks_feature_name), + ..self + } + } + + pub fn with_sails_crate(self, sails_path: &'a str) -> Self { + Self { + sails_path: Some(sails_path), + ..self + } + } + + /// Add an map from IDL type to crate path + /// + /// Instead of generating type in client code, use type path from external crate + /// + /// # Example + /// + /// Following code generates `use my_crate::MyParam as MyFuncParam;` + /// ``` + /// let code = sails_client_gen::ClientGenerator::from_idl("") + /// .with_external_type("MyFuncParam", "my_crate::MyParam"); + /// ``` + pub fn with_external_type(self, name: &'a str, path: &'a str) -> Self { + let mut external_types = self.external_types; + external_types.insert(name, path); + Self { + external_types, + ..self + } + } +} + +impl<'a> ClientGenerator<'a, IdlPath<'a>> { + pub fn from_idl_path(idl_path: &'a Path) -> Self { + Self { + sails_path: None, + mocks_feature_name: None, + external_types: HashMap::new(), + no_derive_traits: false, + idl: IdlPath(idl_path), + } + } + + pub fn generate_to(self, out_path: impl AsRef) -> Result<()> { + let idl_path = self.idl.0; + + let idl = fs::read_to_string(idl_path) + .with_context(|| format!("Failed to open {} for reading", idl_path.display()))?; + + let file_name = idl_path.file_stem().unwrap_or(OsStr::new("service")); + let service_name = file_name.to_string_lossy().to_case(Case::Pascal); + + self.with_idl(&idl) + .generate_to(&service_name, out_path) + .context("failed to generate client")?; + Ok(()) + } + + fn with_idl(self, idl: &'a str) -> ClientGenerator<'a, IdlString<'a>> { + ClientGenerator { + sails_path: self.sails_path, + mocks_feature_name: self.mocks_feature_name, + external_types: self.external_types, + no_derive_traits: self.no_derive_traits, + idl: IdlString(idl), + } + } +} + +impl<'a> ClientGenerator<'a, IdlString<'a>> { + pub fn from_idl(idl: &'a str) -> Self { + Self { + sails_path: None, + mocks_feature_name: None, + external_types: HashMap::new(), + no_derive_traits: false, + idl: IdlString(idl), + } + } + + pub fn generate(self, anonymous_service_name: &str) -> Result { + let idl = self.idl.0; + // let sails_path = self.sails_path.unwrap_or(SAILS); + let mut generator = RootGenerator::new(anonymous_service_name, self.external_types); + let program = sails_idl_parser::ast::parse_idl(idl).context("Failed to parse IDL")?; + visitor::accept_program(&program, &mut generator); + + let code_tokens = generator.finalize(); + let code = code_tokens.to_file_string()?; + + // Check for parsing errors + // let code = pretty_with_rustfmt(&code); + + Ok(code) + } + + pub fn generate_to( + self, + anonymous_service_name: &str, + out_path: impl AsRef, + ) -> Result<()> { + let out_path = out_path.as_ref(); + let code = self + .generate(anonymous_service_name) + .context("failed to generate client")?; + + fs::write(out_path, code).with_context(|| { + format!("Failed to write generated client to {}", out_path.display()) + })?; + + Ok(()) + } +} + +// not using prettyplease since it's bad at reporting syntax errors and also removes comments +// TODO(holykol): Fallback if rustfmt is not in PATH would be nice +fn pretty_with_rustfmt(code: &str) -> String { + use std::process::Command; + let mut child = Command::new("rustfmt") + .arg("--config") + .arg("format_strings=false") + .stdin(std::process::Stdio::piped()) + .stdout(std::process::Stdio::piped()) + .spawn() + .expect("Failed to spawn rustfmt"); + + let child_stdin = child.stdin.as_mut().expect("Failed to open stdin"); + child_stdin + .write_all(code.as_bytes()) + .expect("Failed to write to rustfmt"); + + let output = child + .wait_with_output() + .expect("Failed to wait for rustfmt"); + + if !output.status.success() { + panic!( + "rustfmt failed with status: {}\n{}", + output.status, + String::from_utf8(output.stderr).expect("Failed to read rustfmt stderr") + ); + } + + String::from_utf8(output.stdout).expect("Failed to read rustfmt output") +} diff --git a/rs/client-gen-dotnet/src/mock_generator.rs b/rs/client-gen-dotnet/src/mock_generator.rs new file mode 100644 index 00000000..bacdcdad --- /dev/null +++ b/rs/client-gen-dotnet/src/mock_generator.rs @@ -0,0 +1,64 @@ +use crate::type_generators::generate_type_decl_code; +use convert_case::{Case, Casing}; +use genco::prelude::*; +use rust::Tokens; +use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; + +pub(crate) struct MockGenerator<'a> { + service_name: &'a str, + tokens: rust::Tokens, +} + +impl<'a> MockGenerator<'a> { + pub(crate) fn new(service_name: &'a str) -> Self { + Self { + service_name, + tokens: rust::Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> rust::Tokens { + quote! { + mock! { + pub $(self.service_name) {} + + #[allow(refining_impl_trait)] + #[allow(clippy::type_complexity)] + impl traits::$(self.service_name) for $(self.service_name) { + type Args = A; + $(self.tokens) + } + } + } + } +} + +impl<'a, 'ast> Visitor<'ast> for MockGenerator<'a> { + fn visit_service(&mut self, service: &'ast Service) { + visitor::accept_service(service, self); + } + + fn visit_service_func(&mut self, func: &'ast ServiceFunc) { + let mutability = if func.is_query() { "" } else { "mut" }; + let fn_name = func.name().to_case(Case::Snake); + + let mut params_tokens = Tokens::new(); + for param in func.params() { + let type_decl_code = generate_type_decl_code(param.type_decl()); + quote_in! {params_tokens => + $(param.name()): $(type_decl_code), + }; + } + + let output_type_decl_code = generate_type_decl_code(func.output()); + let output_mock = if func.is_query() { + "MockQuery" + } else { + "MockCall" + }; + + quote_in! { self.tokens=> + fn $fn_name (&$mutability self, $params_tokens) -> $output_mock; + }; + } +} diff --git a/rs/client-gen-dotnet/src/root_generator.rs b/rs/client-gen-dotnet/src/root_generator.rs new file mode 100644 index 00000000..33e02964 --- /dev/null +++ b/rs/client-gen-dotnet/src/root_generator.rs @@ -0,0 +1,53 @@ +use crate::{ + ctor_generators::*, events_generator::*, io_generators::*, mock_generator::MockGenerator, + service_generators::*, type_generators::*, +}; +use convert_case::{Case, Casing}; +use csharp::Tokens; +use genco::prelude::*; +use sails_idl_parser::{ast::visitor::Visitor, ast::*}; +use std::collections::HashMap; + +pub(crate) struct RootGenerator<'a> { + tokens: Tokens, + traits_tokens: Tokens, + mocks_tokens: Tokens, + anonymous_service_name: &'a str, + external_types: HashMap<&'a str, &'a str>, +} + +impl<'a> RootGenerator<'a> { + pub(crate) fn new( + anonymous_service_name: &'a str, + external_types: HashMap<&'a str, &'a str>, + ) -> Self { + Self { + anonymous_service_name, + tokens: Tokens::new(), + traits_tokens: Tokens::new(), + mocks_tokens: Tokens::new(), + external_types, + } + } + + pub(crate) fn finalize(self) -> Tokens { + quote! { + $(self.tokens) + } + } +} + +impl<'a, 'ast> Visitor<'ast> for RootGenerator<'a> { + fn visit_ctor(&mut self, ctor: &'ast Ctor) {} + + fn visit_service(&mut self, service: &'ast Service) {} + + fn visit_type(&mut self, t: &'ast Type) { + if self.external_types.contains_key(t.name()) { + return; + } + let mut type_gen = TopLevelTypeGenerator::new(t.name()); + type_gen.visit_type(t); + self.tokens.extend(type_gen.finalize()); + } +} diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/rs/client-gen-dotnet/src/service_generators.rs new file mode 100644 index 00000000..429ec550 --- /dev/null +++ b/rs/client-gen-dotnet/src/service_generators.rs @@ -0,0 +1,141 @@ +use convert_case::{Case, Casing}; +use genco::prelude::*; +use rust::Tokens; +use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; + +use crate::helpers::*; +use crate::type_generators::generate_type_decl_code; + +/// Generates a trait with service methods +pub(crate) struct ServiceTraitGenerator { + service_name: String, + tokens: Tokens, +} + +impl ServiceTraitGenerator { + pub(crate) fn new(service_name: String) -> Self { + Self { + service_name, + tokens: Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> Tokens { + quote! { + $['\n'] + #[allow(clippy::type_complexity)] + pub trait $(&self.service_name) { + type Args; + $(self.tokens) + } + } + } +} + +impl<'ast> Visitor<'ast> for ServiceTraitGenerator { + fn visit_service(&mut self, service: &'ast Service) { + visitor::accept_service(service, self); + } + + fn visit_service_func(&mut self, func: &'ast ServiceFunc) { + let mutability = if func.is_query() { "" } else { "mut" }; + let fn_name = func.name().to_case(Case::Snake); + + let mut params_tokens = Tokens::new(); + for param in func.params() { + let type_decl_code = generate_type_decl_code(param.type_decl()); + quote_in! {params_tokens => + $(param.name()): $(type_decl_code), + }; + } + + let output_type_decl_code = generate_type_decl_code(func.output()); + let output_trait = if func.is_query() { "Query" } else { "Call" }; + + quote_in! { self.tokens=> + $['\r'] fn $fn_name (&$mutability self, $params_tokens) -> impl $output_trait; + }; + } +} + +/// Generates a client that implements service trait +pub(crate) struct ServiceClientGenerator { + service_name: String, + tokens: Tokens, +} + +impl ServiceClientGenerator { + pub(crate) fn new(service_name: String) -> Self { + Self { + service_name, + tokens: Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> Tokens { + self.tokens + } +} + +// using quote_in instead of tokens.append +impl<'ast> Visitor<'ast> for ServiceClientGenerator { + fn visit_service(&mut self, service: &'ast Service) { + let name = &self.service_name; + + quote_in! {self.tokens => + pub struct $name { + remoting: R, + } + + impl $name { + pub fn new(remoting: R) -> Self { + Self { remoting } + } + } + + impl traits::$name for $name + $("{") + type Args = R::Args; + }; + + visitor::accept_service(service, self); + + quote_in! {self.tokens => + $("}") + }; + } + + fn visit_service_func(&mut self, func: &'ast ServiceFunc) { + let mutability = if func.is_query() { "" } else { "mut" }; + let fn_name = func.name(); + let fn_name_snake = fn_name.to_case(Case::Snake); + + let mut params_tokens = Tokens::new(); + for param in func.params() { + let type_decl_code = generate_type_decl_code(param.type_decl()); + quote_in! {params_tokens => + $(param.name()): $(type_decl_code), + }; + } + + let output_type_decl_code = generate_type_decl_code(func.output()); + let output_trait = if func.is_query() { "Query" } else { "Call" }; + + let args = encoded_args(func.params()); + + let service_name_snake = self.service_name.to_case(Case::Snake); + let params_type = format!("{service_name_snake}::io::{fn_name}"); + + for doc in func.docs() { + quote_in! { self.tokens => + $['\r'] $("///") $doc + }; + } + + quote_in! {self.tokens => + $['\r'] fn $fn_name_snake (&$mutability self, $params_tokens) -> impl $output_trait { + RemotingAction::<_, $params_type>::new(self.remoting.clone(), $args) + } + }; + } +} diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs new file mode 100644 index 00000000..fc1ee8d9 --- /dev/null +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -0,0 +1,289 @@ +use csharp::Tokens; +use genco::prelude::*; +use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; + +pub(crate) fn generate_type_decl_code(type_decl: &TypeDecl) -> String { + let mut type_decl_generator = TypeDeclGenerator::default(); + visitor::accept_type_decl(type_decl, &mut type_decl_generator); + type_decl_generator.code +} + +pub(crate) fn generate_type_decl_with_path(type_decl: &TypeDecl, path: String) -> String { + let mut type_decl_generator = TypeDeclGenerator { + code: String::new(), + path, + }; + visitor::accept_type_decl(type_decl, &mut type_decl_generator); + type_decl_generator.code +} + +pub(crate) struct TopLevelTypeGenerator<'a> { + type_name: &'a str, + tokens: Tokens, +} + +impl<'a> TopLevelTypeGenerator<'a> { + pub(crate) fn new(type_name: &'a str) -> Self { + Self { + type_name, + tokens: Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> Tokens { + self.tokens + } +} + +impl<'a, 'ast> Visitor<'ast> for TopLevelTypeGenerator<'a> { + fn visit_type(&mut self, r#type: &'ast Type) { + for doc in r#type.docs() { + quote_in! { self.tokens => + $['\r'] $("///") $doc + }; + } + visitor::accept_type(r#type, self); + } + + fn visit_struct_def(&mut self, struct_def: &'ast StructDef) { + let mut struct_def_generator = StructDefGenerator::new(self.type_name); + struct_def_generator.visit_struct_def(struct_def); + self.tokens.extend(struct_def_generator.finalize()); + } + + fn visit_enum_def(&mut self, enum_def: &'ast EnumDef) { + let mut enum_def_generator = EnumDefGenerator::new(self.type_name); + enum_def_generator.visit_enum_def(enum_def); + self.tokens.extend(enum_def_generator.finalize()); + } +} + +#[derive(Default)] +struct StructDefGenerator<'a> { + type_name: &'a str, + tokens: Tokens, +} + +impl<'a> StructDefGenerator<'a> { + fn new(type_name: &'a str) -> Self { + Self { + type_name, + tokens: Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> Tokens { + quote! { + public partial record struct $(self.type_name) + { + $(self.tokens) + } + } + } +} + +impl<'ast> Visitor<'ast> for StructDefGenerator<'ast> { + fn visit_struct_def(&mut self, struct_def: &'ast StructDef) { + visitor::accept_struct_def(struct_def, self); + } + + fn visit_struct_field(&mut self, struct_field: &'ast StructField) { + let type_decl_code = generate_type_decl_with_path(struct_field.type_decl(), "".into()); + + for doc in struct_field.docs() { + quote_in! { self.tokens => + $['\r'] $("///") $doc + }; + } + + if let Some(field_name) = struct_field.name() { + quote_in! { self.tokens => + $['\r'] pub $field_name: $type_decl_code, + }; + } else { + quote_in! { self.tokens => + $['\r'] pub $type_decl_code, + }; + } + } +} + +#[derive(Default)] +struct EnumDefGenerator<'a> { + type_name: &'a str, + tokens: Tokens, +} + +impl<'a> EnumDefGenerator<'a> { + pub(crate) fn new(type_name: &'a str) -> Self { + Self { + type_name, + tokens: Tokens::new(), + } + } + + pub(crate) fn finalize(self) -> Tokens { + quote!( + $['\r'] + public enum $(self.type_name) + { + $(self.tokens) + } + ) + } +} + +impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { + fn visit_enum_variant(&mut self, enum_variant: &'ast EnumVariant) { + for doc in enum_variant.docs() { + quote_in! { self.tokens => + $['\r'] $("///") $doc + }; + } + quote_in! { self.tokens => + $['\r'] $(enum_variant.name()), + }; + } +} + +#[derive(Default)] +struct TypeDeclGenerator { + code: String, + path: String, +} + +impl<'ast> Visitor<'ast> for TypeDeclGenerator { + fn visit_optional_type_decl(&mut self, optional_type_decl: &'ast TypeDecl) { + self.code.push_str("Option<"); + visitor::accept_type_decl(optional_type_decl, self); + self.code.push('>'); + } + + fn visit_result_type_decl( + &mut self, + ok_type_decl: &'ast TypeDecl, + err_type_decl: &'ast TypeDecl, + ) { + self.code.push_str("Result<"); + visitor::accept_type_decl(ok_type_decl, self); + self.code.push_str(", "); + visitor::accept_type_decl(err_type_decl, self); + self.code.push('>'); + } + + fn visit_vector_type_decl(&mut self, vector_type_decl: &'ast TypeDecl) { + self.code.push_str("Vec<"); + visitor::accept_type_decl(vector_type_decl, self); + self.code.push('>'); + } + + fn visit_struct_def(&mut self, struct_def: &'ast StructDef) { + let mut struct_def_generator = StructTypeGenerator::new(self.path.clone()); + struct_def_generator.visit_struct_def(struct_def); + self.code.push_str(&struct_def_generator.code); + } + + fn visit_primitive_type_id(&mut self, primitive_type_id: PrimitiveType) { + self.code.push_str(match primitive_type_id { + PrimitiveType::U8 => "u8", + PrimitiveType::U16 => "u16", + PrimitiveType::U32 => "u32", + PrimitiveType::U64 => "u64", + PrimitiveType::U128 => "u128", + PrimitiveType::I8 => "i8", + PrimitiveType::I16 => "i16", + PrimitiveType::I32 => "i32", + PrimitiveType::I64 => "i64", + PrimitiveType::I128 => "i128", + PrimitiveType::Bool => "bool", + PrimitiveType::Str => "String", + PrimitiveType::Char => "char", + PrimitiveType::Null => "()", + PrimitiveType::ActorId => "ActorId", + PrimitiveType::CodeId => "CodeId", + PrimitiveType::MessageId => "MessageId", + PrimitiveType::H160 => "H160", + PrimitiveType::H256 => "H256", + PrimitiveType::U256 => "U256", + PrimitiveType::NonZeroU8 => "NonZeroU8", + PrimitiveType::NonZeroU16 => "NonZeroU16", + PrimitiveType::NonZeroU32 => "NonZeroU32", + PrimitiveType::NonZeroU64 => "NonZeroU64", + PrimitiveType::NonZeroU128 => "NonZeroU128", + PrimitiveType::NonZeroU256 => "NonZeroU256", + }); + } + + fn visit_user_defined_type_id(&mut self, user_defined_type_id: &'ast str) { + if !self.path.is_empty() { + self.code.push_str(&self.path); + self.code.push_str("::"); + } + self.code.push_str(user_defined_type_id); + } + + fn visit_map_type_decl( + &mut self, + key_type_decl: &'ast TypeDecl, + value_type_decl: &'ast TypeDecl, + ) { + self.code.push_str("BTreeMap<"); + visitor::accept_type_decl(key_type_decl, self); + self.code.push_str(", "); + visitor::accept_type_decl(value_type_decl, self); + self.code.push('>'); + } + + fn visit_array_type_decl(&mut self, item_type_decl: &'ast TypeDecl, len: u32) { + self.code.push('['); + visitor::accept_type_decl(item_type_decl, self); + self.code.push_str(&format!("; {len}]")); + } +} + +struct StructTypeGenerator { + code: String, + path: String, +} + +impl StructTypeGenerator { + fn new(path: String) -> Self { + Self { + code: String::new(), + path, + } + } +} + +impl<'ast> Visitor<'ast> for StructTypeGenerator { + fn visit_struct_def(&mut self, struct_def: &'ast StructDef) { + let is_regular_struct = struct_def.fields().iter().all(|f| f.name().is_some()); + let is_tuple_struct = struct_def.fields().iter().all(|f| f.name().is_none()); + if !is_regular_struct && !is_tuple_struct { + panic!("Struct must be either regular or tuple"); + } + if is_regular_struct { + self.code.push('{'); + } else { + self.code.push('('); + } + visitor::accept_struct_def(struct_def, self); + if is_regular_struct { + self.code.push('}'); + } else { + self.code.push(')'); + } + } + + fn visit_struct_field(&mut self, struct_field: &'ast StructField) { + let type_decl_code = + generate_type_decl_with_path(struct_field.type_decl(), self.path.clone()); + + if let Some(field_name) = struct_field.name() { + self.code + .push_str(&format!("{field_name}: {type_decl_code},")); + } else { + self.code.push_str(&format!("{type_decl_code},")); + } + } +} diff --git a/rs/client-gen-dotnet/tests/generator.rs b/rs/client-gen-dotnet/tests/generator.rs new file mode 100644 index 00000000..6131a442 --- /dev/null +++ b/rs/client-gen-dotnet/tests/generator.rs @@ -0,0 +1,237 @@ +use sails_client_gen_dotnet::ClientGenerator; + +#[test] +fn full() { + const IDL: &str = r#" + // Comments are supported but ignored by idl-parser + + /// ThisThatSvcAppTupleStruct docs + type ThisThatSvcAppTupleStruct = struct { + /// field `bool` + bool, + }; + + /// ThisThatSvcAppDoThatParam docs + type ThisThatSvcAppDoThatParam = struct { + /// field `query` + query: u32, + /// field `result` + result: str, + /// field `p3` + p3: ThisThatSvcAppManyVariants, + }; + + /// ThisThatSvcAppManyVariants docs + type ThisThatSvcAppManyVariants = enum { + /// variant `One` + One, + /// variant `Two` + Two: u32, + Three: opt u32, + Four: struct { a: u32, b: opt u16 }, + Five: struct { str, u32 }, + Six: struct { u32 }, + }; + + type T = enum { One }; + + constructor { + /// New constructor + New : (a: u32); + }; + + service { + /// Some description + DoThis : (p1: u32, p2: str, p3: struct { opt str, u8 }, p4: ThisThatSvcAppTupleStruct) -> struct { str, u32 }; + /// Some multiline description + /// Second line + /// Third line + DoThat : (param: ThisThatSvcAppDoThatParam) -> result (struct { str, u32 }, struct { str }); + /// This is a query + query This : (v1: vec u16) -> u32; + /// This is a second query + /// This is a second line + query That : (v1: null) -> result (str, str); + + events { + /// `This` Done + ThisDone: u32; + /// `That` Done too + ThatDone: struct { p1: str }; + } + }; + "#; + + insta::assert_snapshot!(gen(IDL, "Service")); +} + +#[test] +fn test_basic_works() { + let idl = r" + type MyParam = struct { + f1: u32, + f2: vec str, + f3: opt struct { u8, u32 }, + }; + + type MyParam2 = enum { + Variant1, + Variant2: u32, + Variant3: struct { u32 }, + Variant4: struct { u8, u32 }, + Variant5: struct { f1: str, f2: vec u8 }, + }; + + service { + DoThis: (p1: u32, p2: MyParam) -> u16; + DoThat: (p1: struct { u8, u32 }) -> u8; + }; + "; + + insta::assert_snapshot!(gen(idl, "Basic")); +} + +#[test] +fn test_multiple_services() { + let idl = r" + service { + DoThis: (p1: u32, p2: MyParam) -> u16; + DoThat: (p1: struct { u8, u32 }) -> u8; + }; + + service Named { + query That: (p1: u32) -> str; + }; + "; + + insta::assert_snapshot!(gen(idl, "Multiple")); +} + +#[test] +fn test_rmrk_works() { + let idl = include_str!("../../../examples/rmrk/catalog/wasm/rmrk-catalog.idl"); + + insta::assert_snapshot!(gen(idl, "RmrkCatalog")); +} + +#[test] +fn test_nonzero_works() { + let idl = r" + type MyParam = struct { + f1: nat256, + f2: vec nat8, + f3: opt struct { nat64, nat256 }, + }; + + service { + DoThis: (p1: nat256, p2: MyParam) -> nat64; + }; + "; + + insta::assert_snapshot!(gen(idl, "NonZeroParams")); +} + +#[test] +fn test_events_works() { + let idl = r" + type MyParam = struct { + f1: nat256, + f2: vec nat8, + f3: opt struct { nat64, nat256 }, + }; + + service { + DoThis: (p1: nat256, p2: MyParam) -> nat64; + + events { + One: u64; + Two: struct { id: u8, reference: u64 }; + Three: MyParam; + Reset; + } + }; + "; + + insta::assert_snapshot!(gen(idl, "ServiceWithEvents")); +} + +#[test] +fn full_with_sails_path() { + const IDL: &str = r#" + type ThisThatSvcAppTupleStruct = struct { + bool, + }; + + type ThisThatSvcAppDoThatParam = struct { + p1: u32, + p2: str, + p3: ThisThatSvcAppManyVariants, + }; + + type ThisThatSvcAppManyVariants = enum { + One, + Two: u32, + Three: opt u32, + Four: struct { a: u32, b: opt u16 }, + Five: struct { str, u32 }, + Six: struct { u32 }, + }; + + type T = enum { One }; + + constructor { + New : (a: u32); + }; + + service { + DoThis : (p1: u32, p2: str, p3: struct { opt str, u8 }, p4: ThisThatSvcAppTupleStruct) -> struct { str, u32 }; + DoThat : (param: ThisThatSvcAppDoThatParam) -> result (struct { str, u32 }, struct { str }); + query This : (v1: vec u16) -> u32; + query That : (v1: null) -> result (str, str); + }; + "#; + + let code = ClientGenerator::from_idl(IDL) + .with_sails_crate("my_crate::sails") + .generate("Service") + .expect("generate client"); + insta::assert_snapshot!(code); +} + +#[test] +fn test_external_types() { + const IDL: &str = r#" + type MyParam = struct { + f1: u32, + f2: vec str, + f3: opt struct { u8, u32 }, + }; + + type MyParam2 = enum { + Variant1, + Variant2: u32, + Variant3: struct { u32 }, + Variant4: struct { u8, u32 }, + Variant5: struct { f1: str, f2: vec u8 }, + }; + + service { + DoThis: (p1: u32, p2: MyParam) -> u16; + DoThat: (p1: struct { u8, u32 }) -> u8; + }; + "#; + + let code = ClientGenerator::from_idl(IDL) + .with_sails_crate("my_crate::sails") + .with_external_type("MyParam", "my_crate::MyParam") + .generate("Service") + .expect("generate client"); + insta::assert_snapshot!(code); +} + +fn gen(program: &str, service_name: &str) -> String { + ClientGenerator::from_idl(program) + .with_mocks("with_mocks") + .generate(service_name) + .expect("generate client") +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap new file mode 100644 index 00000000..3b9a729d --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap @@ -0,0 +1,104 @@ +--- +source: rs/client-gen/tests/generator.rs +expression: "gen(idl, \"Basic\")" +--- +// Code generated by sails-client-gen. DO NOT EDIT. +#[allow(unused_imports)] +use sails_rs::collections::BTreeMap; +#[allow(unused_imports)] +use sails_rs::{ + calls::{Activation, Call, Query, Remoting, RemotingAction}, + prelude::*, + String, +}; +pub struct Basic { + remoting: R, +} +impl Basic { + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::Basic for Basic { + type Args = R::Args; + fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call { + RemotingAction::<_, basic::io::DoThis>::new(self.remoting.clone(), (p1, p2)) + } + fn do_that(&mut self, p1: (u8, u32)) -> impl Call { + RemotingAction::<_, basic::io::DoThat>::new(self.remoting.clone(), p1) + } +} + +pub mod basic { + use super::*; + + pub mod io { + use super::*; + use sails_rs::calls::ActionIo; + pub struct DoThis(()); + impl DoThis { + #[allow(dead_code)] + pub fn encode_call(p1: u32, p2: super::MyParam) -> Vec { + ::encode_call(&(p1, p2)) + } + } + impl ActionIo for DoThis { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; + type Params = (u32, super::MyParam); + type Reply = u16; + } + pub struct DoThat(()); + impl DoThat { + #[allow(dead_code)] + pub fn encode_call(p1: (u8, u32)) -> Vec { + ::encode_call(&p1) + } + } + impl ActionIo for DoThat { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; + type Params = (u8, u32); + type Reply = u8; + } + } +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub struct MyParam { + pub f1: u32, + pub f2: Vec, + pub f3: Option<(u8, u32)>, +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub enum MyParam2 { + Variant1, + Variant2(u32), + Variant3((u32,)), + Variant4((u8, u32)), + Variant5 { f1: String, f2: Vec }, +} + +pub mod traits { + use super::*; + + #[allow(clippy::type_complexity)] + pub trait Basic { + type Args; + fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call; + fn do_that(&mut self, p1: (u8, u32)) -> impl Call; + } +} + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +pub mod mockall { + use super::*; + use sails_rs::mockall::*; + mock! { pub Basic {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::Basic for Basic { type Args = A; fn do_this (&mut self, p1: u32,p2: MyParam,) -> MockCall;fn do_that (&mut self, p1: (u8,u32,),) -> MockCall; } } +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap.new b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap.new new file mode 100644 index 00000000..902abe25 --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap.new @@ -0,0 +1,15 @@ +--- +source: rs/client-gen-dotnet/tests/generator.rs +assertion_line: 91 +expression: "gen(idl, \"Basic\")" +--- +public partial record struct MyParam { + pub f1: u32, + pub f2: Vec, + pub f3: Option<(u8,u32,)>, } + public enum MyParam2 { + Variant1, + Variant2, + Variant3, + Variant4, + Variant5, } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap new file mode 100644 index 00000000..66295658 --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap @@ -0,0 +1,116 @@ +--- +source: rs/client-gen/tests/generator.rs +expression: "gen(idl, \"ServiceWithEvents\")" +--- +// Code generated by sails-client-gen. DO NOT EDIT. +#[allow(unused_imports)] +use sails_rs::collections::BTreeMap; +#[allow(unused_imports)] +use sails_rs::{ + calls::{Activation, Call, Query, Remoting, RemotingAction}, + prelude::*, + String, +}; +pub struct ServiceWithEvents { + remoting: R, +} +impl ServiceWithEvents { + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::ServiceWithEvents for ServiceWithEvents { + type Args = R::Args; + fn do_this( + &mut self, + p1: NonZeroU256, + p2: MyParam, + ) -> impl Call { + RemotingAction::<_, service_with_events::io::DoThis>::new(self.remoting.clone(), (p1, p2)) + } +} + +pub mod service_with_events { + use super::*; + + pub mod io { + use super::*; + use sails_rs::calls::ActionIo; + pub struct DoThis(()); + impl DoThis { + #[allow(dead_code)] + pub fn encode_call(p1: NonZeroU256, p2: super::MyParam) -> Vec { + ::encode_call(&(p1, p2)) + } + } + impl ActionIo for DoThis { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; + type Params = (NonZeroU256, super::MyParam); + type Reply = NonZeroU64; + } + } + + #[allow(dead_code)] + #[cfg(not(target_arch = "wasm32"))] + pub mod events { + use super::*; + use sails_rs::events::*; + #[derive(PartialEq, Debug, Encode, Decode)] + #[codec(crate = sails_rs::scale_codec)] + pub enum ServiceWithEventsEvents { + One(u64), + Two { id: u8, reference: u64 }, + Three(MyParam), + Reset, + } + impl EventIo for ServiceWithEventsEvents { + const ROUTE: &'static [u8] = &[]; + const EVENT_NAMES: &'static [&'static [u8]] = &[ + &[12, 79, 110, 101], + &[12, 84, 119, 111], + &[20, 84, 104, 114, 101, 101], + &[20, 82, 101, 115, 101, 116], + ]; + type Event = Self; + } + pub fn listener>>( + remoting: R, + ) -> impl Listener { + RemotingListener::<_, ServiceWithEventsEvents>::new(remoting) + } + } +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub struct MyParam { + pub f1: NonZeroU256, + pub f2: Vec, + pub f3: Option<(NonZeroU64, NonZeroU256)>, +} + +pub mod traits { + use super::*; + + #[allow(clippy::type_complexity)] + pub trait ServiceWithEvents { + type Args; + fn do_this( + &mut self, + p1: NonZeroU256, + p2: MyParam, + ) -> impl Call; + } +} + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +pub mod mockall { + use super::*; + use sails_rs::mockall::*; + mock! { pub ServiceWithEvents {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::ServiceWithEvents for ServiceWithEvents { type Args = A; fn do_this (&mut self, p1: NonZeroU256,p2: MyParam,) -> MockCall; } } +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap new file mode 100644 index 00000000..8828daa1 --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap @@ -0,0 +1,86 @@ +--- +source: rs/client-gen/tests/generator.rs +expression: code +--- +// Code generated by sails-client-gen. DO NOT EDIT. +#[allow(unused_imports)] +use my_crate::sails::collections::BTreeMap; +#[allow(unused_imports)] +use my_crate::sails::{ + calls::{Activation, Call, Query, Remoting, RemotingAction}, + prelude::*, + String, +}; +#[allow(unused_imports)] +use my_crate::MyParam; +pub struct Service { + remoting: R, +} +impl Service { + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::Service for Service { + type Args = R::Args; + fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call { + RemotingAction::<_, service::io::DoThis>::new(self.remoting.clone(), (p1, p2)) + } + fn do_that(&mut self, p1: (u8, u32)) -> impl Call { + RemotingAction::<_, service::io::DoThat>::new(self.remoting.clone(), p1) + } +} + +pub mod service { + use super::*; + + pub mod io { + use super::*; + use my_crate::sails::calls::ActionIo; + pub struct DoThis(()); + impl DoThis { + #[allow(dead_code)] + pub fn encode_call(p1: u32, p2: super::MyParam) -> Vec { + ::encode_call(&(p1, p2)) + } + } + impl ActionIo for DoThis { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; + type Params = (u32, super::MyParam); + type Reply = u16; + } + pub struct DoThat(()); + impl DoThat { + #[allow(dead_code)] + pub fn encode_call(p1: (u8, u32)) -> Vec { + ::encode_call(&p1) + } + } + impl ActionIo for DoThat { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; + type Params = (u8, u32); + type Reply = u8; + } + } +} +#[derive(Encode, Decode, TypeInfo)] +#[codec(crate = my_crate::sails::scale_codec)] +#[scale_info(crate = my_crate::sails::scale_info)] +pub enum MyParam2 { + Variant1, + Variant2(u32), + Variant3((u32,)), + Variant4((u8, u32)), + Variant5 { f1: String, f2: Vec }, +} + +pub mod traits { + use super::*; + + #[allow(clippy::type_complexity)] + pub trait Service { + type Args; + fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call; + fn do_that(&mut self, p1: (u8, u32)) -> impl Call; + } +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap new file mode 100644 index 00000000..5af38207 --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -0,0 +1,266 @@ +--- +source: rs/client-gen/tests/generator.rs +expression: "gen(IDL, \"Service\")" +--- +// Code generated by sails-client-gen. DO NOT EDIT. +#[allow(unused_imports)] +use sails_rs::collections::BTreeMap; +#[allow(unused_imports)] +use sails_rs::{ + calls::{Activation, Call, Query, Remoting, RemotingAction}, + prelude::*, + String, +}; +pub struct ServiceFactory { + #[allow(dead_code)] + remoting: R, +} +impl ServiceFactory { + #[allow(unused)] + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::ServiceFactory for ServiceFactory { + type Args = R::Args; + /// New constructor + fn new(&self, a: u32) -> impl Activation { + RemotingAction::<_, service_factory::io::New>::new(self.remoting.clone(), a) + } +} + +pub mod service_factory { + use super::*; + pub mod io { + use super::*; + use sails_rs::calls::ActionIo; + pub struct New(()); + impl New { + #[allow(dead_code)] + pub fn encode_call(a: u32) -> Vec { + ::encode_call(&a) + } + } + impl ActionIo for New { + const ROUTE: &'static [u8] = &[12, 78, 101, 119]; + type Params = u32; + type Reply = (); + } + } +} +pub struct Service { + remoting: R, +} +impl Service { + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::Service for Service { + type Args = R::Args; + /// Some description + fn do_this( + &mut self, + p1: u32, + p2: String, + p3: (Option, u8), + p4: ThisThatSvcAppTupleStruct, + ) -> impl Call { + RemotingAction::<_, service::io::DoThis>::new(self.remoting.clone(), (p1, p2, p3, p4)) + } + /// Some multiline description + /// Second line + /// Third line + fn do_that( + &mut self, + param: ThisThatSvcAppDoThatParam, + ) -> impl Call, Args = R::Args> { + RemotingAction::<_, service::io::DoThat>::new(self.remoting.clone(), param) + } + /// This is a query + fn this(&self, v1: Vec) -> impl Query { + RemotingAction::<_, service::io::This>::new(self.remoting.clone(), v1) + } + /// This is a second query + /// This is a second line + fn that(&self, v1: ()) -> impl Query, Args = R::Args> { + RemotingAction::<_, service::io::That>::new(self.remoting.clone(), v1) + } +} + +pub mod service { + use super::*; + + pub mod io { + use super::*; + use sails_rs::calls::ActionIo; + pub struct DoThis(()); + impl DoThis { + #[allow(dead_code)] + pub fn encode_call( + p1: u32, + p2: String, + p3: (Option, u8), + p4: super::ThisThatSvcAppTupleStruct, + ) -> Vec { + ::encode_call(&(p1, p2, p3, p4)) + } + } + impl ActionIo for DoThis { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; + type Params = ( + u32, + String, + (Option, u8), + super::ThisThatSvcAppTupleStruct, + ); + type Reply = (String, u32); + } + pub struct DoThat(()); + impl DoThat { + #[allow(dead_code)] + pub fn encode_call(param: super::ThisThatSvcAppDoThatParam) -> Vec { + ::encode_call(¶m) + } + } + impl ActionIo for DoThat { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; + type Params = super::ThisThatSvcAppDoThatParam; + type Reply = Result<(String, u32), (String,)>; + } + pub struct This(()); + impl This { + #[allow(dead_code)] + pub fn encode_call(v1: Vec) -> Vec { + ::encode_call(&v1) + } + } + impl ActionIo for This { + const ROUTE: &'static [u8] = &[16, 84, 104, 105, 115]; + type Params = Vec; + type Reply = u32; + } + pub struct That(()); + impl That { + #[allow(dead_code)] + pub fn encode_call(v1: ()) -> Vec { + ::encode_call(&v1) + } + } + impl ActionIo for That { + const ROUTE: &'static [u8] = &[16, 84, 104, 97, 116]; + type Params = (); + type Reply = Result; + } + } + + #[allow(dead_code)] + #[cfg(not(target_arch = "wasm32"))] + pub mod events { + use super::*; + use sails_rs::events::*; + #[derive(PartialEq, Debug, Encode, Decode)] + #[codec(crate = sails_rs::scale_codec)] + pub enum ServiceEvents { + /// `This` Done + ThisDone(u32), + /// `That` Done too + ThatDone { p1: String }, + } + impl EventIo for ServiceEvents { + const ROUTE: &'static [u8] = &[]; + const EVENT_NAMES: &'static [&'static [u8]] = &[ + &[32, 84, 104, 105, 115, 68, 111, 110, 101], + &[32, 84, 104, 97, 116, 68, 111, 110, 101], + ]; + type Event = Self; + } + pub fn listener>>(remoting: R) -> impl Listener { + RemotingListener::<_, ServiceEvents>::new(remoting) + } + } +} +/// ThisThatSvcAppTupleStruct docs +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub struct ThisThatSvcAppTupleStruct( + /// field `bool` + pub bool, +); +/// ThisThatSvcAppDoThatParam docs +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub struct ThisThatSvcAppDoThatParam { + /// field `query` + pub query: u32, + /// field `result` + pub result: String, + /// field `p3` + pub p3: ThisThatSvcAppManyVariants, +} +/// ThisThatSvcAppManyVariants docs +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub enum ThisThatSvcAppManyVariants { + /// variant `One` + One, + /// variant `Two` + Two(u32), + Three(Option), + Four { + a: u32, + b: Option, + }, + Five((String, u32)), + Six((u32,)), +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub enum T { + One, +} + +pub mod traits { + use super::*; + #[allow(dead_code)] + pub trait ServiceFactory { + type Args; + #[allow(clippy::new_ret_no_self)] + #[allow(clippy::wrong_self_convention)] + fn new(&self, a: u32) -> impl Activation; + } + + #[allow(clippy::type_complexity)] + pub trait Service { + type Args; + fn do_this( + &mut self, + p1: u32, + p2: String, + p3: (Option, u8), + p4: ThisThatSvcAppTupleStruct, + ) -> impl Call; + fn do_that( + &mut self, + param: ThisThatSvcAppDoThatParam, + ) -> impl Call, Args = Self::Args>; + fn this(&self, v1: Vec) -> impl Query; + fn that(&self, v1: ()) -> impl Query, Args = Self::Args>; + } +} + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +pub mod mockall { + use super::*; + use sails_rs::mockall::*; + mock! { pub Service {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::Service for Service { type Args = A; fn do_this (&mut self, p1: u32,p2: String,p3: (Option,u8,),p4: ThisThatSvcAppTupleStruct,) -> MockCall;fn do_that (&mut self, param: ThisThatSvcAppDoThatParam,) -> MockCall>;fn this (& self, v1: Vec,) -> MockQuery;fn that (& self, v1: (),) -> MockQuery>; } } +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new new file mode 100644 index 00000000..f20fbcae --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new @@ -0,0 +1,27 @@ +--- +source: rs/client-gen-dotnet/tests/generator.rs +assertion_line: 65 +expression: "gen(IDL, \"Service\")" +--- + /// ThisThatSvcAppTupleStruct docspublic partial record struct ThisThatSvcAppTupleStruct { + /// field `bool` + pub bool, } + /// ThisThatSvcAppDoThatParam docspublic partial record struct ThisThatSvcAppDoThatParam { + /// field `query` + pub query: u32, + /// field `result` + pub result: String, + /// field `p3` + pub p3: ThisThatSvcAppManyVariants, } + /// ThisThatSvcAppManyVariants docs + public enum ThisThatSvcAppManyVariants { + /// variant `One` + One, + /// variant `Two` + Two, + Three, + Four, + Five, + Six, } + public enum T { + One, } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap new file mode 100644 index 00000000..ba3df807 --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -0,0 +1,206 @@ +--- +source: rs/client-gen/tests/generator.rs +expression: code +--- +// Code generated by sails-client-gen. DO NOT EDIT. +#[allow(unused_imports)] +use my_crate::sails::collections::BTreeMap; +#[allow(unused_imports)] +use my_crate::sails::{ + calls::{Activation, Call, Query, Remoting, RemotingAction}, + prelude::*, + String, +}; +pub struct ServiceFactory { + #[allow(dead_code)] + remoting: R, +} +impl ServiceFactory { + #[allow(unused)] + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::ServiceFactory for ServiceFactory { + type Args = R::Args; + fn new(&self, a: u32) -> impl Activation { + RemotingAction::<_, service_factory::io::New>::new(self.remoting.clone(), a) + } +} + +pub mod service_factory { + use super::*; + pub mod io { + use super::*; + use my_crate::sails::calls::ActionIo; + pub struct New(()); + impl New { + #[allow(dead_code)] + pub fn encode_call(a: u32) -> Vec { + ::encode_call(&a) + } + } + impl ActionIo for New { + const ROUTE: &'static [u8] = &[12, 78, 101, 119]; + type Params = u32; + type Reply = (); + } + } +} +pub struct Service { + remoting: R, +} +impl Service { + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::Service for Service { + type Args = R::Args; + fn do_this( + &mut self, + p1: u32, + p2: String, + p3: (Option, u8), + p4: ThisThatSvcAppTupleStruct, + ) -> impl Call { + RemotingAction::<_, service::io::DoThis>::new(self.remoting.clone(), (p1, p2, p3, p4)) + } + fn do_that( + &mut self, + param: ThisThatSvcAppDoThatParam, + ) -> impl Call, Args = R::Args> { + RemotingAction::<_, service::io::DoThat>::new(self.remoting.clone(), param) + } + fn this(&self, v1: Vec) -> impl Query { + RemotingAction::<_, service::io::This>::new(self.remoting.clone(), v1) + } + fn that(&self, v1: ()) -> impl Query, Args = R::Args> { + RemotingAction::<_, service::io::That>::new(self.remoting.clone(), v1) + } +} + +pub mod service { + use super::*; + + pub mod io { + use super::*; + use my_crate::sails::calls::ActionIo; + pub struct DoThis(()); + impl DoThis { + #[allow(dead_code)] + pub fn encode_call( + p1: u32, + p2: String, + p3: (Option, u8), + p4: super::ThisThatSvcAppTupleStruct, + ) -> Vec { + ::encode_call(&(p1, p2, p3, p4)) + } + } + impl ActionIo for DoThis { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; + type Params = ( + u32, + String, + (Option, u8), + super::ThisThatSvcAppTupleStruct, + ); + type Reply = (String, u32); + } + pub struct DoThat(()); + impl DoThat { + #[allow(dead_code)] + pub fn encode_call(param: super::ThisThatSvcAppDoThatParam) -> Vec { + ::encode_call(¶m) + } + } + impl ActionIo for DoThat { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; + type Params = super::ThisThatSvcAppDoThatParam; + type Reply = Result<(String, u32), (String,)>; + } + pub struct This(()); + impl This { + #[allow(dead_code)] + pub fn encode_call(v1: Vec) -> Vec { + ::encode_call(&v1) + } + } + impl ActionIo for This { + const ROUTE: &'static [u8] = &[16, 84, 104, 105, 115]; + type Params = Vec; + type Reply = u32; + } + pub struct That(()); + impl That { + #[allow(dead_code)] + pub fn encode_call(v1: ()) -> Vec { + ::encode_call(&v1) + } + } + impl ActionIo for That { + const ROUTE: &'static [u8] = &[16, 84, 104, 97, 116]; + type Params = (); + type Reply = Result; + } + } +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = my_crate::sails::scale_codec)] +#[scale_info(crate = my_crate::sails::scale_info)] +pub struct ThisThatSvcAppTupleStruct(pub bool); +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = my_crate::sails::scale_codec)] +#[scale_info(crate = my_crate::sails::scale_info)] +pub struct ThisThatSvcAppDoThatParam { + pub p1: u32, + pub p2: String, + pub p3: ThisThatSvcAppManyVariants, +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = my_crate::sails::scale_codec)] +#[scale_info(crate = my_crate::sails::scale_info)] +pub enum ThisThatSvcAppManyVariants { + One, + Two(u32), + Three(Option), + Four { a: u32, b: Option }, + Five((String, u32)), + Six((u32,)), +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = my_crate::sails::scale_codec)] +#[scale_info(crate = my_crate::sails::scale_info)] +pub enum T { + One, +} + +pub mod traits { + use super::*; + #[allow(dead_code)] + pub trait ServiceFactory { + type Args; + #[allow(clippy::new_ret_no_self)] + #[allow(clippy::wrong_self_convention)] + fn new(&self, a: u32) -> impl Activation; + } + + #[allow(clippy::type_complexity)] + pub trait Service { + type Args; + fn do_this( + &mut self, + p1: u32, + p2: String, + p3: (Option, u8), + p4: ThisThatSvcAppTupleStruct, + ) -> impl Call; + fn do_that( + &mut self, + param: ThisThatSvcAppDoThatParam, + ) -> impl Call, Args = Self::Args>; + fn this(&self, v1: Vec) -> impl Query; + fn that(&self, v1: ()) -> impl Query, Args = Self::Args>; + } +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap new file mode 100644 index 00000000..c3950115 --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap @@ -0,0 +1,128 @@ +--- +source: rs/client-gen/tests/generator.rs +expression: "gen(idl, \"Multiple\")" +--- +// Code generated by sails-client-gen. DO NOT EDIT. +#[allow(unused_imports)] +use sails_rs::collections::BTreeMap; +#[allow(unused_imports)] +use sails_rs::{ + calls::{Activation, Call, Query, Remoting, RemotingAction}, + prelude::*, + String, +}; +pub struct Multiple { + remoting: R, +} +impl Multiple { + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::Multiple for Multiple { + type Args = R::Args; + fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call { + RemotingAction::<_, multiple::io::DoThis>::new(self.remoting.clone(), (p1, p2)) + } + fn do_that(&mut self, p1: (u8, u32)) -> impl Call { + RemotingAction::<_, multiple::io::DoThat>::new(self.remoting.clone(), p1) + } +} + +pub mod multiple { + use super::*; + + pub mod io { + use super::*; + use sails_rs::calls::ActionIo; + pub struct DoThis(()); + impl DoThis { + #[allow(dead_code)] + pub fn encode_call(p1: u32, p2: super::MyParam) -> Vec { + ::encode_call(&(p1, p2)) + } + } + impl ActionIo for DoThis { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; + type Params = (u32, super::MyParam); + type Reply = u16; + } + pub struct DoThat(()); + impl DoThat { + #[allow(dead_code)] + pub fn encode_call(p1: (u8, u32)) -> Vec { + ::encode_call(&p1) + } + } + impl ActionIo for DoThat { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; + type Params = (u8, u32); + type Reply = u8; + } + } +} +pub struct Named { + remoting: R, +} +impl Named { + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::Named for Named { + type Args = R::Args; + fn that(&self, p1: u32) -> impl Query { + RemotingAction::<_, named::io::That>::new(self.remoting.clone(), p1) + } +} + +pub mod named { + use super::*; + + pub mod io { + use super::*; + use sails_rs::calls::ActionIo; + pub struct That(()); + impl That { + #[allow(dead_code)] + pub fn encode_call(p1: u32) -> Vec { + ::encode_call(&p1) + } + } + impl ActionIo for That { + const ROUTE: &'static [u8] = &[20, 78, 97, 109, 101, 100, 16, 84, 104, 97, 116]; + type Params = u32; + type Reply = String; + } + } +} + +pub mod traits { + use super::*; + + #[allow(clippy::type_complexity)] + pub trait Multiple { + type Args; + fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call; + fn do_that(&mut self, p1: (u8, u32)) -> impl Call; + } + + #[allow(clippy::type_complexity)] + pub trait Named { + type Args; + fn that(&self, p1: u32) -> impl Query; + } +} + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +pub mod mockall { + use super::*; + use sails_rs::mockall::*; + mock! { pub Multiple {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::Multiple for Multiple { type Args = A; fn do_this (&mut self, p1: u32,p2: MyParam,) -> MockCall;fn do_that (&mut self, p1: (u8,u32,),) -> MockCall; } } + mock! { pub Named {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::Named for Named { type Args = A; fn that (& self, p1: u32,) -> MockQuery; } } +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap new file mode 100644 index 00000000..997e75aa --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap @@ -0,0 +1,86 @@ +--- +source: rs/client-gen/tests/generator.rs +expression: "gen(idl, \"NonZeroParams\")" +--- +// Code generated by sails-client-gen. DO NOT EDIT. +#[allow(unused_imports)] +use sails_rs::collections::BTreeMap; +#[allow(unused_imports)] +use sails_rs::{ + calls::{Activation, Call, Query, Remoting, RemotingAction}, + prelude::*, + String, +}; +pub struct NonZeroParams { + remoting: R, +} +impl NonZeroParams { + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::NonZeroParams for NonZeroParams { + type Args = R::Args; + fn do_this( + &mut self, + p1: NonZeroU256, + p2: MyParam, + ) -> impl Call { + RemotingAction::<_, non_zero_params::io::DoThis>::new(self.remoting.clone(), (p1, p2)) + } +} + +pub mod non_zero_params { + use super::*; + + pub mod io { + use super::*; + use sails_rs::calls::ActionIo; + pub struct DoThis(()); + impl DoThis { + #[allow(dead_code)] + pub fn encode_call(p1: NonZeroU256, p2: super::MyParam) -> Vec { + ::encode_call(&(p1, p2)) + } + } + impl ActionIo for DoThis { + const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; + type Params = (NonZeroU256, super::MyParam); + type Reply = NonZeroU64; + } + } +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub struct MyParam { + pub f1: NonZeroU256, + pub f2: Vec, + pub f3: Option<(NonZeroU64, NonZeroU256)>, +} + +pub mod traits { + use super::*; + + #[allow(clippy::type_complexity)] + pub trait NonZeroParams { + type Args; + fn do_this( + &mut self, + p1: NonZeroU256, + p2: MyParam, + ) -> impl Call; + } +} + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +pub mod mockall { + use super::*; + use sails_rs::mockall::*; + mock! { pub NonZeroParams {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::NonZeroParams for NonZeroParams { type Args = A; fn do_this (&mut self, p1: NonZeroU256,p2: MyParam,) -> MockCall; } } +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap new file mode 100644 index 00000000..ae8cde16 --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap @@ -0,0 +1,351 @@ +--- +source: rs/client-gen/tests/generator.rs +expression: "gen(idl, \"RmrkCatalog\")" +--- +// Code generated by sails-client-gen. DO NOT EDIT. +#[allow(unused_imports)] +use sails_rs::collections::BTreeMap; +#[allow(unused_imports)] +use sails_rs::{ + calls::{Activation, Call, Query, Remoting, RemotingAction}, + prelude::*, + String, +}; +pub struct RmrkCatalogFactory { + #[allow(dead_code)] + remoting: R, +} +impl RmrkCatalogFactory { + #[allow(unused)] + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::RmrkCatalogFactory for RmrkCatalogFactory { + type Args = R::Args; + fn new(&self) -> impl Activation { + RemotingAction::<_, rmrk_catalog_factory::io::New>::new(self.remoting.clone(), ()) + } +} + +pub mod rmrk_catalog_factory { + use super::*; + pub mod io { + use super::*; + use sails_rs::calls::ActionIo; + pub struct New(()); + impl New { + #[allow(dead_code)] + pub fn encode_call() -> Vec { + ::encode_call(&()) + } + } + impl ActionIo for New { + const ROUTE: &'static [u8] = &[12, 78, 101, 119]; + type Params = (); + type Reply = (); + } + } +} +pub struct RmrkCatalog { + remoting: R, +} +impl RmrkCatalog { + pub fn new(remoting: R) -> Self { + Self { remoting } + } +} +impl traits::RmrkCatalog for RmrkCatalog { + type Args = R::Args; + fn add_equippables( + &mut self, + part_id: u32, + collection_ids: Vec, + ) -> impl Call), Error>, Args = R::Args> { + RemotingAction::<_, rmrk_catalog::io::AddEquippables>::new( + self.remoting.clone(), + (part_id, collection_ids), + ) + } + fn add_parts( + &mut self, + parts: BTreeMap, + ) -> impl Call, Error>, Args = R::Args> { + RemotingAction::<_, rmrk_catalog::io::AddParts>::new(self.remoting.clone(), parts) + } + fn remove_equippable( + &mut self, + part_id: u32, + collection_id: ActorId, + ) -> impl Call, Args = R::Args> { + RemotingAction::<_, rmrk_catalog::io::RemoveEquippable>::new( + self.remoting.clone(), + (part_id, collection_id), + ) + } + fn remove_parts( + &mut self, + part_ids: Vec, + ) -> impl Call, Error>, Args = R::Args> { + RemotingAction::<_, rmrk_catalog::io::RemoveParts>::new(self.remoting.clone(), part_ids) + } + fn reset_equippables( + &mut self, + part_id: u32, + ) -> impl Call, Args = R::Args> { + RemotingAction::<_, rmrk_catalog::io::ResetEquippables>::new(self.remoting.clone(), part_id) + } + fn set_equippables_to_all( + &mut self, + part_id: u32, + ) -> impl Call, Args = R::Args> { + RemotingAction::<_, rmrk_catalog::io::SetEquippablesToAll>::new( + self.remoting.clone(), + part_id, + ) + } + fn equippable( + &self, + part_id: u32, + collection_id: ActorId, + ) -> impl Query, Args = R::Args> { + RemotingAction::<_, rmrk_catalog::io::Equippable>::new( + self.remoting.clone(), + (part_id, collection_id), + ) + } + fn part(&self, part_id: u32) -> impl Query, Args = R::Args> { + RemotingAction::<_, rmrk_catalog::io::Part>::new(self.remoting.clone(), part_id) + } +} + +pub mod rmrk_catalog { + use super::*; + + pub mod io { + use super::*; + use sails_rs::calls::ActionIo; + pub struct AddEquippables(()); + impl AddEquippables { + #[allow(dead_code)] + pub fn encode_call(part_id: u32, collection_ids: Vec) -> Vec { + ::encode_call(&(part_id, collection_ids)) + } + } + impl ActionIo for AddEquippables { + const ROUTE: &'static [u8] = &[ + 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 56, 65, 100, 100, 69, 113, + 117, 105, 112, 112, 97, 98, 108, 101, 115, + ]; + type Params = (u32, Vec); + type Reply = Result<(u32, Vec), super::Error>; + } + pub struct AddParts(()); + impl AddParts { + #[allow(dead_code)] + pub fn encode_call(parts: BTreeMap) -> Vec { + ::encode_call(&parts) + } + } + impl ActionIo for AddParts { + const ROUTE: &'static [u8] = &[ + 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 32, 65, 100, 100, 80, 97, + 114, 116, 115, + ]; + type Params = BTreeMap; + type Reply = Result, super::Error>; + } + pub struct RemoveEquippable(()); + impl RemoveEquippable { + #[allow(dead_code)] + pub fn encode_call(part_id: u32, collection_id: ActorId) -> Vec { + ::encode_call(&(part_id, collection_id)) + } + } + impl ActionIo for RemoveEquippable { + const ROUTE: &'static [u8] = &[ + 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 109, 111, 118, + 101, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, + ]; + type Params = (u32, ActorId); + type Reply = Result<(u32, ActorId), super::Error>; + } + pub struct RemoveParts(()); + impl RemoveParts { + #[allow(dead_code)] + pub fn encode_call(part_ids: Vec) -> Vec { + ::encode_call(&part_ids) + } + } + impl ActionIo for RemoveParts { + const ROUTE: &'static [u8] = &[ + 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 44, 82, 101, 109, 111, 118, + 101, 80, 97, 114, 116, 115, + ]; + type Params = Vec; + type Reply = Result, super::Error>; + } + pub struct ResetEquippables(()); + impl ResetEquippables { + #[allow(dead_code)] + pub fn encode_call(part_id: u32) -> Vec { + ::encode_call(&part_id) + } + } + impl ActionIo for ResetEquippables { + const ROUTE: &'static [u8] = &[ + 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 115, 101, 116, + 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115, + ]; + type Params = u32; + type Reply = Result<(), super::Error>; + } + pub struct SetEquippablesToAll(()); + impl SetEquippablesToAll { + #[allow(dead_code)] + pub fn encode_call(part_id: u32) -> Vec { + ::encode_call(&part_id) + } + } + impl ActionIo for SetEquippablesToAll { + const ROUTE: &'static [u8] = &[ + 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 76, 83, 101, 116, 69, 113, + 117, 105, 112, 112, 97, 98, 108, 101, 115, 84, 111, 65, 108, 108, + ]; + type Params = u32; + type Reply = Result<(), super::Error>; + } + pub struct Equippable(()); + impl Equippable { + #[allow(dead_code)] + pub fn encode_call(part_id: u32, collection_id: ActorId) -> Vec { + ::encode_call(&(part_id, collection_id)) + } + } + impl ActionIo for Equippable { + const ROUTE: &'static [u8] = &[ + 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 40, 69, 113, 117, 105, 112, + 112, 97, 98, 108, 101, + ]; + type Params = (u32, ActorId); + type Reply = Result; + } + pub struct Part(()); + impl Part { + #[allow(dead_code)] + pub fn encode_call(part_id: u32) -> Vec { + ::encode_call(&part_id) + } + } + impl ActionIo for Part { + const ROUTE: &'static [u8] = &[ + 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 16, 80, 97, 114, 116, + ]; + type Params = u32; + type Reply = Option; + } + } +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub enum Error { + PartIdCantBeZero, + BadConfig, + PartAlreadyExists, + ZeroLengthPassed, + PartDoesNotExist, + WrongPartFormat, + NotAllowedToCall, +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub enum Part { + Fixed(FixedPart), + Slot(SlotPart), +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub struct FixedPart { + /// An optional zIndex of base part layer. + /// specifies the stack order of an element. + /// An element with greater stack order is always in front of an element with a lower stack order. + pub z: Option, + /// The metadata URI of the part. + pub metadata_uri: String, +} +#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] +#[codec(crate = sails_rs::scale_codec)] +#[scale_info(crate = sails_rs::scale_info)] +pub struct SlotPart { + /// Array of whitelisted collections that can be equipped in the given slot. Used with slot parts only. + pub equippable: Vec, + /// An optional zIndex of base part layer. + /// specifies the stack order of an element. + /// An element with greater stack order is always in front of an element with a lower stack order. + pub z: Option, + /// The metadata URI of the part. + pub metadata_uri: String, +} + +pub mod traits { + use super::*; + #[allow(dead_code)] + pub trait RmrkCatalogFactory { + type Args; + #[allow(clippy::new_ret_no_self)] + #[allow(clippy::wrong_self_convention)] + fn new(&self) -> impl Activation; + } + + #[allow(clippy::type_complexity)] + pub trait RmrkCatalog { + type Args; + fn add_equippables( + &mut self, + part_id: u32, + collection_ids: Vec, + ) -> impl Call), Error>, Args = Self::Args>; + fn add_parts( + &mut self, + parts: BTreeMap, + ) -> impl Call, Error>, Args = Self::Args>; + fn remove_equippable( + &mut self, + part_id: u32, + collection_id: ActorId, + ) -> impl Call, Args = Self::Args>; + fn remove_parts( + &mut self, + part_ids: Vec, + ) -> impl Call, Error>, Args = Self::Args>; + fn reset_equippables( + &mut self, + part_id: u32, + ) -> impl Call, Args = Self::Args>; + fn set_equippables_to_all( + &mut self, + part_id: u32, + ) -> impl Call, Args = Self::Args>; + fn equippable( + &self, + part_id: u32, + collection_id: ActorId, + ) -> impl Query, Args = Self::Args>; + fn part(&self, part_id: u32) -> impl Query, Args = Self::Args>; + } +} + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +extern crate std; + +#[cfg(feature = "with_mocks")] +#[cfg(not(target_arch = "wasm32"))] +pub mod mockall { + use super::*; + use sails_rs::mockall::*; + mock! { pub RmrkCatalog {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::RmrkCatalog for RmrkCatalog { type Args = A; fn add_equippables (&mut self, part_id: u32,collection_ids: Vec,) -> MockCall,), Error>>;fn add_parts (&mut self, parts: BTreeMap,) -> MockCall, Error>>;fn remove_equippable (&mut self, part_id: u32,collection_id: ActorId,) -> MockCall>;fn remove_parts (&mut self, part_ids: Vec,) -> MockCall, Error>>;fn reset_equippables (&mut self, part_id: u32,) -> MockCall>;fn set_equippables_to_all (&mut self, part_id: u32,) -> MockCall>;fn equippable (& self, part_id: u32,collection_id: ActorId,) -> MockQuery>;fn part (& self, part_id: u32,) -> MockQuery>; } } +} From 76aa5d7835a76e828d13f5f22eb95ca345a29983 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 23 Oct 2024 17:35:06 +0200 Subject: [PATCH 02/54] wip: typpe generator --- rs/client-gen-dotnet/src/helpers.rs | 37 +++++++++++++++++ rs/client-gen-dotnet/src/type_generators.rs | 46 ++++++++++++--------- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/rs/client-gen-dotnet/src/helpers.rs b/rs/client-gen-dotnet/src/helpers.rs index b58f8ab3..fc98a86f 100644 --- a/rs/client-gen-dotnet/src/helpers.rs +++ b/rs/client-gen-dotnet/src/helpers.rs @@ -1,3 +1,7 @@ +use genco::{ + lang::{csharp::Tokens, Csharp}, + tokens::{FormatInto, ItemStr}, +}; use parity_scale_codec::Encode; use sails_idl_parser::ast::FuncParam; @@ -48,3 +52,36 @@ pub(crate) fn encoded_args(params: &[FuncParam]) -> String { format!("({arg_names})") } + +pub fn summary_comment(comment: T) -> SummaryComment +where + T: IntoIterator, + T::Item: Into, +{ + SummaryComment(comment) +} + +pub struct SummaryComment(pub T); + +impl FormatInto for SummaryComment +where + T: IntoIterator, + T::Item: Into, +{ + fn format_into(self, tokens: &mut Tokens) { + let mut iter = self.0.into_iter().peekable(); + if iter.peek().is_none() { + return; + } + tokens.push(); + tokens.append(ItemStr::Static("/// ")); + for line in iter { + tokens.push(); + tokens.append(ItemStr::Static("///")); + tokens.space(); + tokens.append(line.into()); + } + tokens.push(); + tokens.append(ItemStr::Static("/// ")); + } +} diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index fc1ee8d9..7293b4fe 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -1,3 +1,5 @@ +use crate::helpers::summary_comment; +use convert_case::{Case, Casing}; use csharp::Tokens; use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; @@ -37,11 +39,10 @@ impl<'a> TopLevelTypeGenerator<'a> { impl<'a, 'ast> Visitor<'ast> for TopLevelTypeGenerator<'a> { fn visit_type(&mut self, r#type: &'ast Type) { - for doc in r#type.docs() { - quote_in! { self.tokens => - $['\r'] $("///") $doc - }; - } + quote_in! { self.tokens => + $['\r'] + $(summary_comment(r#type.docs())) + }; visitor::accept_type(r#type, self); } @@ -61,6 +62,7 @@ impl<'a, 'ast> Visitor<'ast> for TopLevelTypeGenerator<'a> { #[derive(Default)] struct StructDefGenerator<'a> { type_name: &'a str, + is_tuple_struct: bool, tokens: Tokens, } @@ -69,40 +71,48 @@ impl<'a> StructDefGenerator<'a> { Self { type_name, tokens: Tokens::new(), + is_tuple_struct: false, } } pub(crate) fn finalize(self) -> Tokens { quote! { + $['\r'] public partial record struct $(self.type_name) - { + ( $(self.tokens) - } + ) } } } impl<'ast> Visitor<'ast> for StructDefGenerator<'ast> { fn visit_struct_def(&mut self, struct_def: &'ast StructDef) { + let is_regular_struct = struct_def.fields().iter().all(|f| f.name().is_some()); + let is_tuple_struct = struct_def.fields().iter().all(|f| f.name().is_none()); + if !is_regular_struct && !is_tuple_struct { + panic!("Struct must be either regular or tuple"); + } + self.is_tuple_struct = is_tuple_struct; + visitor::accept_struct_def(struct_def, self); } fn visit_struct_field(&mut self, struct_field: &'ast StructField) { let type_decl_code = generate_type_decl_with_path(struct_field.type_decl(), "".into()); - for doc in struct_field.docs() { - quote_in! { self.tokens => - $['\r'] $("///") $doc - }; - } + quote_in! { self.tokens => + $['\r'] + $(csharp::block_comment(struct_field.docs())) + }; if let Some(field_name) = struct_field.name() { quote_in! { self.tokens => - $['\r'] pub $field_name: $type_decl_code, + $['\r'] $type_decl_code $(field_name.to_case(Case::Pascal)), }; } else { quote_in! { self.tokens => - $['\r'] pub $type_decl_code, + $['\r'] $type_decl_code, }; } } @@ -135,11 +145,9 @@ impl<'a> EnumDefGenerator<'a> { impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { fn visit_enum_variant(&mut self, enum_variant: &'ast EnumVariant) { - for doc in enum_variant.docs() { - quote_in! { self.tokens => - $['\r'] $("///") $doc - }; - } + quote_in! { self.tokens => + $['\r'] $(summary_comment(enum_variant.docs())) + }; quote_in! { self.tokens => $['\r'] $(enum_variant.name()), }; From 2a448983d267bce4dd9d8ab6b6ce223c88c63db0 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 23 Oct 2024 19:36:05 +0200 Subject: [PATCH 03/54] wip: net client gen --- Sails.Net.sln | 6 +++ net/Directory.Packages.props | 10 +++-- .../Sails.ClientGenerator.csproj | 28 ++++++++++++++ .../SailsClientGenerator.cs | 38 +++++++++++++++++++ rs/client-gen-dotnet/src/lib.rs | 2 +- rs/client-gen-dotnet/src/type_generators.rs | 30 ++++++++++++--- 6 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj create mode 100644 net/src/Sails.ClientGenerator/SailsClientGenerator.cs diff --git a/Sails.Net.sln b/Sails.Net.sln index 742906be..37f9ea4e 100644 --- a/Sails.Net.sln +++ b/Sails.Net.sln @@ -19,6 +19,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate.Gear.Client", "net\src\Substrate.Gear.Client\Substrate.Gear.Client.csproj", "{1589D5A4-0CC4-4855-89E0-2E61BBC5E0B0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sails.ClientGenerator", "net\src\Sails.ClientGenerator\Sails.ClientGenerator.csproj", "{F93FFE42-71C1-44BD-9DBA-3559B307370C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -45,6 +47,10 @@ Global {1589D5A4-0CC4-4855-89E0-2E61BBC5E0B0}.Debug|Any CPU.Build.0 = Debug|Any CPU {1589D5A4-0CC4-4855-89E0-2E61BBC5E0B0}.Release|Any CPU.ActiveCfg = Release|Any CPU {1589D5A4-0CC4-4855-89E0-2E61BBC5E0B0}.Release|Any CPU.Build.0 = Release|Any CPU + {F93FFE42-71C1-44BD-9DBA-3559B307370C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F93FFE42-71C1-44BD-9DBA-3559B307370C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F93FFE42-71C1-44BD-9DBA-3559B307370C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F93FFE42-71C1-44BD-9DBA-3559B307370C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/net/Directory.Packages.props b/net/Directory.Packages.props index 3029cfae..134d42ec 100644 --- a/net/Directory.Packages.props +++ b/net/Directory.Packages.props @@ -1,18 +1,22 @@ - true true - + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + all + - diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj new file mode 100644 index 00000000..13d08f3e --- /dev/null +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -0,0 +1,28 @@ + + + + netstandard2.0 + false + enable + enable + latest + true + true + $(NoWarn);NU5128 + Code generator for Sails.Net. + + + + + + + + + + + + + + + + diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs new file mode 100644 index 00000000..0135e4b5 --- /dev/null +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -0,0 +1,38 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Sails.ClientGenerator; + +[Generator(LanguageNames.CSharp)] +public partial class SailsClientGenerator : IIncrementalGenerator +{ + public const string SailsClientAttributeFullName = "Sails.ClientGenerator.SailsClientAttribute"; + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + context.RegisterPostInitializationOutput(ctx => + { + ctx.AddSource("SailsClientAttribute.g.cs", """ +namespace Sails.ClientGenerator +{ + [System.AttributeUsage(System.AttributeTargets.Class)] + public class SailsClientAttribute : System.Attribute + { + } +} +"""); + }); + + var source = context.SyntaxProvider.ForAttributeWithMetadataName( + SailsClientAttributeFullName, + predicate: static (node, token) => node is ClassDeclarationSyntax, + transform: static (context, token) => context); + + context.RegisterSourceOutput(source, Generate); + } + + private static void Generate(SourceProductionContext context, GeneratorAttributeSyntaxContext source) + { + + } +} diff --git a/rs/client-gen-dotnet/src/lib.rs b/rs/client-gen-dotnet/src/lib.rs index 6d83d9fc..4dde9002 100644 --- a/rs/client-gen-dotnet/src/lib.rs +++ b/rs/client-gen-dotnet/src/lib.rs @@ -13,7 +13,7 @@ mod root_generator; mod service_generators; mod type_generators; -const SAILS: &str = "sails_rs"; +const BASE_NAMESPACE: &str = "sails_rs"; pub struct IdlPath<'a>(&'a Path); pub struct IdlString<'a>(&'a str); diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index 7293b4fe..3a7e4b74 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -121,23 +121,39 @@ impl<'ast> Visitor<'ast> for StructDefGenerator<'ast> { #[derive(Default)] struct EnumDefGenerator<'a> { type_name: &'a str, - tokens: Tokens, + enum_tokens: Tokens, + class_tokens: Tokens, } impl<'a> EnumDefGenerator<'a> { pub(crate) fn new(type_name: &'a str) -> Self { Self { type_name, - tokens: Tokens::new(), + enum_tokens: Tokens::new(), + class_tokens: Tokens::new(), } } pub(crate) fn finalize(self) -> Tokens { + let class_name = format!("Enum{}", self.type_name); quote!( $['\r'] public enum $(self.type_name) { - $(self.tokens) + $(self.enum_tokens) + } + + $['\r'] + public sealed class $(&class_name) : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust<$(self.type_name)> + { + $['\r'] + public $(&class_name)() + $['\r'] + { + $['\r'] + $(self.class_tokens) + $['\r'] + } } ) } @@ -145,12 +161,16 @@ impl<'a> EnumDefGenerator<'a> { impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { fn visit_enum_variant(&mut self, enum_variant: &'ast EnumVariant) { - quote_in! { self.tokens => + quote_in! { self.enum_tokens => $['\r'] $(summary_comment(enum_variant.docs())) }; - quote_in! { self.tokens => + quote_in! { self.enum_tokens => $['\r'] $(enum_variant.name()), }; + + quote_in! { self.class_tokens => + AddTypeDecoder<>($(self.type_name).$(enum_variant.name())); + } } } From b6521d880d4b0f2bc98e2613a25775b09cf606b1 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Thu, 24 Oct 2024 15:24:37 +0200 Subject: [PATCH 04/54] wip: type generator --- rs/client-gen-dotnet/src/lib.rs | 16 +- rs/client-gen-dotnet/src/root_generator.rs | 4 +- rs/client-gen-dotnet/src/type_generators.rs | 174 +++++++++++------- .../tests/snapshots/generator__full.snap.new | 113 +++++++++--- .../generator__full_with_sails_path.snap.new | 72 ++++++++ 5 files changed, 281 insertions(+), 98 deletions(-) create mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap.new diff --git a/rs/client-gen-dotnet/src/lib.rs b/rs/client-gen-dotnet/src/lib.rs index 4dde9002..11c88339 100644 --- a/rs/client-gen-dotnet/src/lib.rs +++ b/rs/client-gen-dotnet/src/lib.rs @@ -111,18 +111,20 @@ impl<'a> ClientGenerator<'a, IdlString<'a>> { pub fn generate(self, anonymous_service_name: &str) -> Result { let idl = self.idl.0; - // let sails_path = self.sails_path.unwrap_or(SAILS); - let mut generator = RootGenerator::new(anonymous_service_name, self.external_types); let program = sails_idl_parser::ast::parse_idl(idl).context("Failed to parse IDL")?; + + let mut generator = RootGenerator::new(anonymous_service_name, self.external_types); visitor::accept_program(&program, &mut generator); + let tokens = generator.finalize(); - let code_tokens = generator.finalize(); - let code = code_tokens.to_file_string()?; + let fmt = genco::fmt::Config::from_lang::() + .with_indentation(genco::fmt::Indentation::Space(4)); + let config = genco::lang::csharp::Config::default(); + let mut w = genco::fmt::FmtWriter::new(String::new()); - // Check for parsing errors - // let code = pretty_with_rustfmt(&code); + tokens.format_file(&mut w.as_formatter(&fmt), &config)?; - Ok(code) + Ok(w.into_inner()) } pub fn generate_to( diff --git a/rs/client-gen-dotnet/src/root_generator.rs b/rs/client-gen-dotnet/src/root_generator.rs index 33e02964..78a149f9 100644 --- a/rs/client-gen-dotnet/src/root_generator.rs +++ b/rs/client-gen-dotnet/src/root_generator.rs @@ -31,9 +31,7 @@ impl<'a> RootGenerator<'a> { } pub(crate) fn finalize(self) -> Tokens { - quote! { - $(self.tokens) - } + self.tokens } } diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index 3a7e4b74..51b8dc29 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -1,6 +1,6 @@ use crate::helpers::summary_comment; use convert_case::{Case, Casing}; -use csharp::Tokens; +use csharp::{block_comment, Tokens}; use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; @@ -37,22 +37,22 @@ impl<'a> TopLevelTypeGenerator<'a> { } } -impl<'a, 'ast> Visitor<'ast> for TopLevelTypeGenerator<'a> { - fn visit_type(&mut self, r#type: &'ast Type) { - quote_in! { self.tokens => - $['\r'] - $(summary_comment(r#type.docs())) - }; - visitor::accept_type(r#type, self); +impl<'a> Visitor<'a> for TopLevelTypeGenerator<'a> { + fn visit_type(&mut self, type_: &'a Type) { + self.tokens.push(); + self.tokens.append(summary_comment(type_.docs())); + self.tokens.push(); + visitor::accept_type(type_, self); + self.tokens.line(); } - fn visit_struct_def(&mut self, struct_def: &'ast StructDef) { + fn visit_struct_def(&mut self, struct_def: &'a StructDef) { let mut struct_def_generator = StructDefGenerator::new(self.type_name); struct_def_generator.visit_struct_def(struct_def); self.tokens.extend(struct_def_generator.finalize()); } - fn visit_enum_def(&mut self, enum_def: &'ast EnumDef) { + fn visit_enum_def(&mut self, enum_def: &'a EnumDef) { let mut enum_def_generator = EnumDefGenerator::new(self.type_name); enum_def_generator.visit_enum_def(enum_def); self.tokens.extend(enum_def_generator.finalize()); @@ -63,25 +63,55 @@ impl<'a, 'ast> Visitor<'ast> for TopLevelTypeGenerator<'a> { struct StructDefGenerator<'a> { type_name: &'a str, is_tuple_struct: bool, - tokens: Tokens, + props_tokens: Tokens, + encode_tokens: Tokens, + decode_tokens: Tokens, } impl<'a> StructDefGenerator<'a> { fn new(type_name: &'a str) -> Self { Self { type_name, - tokens: Tokens::new(), is_tuple_struct: false, + props_tokens: Tokens::new(), + encode_tokens: Tokens::new(), + decode_tokens: Tokens::new(), } } pub(crate) fn finalize(self) -> Tokens { - quote! { - $['\r'] - public partial record struct $(self.type_name) - ( - $(self.tokens) - ) + if self.is_tuple_struct { + Tokens::new() + } else { + quote! { + [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] + public sealed partial class $(self.type_name) : global::Substrate.NetApi.Model.Types.Base.BaseType + { + $(self.props_tokens) + + $(block_comment(vec![""])) + public override string TypeName() => $(quoted(self.type_name)); + + $(block_comment(vec![""])) + public override byte[] Encode() + { + var result = new List(); + $(self.encode_tokens) + return result.ToArray(); + } + + $(block_comment(vec![""])) + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + $(self.decode_tokens) + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); + } + } + } } } } @@ -99,20 +129,27 @@ impl<'ast> Visitor<'ast> for StructDefGenerator<'ast> { } fn visit_struct_field(&mut self, struct_field: &'ast StructField) { - let type_decl_code = generate_type_decl_with_path(struct_field.type_decl(), "".into()); - - quote_in! { self.tokens => - $['\r'] - $(csharp::block_comment(struct_field.docs())) - }; + let type_decl_code = generate_type_decl_code(struct_field.type_decl()); + self.props_tokens.push(); + self.props_tokens + .append(summary_comment(struct_field.docs())); + self.props_tokens.push(); if let Some(field_name) = struct_field.name() { - quote_in! { self.tokens => - $['\r'] $type_decl_code $(field_name.to_case(Case::Pascal)), + let field_name_pascal = field_name.to_case(Case::Pascal); + quote_in! { self.props_tokens => + public $(&type_decl_code) $(&field_name_pascal) { get; set; }$['\r'] + }; + quote_in! { self.encode_tokens => + result.AddRange($(&field_name_pascal).Encode());$['\r'] + }; + quote_in! { self.decode_tokens => + $(&field_name_pascal) = new $(&type_decl_code)();$['\r'] + $(&field_name_pascal).Decode(byteArray, ref p);$['\r'] }; } else { - quote_in! { self.tokens => - $['\r'] $type_decl_code, + quote_in! { self.props_tokens => + $(&type_decl_code), }; } } @@ -137,22 +174,16 @@ impl<'a> EnumDefGenerator<'a> { pub(crate) fn finalize(self) -> Tokens { let class_name = format!("Enum{}", self.type_name); quote!( - $['\r'] public enum $(self.type_name) { $(self.enum_tokens) } - $['\r'] public sealed class $(&class_name) : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust<$(self.type_name)> { - $['\r'] public $(&class_name)() - $['\r'] { - $['\r'] $(self.class_tokens) - $['\r'] } } ) @@ -162,14 +193,19 @@ impl<'a> EnumDefGenerator<'a> { impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { fn visit_enum_variant(&mut self, enum_variant: &'ast EnumVariant) { quote_in! { self.enum_tokens => - $['\r'] $(summary_comment(enum_variant.docs())) + $(summary_comment(enum_variant.docs())) }; quote_in! { self.enum_tokens => - $['\r'] $(enum_variant.name()), + $(enum_variant.name()), }; + let type_decl_code = if let Some(type_decl) = enum_variant.type_decl().as_ref() { + generate_type_decl_code(type_decl) + } else { + primitive_type_to_dotnet(PrimitiveType::Null).into() + }; quote_in! { self.class_tokens => - AddTypeDecoder<>($(self.type_name).$(enum_variant.name())); + this.AddTypeDecoder<$(type_decl_code)>($(self.type_name).$(enum_variant.name()));$['\r'] } } } @@ -182,7 +218,8 @@ struct TypeDeclGenerator { impl<'ast> Visitor<'ast> for TypeDeclGenerator { fn visit_optional_type_decl(&mut self, optional_type_decl: &'ast TypeDecl) { - self.code.push_str("Option<"); + self.code + .push_str("global::Substrate.NetApi.Model.Types.Base.BaseOpt<"); visitor::accept_type_decl(optional_type_decl, self); self.code.push('>'); } @@ -212,34 +249,8 @@ impl<'ast> Visitor<'ast> for TypeDeclGenerator { } fn visit_primitive_type_id(&mut self, primitive_type_id: PrimitiveType) { - self.code.push_str(match primitive_type_id { - PrimitiveType::U8 => "u8", - PrimitiveType::U16 => "u16", - PrimitiveType::U32 => "u32", - PrimitiveType::U64 => "u64", - PrimitiveType::U128 => "u128", - PrimitiveType::I8 => "i8", - PrimitiveType::I16 => "i16", - PrimitiveType::I32 => "i32", - PrimitiveType::I64 => "i64", - PrimitiveType::I128 => "i128", - PrimitiveType::Bool => "bool", - PrimitiveType::Str => "String", - PrimitiveType::Char => "char", - PrimitiveType::Null => "()", - PrimitiveType::ActorId => "ActorId", - PrimitiveType::CodeId => "CodeId", - PrimitiveType::MessageId => "MessageId", - PrimitiveType::H160 => "H160", - PrimitiveType::H256 => "H256", - PrimitiveType::U256 => "U256", - PrimitiveType::NonZeroU8 => "NonZeroU8", - PrimitiveType::NonZeroU16 => "NonZeroU16", - PrimitiveType::NonZeroU32 => "NonZeroU32", - PrimitiveType::NonZeroU64 => "NonZeroU64", - PrimitiveType::NonZeroU128 => "NonZeroU128", - PrimitiveType::NonZeroU256 => "NonZeroU256", - }); + self.code + .push_str(primitive_type_to_dotnet(primitive_type_id)); } fn visit_user_defined_type_id(&mut self, user_defined_type_id: &'ast str) { @@ -315,3 +326,34 @@ impl<'ast> Visitor<'ast> for StructTypeGenerator { } } } + +fn primitive_type_to_dotnet(primitive_type: PrimitiveType) -> &'static str { + match primitive_type { + PrimitiveType::U8 => "global::Substrate.NetApi.Model.Types.Primitive.U8", + PrimitiveType::U16 => "global::Substrate.NetApi.Model.Types.Primitive.U16", + PrimitiveType::U32 => "global::Substrate.NetApi.Model.Types.Primitive.U32", + PrimitiveType::U64 => "global::Substrate.NetApi.Model.Types.Primitive.U64", + PrimitiveType::U128 => "global::Substrate.NetApi.Model.Types.Primitive.U128", + PrimitiveType::I8 => "global::Substrate.NetApi.Model.Types.Primitive.I8", + PrimitiveType::I16 => "global::Substrate.NetApi.Model.Types.Primitive.I16", + PrimitiveType::I32 => "global::Substrate.NetApi.Model.Types.Primitive.I32", + PrimitiveType::I64 => "global::Substrate.NetApi.Model.Types.Primitive.I64", + PrimitiveType::I128 => "global::Substrate.NetApi.Model.Types.Primitive.I128", + PrimitiveType::Bool => "global::Substrate.NetApi.Model.Types.Primitive.Bool", + PrimitiveType::Str => "global::Substrate.NetApi.Model.Types.Primitive.Str", + PrimitiveType::Char => "global::Substrate.NetApi.Model.Types.Primitive.PrimChar", + PrimitiveType::Null => "global::Substrate.NetApi.Model.Types.Base.BaseVoid", + PrimitiveType::ActorId => "ActorId", + PrimitiveType::CodeId => "CodeId", + PrimitiveType::MessageId => "MessageId", + PrimitiveType::H160 => "H160", + PrimitiveType::H256 => "H256", + PrimitiveType::U256 => "U256", + PrimitiveType::NonZeroU8 => "NonZeroU8", + PrimitiveType::NonZeroU16 => "NonZeroU16", + PrimitiveType::NonZeroU32 => "NonZeroU32", + PrimitiveType::NonZeroU64 => "NonZeroU64", + PrimitiveType::NonZeroU128 => "NonZeroU128", + PrimitiveType::NonZeroU256 => "NonZeroU256", + } +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new index f20fbcae..75c8ce5f 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new @@ -3,25 +3,94 @@ source: rs/client-gen-dotnet/tests/generator.rs assertion_line: 65 expression: "gen(IDL, \"Service\")" --- - /// ThisThatSvcAppTupleStruct docspublic partial record struct ThisThatSvcAppTupleStruct { - /// field `bool` - pub bool, } - /// ThisThatSvcAppDoThatParam docspublic partial record struct ThisThatSvcAppDoThatParam { - /// field `query` - pub query: u32, - /// field `result` - pub result: String, - /// field `p3` - pub p3: ThisThatSvcAppManyVariants, } - /// ThisThatSvcAppManyVariants docs - public enum ThisThatSvcAppManyVariants { - /// variant `One` - One, - /// variant `Two` - Two, - Three, - Four, - Five, - Six, } - public enum T { - One, } +/// +/// ThisThatSvcAppTupleStruct docs +/// + +/// +/// ThisThatSvcAppDoThatParam docs +/// +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + /// + /// field `query` + /// + public global::Substrate.NetApi.Model.Types.Primitive.U32 Query { get; set; } + /// + /// field `result` + /// + public global::Substrate.NetApi.Model.Types.Primitive.Str Result { get; set; } + /// + /// field `p3` + /// + public ThisThatSvcAppManyVariants P3 { get; set; } + + /// + public override string TypeName() => "ThisThatSvcAppDoThatParam"; + + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(Query.Encode()); + result.AddRange(Result.Encode()); + result.AddRange(P3.Encode()); + return result.ToArray(); + } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + Query = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + Query.Decode(byteArray, ref p); + Result = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + Result.Decode(byteArray, ref p); + P3 = new ThisThatSvcAppManyVariants(); + P3.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); + } +} + +/// +/// ThisThatSvcAppManyVariants docs +/// +public enum ThisThatSvcAppManyVariants +{ + /// + /// variant `One` + /// One, + /// + /// variant `Two` + /// Two,Three,Four,Five,Six, +} + +public sealed class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumThisThatSvcAppManyVariants() + { + this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); + this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); + this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); + this.AddTypeDecoder<{a: global::Substrate.NetApi.Model.Types.Primitive.U32,b: global::Substrate.NetApi.Model.Types.Base.BaseOpt,}>(ThisThatSvcAppManyVariants.Four); + this.AddTypeDecoder<(global::Substrate.NetApi.Model.Types.Primitive.Str,global::Substrate.NetApi.Model.Types.Primitive.U32,)>(ThisThatSvcAppManyVariants.Five); + this.AddTypeDecoder<(global::Substrate.NetApi.Model.Types.Primitive.U32,)>(ThisThatSvcAppManyVariants.Six); + } +} + +public enum T +{ + One, +} + +public sealed class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumT() + { + this.AddTypeDecoder(T.One); + } +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap.new b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap.new new file mode 100644 index 00000000..1a4c1287 --- /dev/null +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap.new @@ -0,0 +1,72 @@ +--- +source: rs/client-gen-dotnet/tests/generator.rs +assertion_line: 198 +expression: code +--- +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } + public global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } + public ThisThatSvcAppManyVariants P3 { get; set; } + + /// + public override string TypeName() => "ThisThatSvcAppDoThatParam"; + + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(P1.Encode()); + result.AddRange(P2.Encode()); + result.AddRange(P3.Encode()); + return result.ToArray(); + } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + P1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + P1.Decode(byteArray, ref p); + P2 = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + P2.Decode(byteArray, ref p); + P3 = new ThisThatSvcAppManyVariants(); + P3.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); + } +} + +public enum ThisThatSvcAppManyVariants +{ + One,Two,Three,Four,Five,Six, +} + +public sealed class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumThisThatSvcAppManyVariants() + { + this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); + this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); + this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); + this.AddTypeDecoder<{a: global::Substrate.NetApi.Model.Types.Primitive.U32,b: global::Substrate.NetApi.Model.Types.Base.BaseOpt,}>(ThisThatSvcAppManyVariants.Four); + this.AddTypeDecoder<(global::Substrate.NetApi.Model.Types.Primitive.Str,global::Substrate.NetApi.Model.Types.Primitive.U32,)>(ThisThatSvcAppManyVariants.Five); + this.AddTypeDecoder<(global::Substrate.NetApi.Model.Types.Primitive.U32,)>(ThisThatSvcAppManyVariants.Six); + } +} + +public enum T +{ + One, +} + +public sealed class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumT() + { + this.AddTypeDecoder(T.One); + } +} From e8c1a908374bda58c6abd0d1a0f89bce7ab0b599 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Thu, 24 Oct 2024 19:18:54 +0200 Subject: [PATCH 05/54] wip: type generatore --- Cargo.lock | 1 + rs/client-gen-dotnet/Cargo.toml | 1 + rs/client-gen-dotnet/src/helpers.rs | 1 + rs/client-gen-dotnet/src/root_generator.rs | 23 +- rs/client-gen-dotnet/src/type_generators.rs | 269 +++++++------- .../snapshots/generator__basic_works.snap.new | 15 - .../tests/snapshots/generator__full.snap | 345 ++++++------------ .../tests/snapshots/generator__full.snap.new | 96 ----- .../generator__full_with_sails_path.snap | 273 +++++--------- .../generator__full_with_sails_path.snap.new | 72 ---- 10 files changed, 349 insertions(+), 747 deletions(-) delete mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap.new delete mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new delete mode 100644 rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap.new diff --git a/Cargo.lock b/Cargo.lock index fd7dbd57..7a5697dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6204,6 +6204,7 @@ dependencies = [ "convert_case 0.6.0", "genco", "insta", + "itertools 0.13.0", "parity-scale-codec", "sails-idl-parser", ] diff --git a/rs/client-gen-dotnet/Cargo.toml b/rs/client-gen-dotnet/Cargo.toml index 459cf811..390ec8f6 100644 --- a/rs/client-gen-dotnet/Cargo.toml +++ b/rs/client-gen-dotnet/Cargo.toml @@ -12,6 +12,7 @@ repository.workspace = true anyhow.workspace = true convert-case.workspace = true genco.workspace = true +itertools.workspace = true parity-scale-codec.workspace = true sails-idl-parser.workspace = true diff --git a/rs/client-gen-dotnet/src/helpers.rs b/rs/client-gen-dotnet/src/helpers.rs index fc98a86f..49eb238e 100644 --- a/rs/client-gen-dotnet/src/helpers.rs +++ b/rs/client-gen-dotnet/src/helpers.rs @@ -83,5 +83,6 @@ where } tokens.push(); tokens.append(ItemStr::Static("/// ")); + tokens.push(); } } diff --git a/rs/client-gen-dotnet/src/root_generator.rs b/rs/client-gen-dotnet/src/root_generator.rs index 78a149f9..36dc955a 100644 --- a/rs/client-gen-dotnet/src/root_generator.rs +++ b/rs/client-gen-dotnet/src/root_generator.rs @@ -14,6 +14,7 @@ pub(crate) struct RootGenerator<'a> { mocks_tokens: Tokens, anonymous_service_name: &'a str, external_types: HashMap<&'a str, &'a str>, + generated_types: Vec<&'a Type>, } impl<'a> RootGenerator<'a> { @@ -27,25 +28,31 @@ impl<'a> RootGenerator<'a> { traits_tokens: Tokens::new(), mocks_tokens: Tokens::new(), external_types, + generated_types: Vec::new(), } } - pub(crate) fn finalize(self) -> Tokens { + pub(crate) fn finalize(mut self) -> Tokens { + for &type_ in &self.generated_types { + let mut type_gen = TopLevelTypeGenerator::new(&type_.name(), &self.generated_types); + type_gen.visit_type(type_); + self.tokens.extend(type_gen.finalize()); + } self.tokens } } -impl<'a, 'ast> Visitor<'ast> for RootGenerator<'a> { - fn visit_ctor(&mut self, ctor: &'ast Ctor) {} +impl<'a> Visitor<'a> for RootGenerator<'a> { + fn visit_ctor(&mut self, ctor: &'a Ctor) {} - fn visit_service(&mut self, service: &'ast Service) {} + fn visit_service(&mut self, service: &'a Service) {} - fn visit_type(&mut self, t: &'ast Type) { + fn visit_type(&mut self, t: &'a Type) { if self.external_types.contains_key(t.name()) { return; } - let mut type_gen = TopLevelTypeGenerator::new(t.name()); - type_gen.visit_type(t); - self.tokens.extend(type_gen.finalize()); + // collect all generated types + // used later to add prefix to enum types + self.generated_types.push(t); } } diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index 51b8dc29..969357e2 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -4,16 +4,43 @@ use csharp::{block_comment, Tokens}; use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; -pub(crate) fn generate_type_decl_code(type_decl: &TypeDecl) -> String { - let mut type_decl_generator = TypeDeclGenerator::default(); +pub(crate) fn generate_type_decl_code<'a>(type_decl: &TypeDecl) -> String { + let mut type_decl_generator = TypeDeclGenerator { + code: String::new(), + generated_types: &Vec::new(), + }; + visitor::accept_type_decl(type_decl, &mut type_decl_generator); + type_decl_generator.code +} + +pub(crate) fn generate_type_decl_code_with_enums<'a>( + type_decl: &TypeDecl, + generated_types: &'a Vec<&'a Type>, +) -> String { + let mut type_decl_generator = TypeDeclGenerator { + code: String::new(), + generated_types, + }; visitor::accept_type_decl(type_decl, &mut type_decl_generator); type_decl_generator.code } +pub(crate) fn generate_struct_def_code_with_enums<'a>( + struct_def: &StructDef, + generated_types: &'a Vec<&'a Type>, +) -> String { + let mut type_decl_generator = TypeDeclGenerator { + code: String::new(), + generated_types, + }; + visitor::accept_struct_def(struct_def, &mut type_decl_generator); + type_decl_generator.code +} + pub(crate) fn generate_type_decl_with_path(type_decl: &TypeDecl, path: String) -> String { let mut type_decl_generator = TypeDeclGenerator { code: String::new(), - path, + generated_types: &Vec::new(), }; visitor::accept_type_decl(type_decl, &mut type_decl_generator); type_decl_generator.code @@ -21,13 +48,15 @@ pub(crate) fn generate_type_decl_with_path(type_decl: &TypeDecl, path: String) - pub(crate) struct TopLevelTypeGenerator<'a> { type_name: &'a str, + generated_types: &'a Vec<&'a Type>, tokens: Tokens, } impl<'a> TopLevelTypeGenerator<'a> { - pub(crate) fn new(type_name: &'a str) -> Self { + pub(crate) fn new(type_name: &'a str, generated_types: &'a Vec<&'a Type>) -> Self { Self { type_name, + generated_types, tokens: Tokens::new(), } } @@ -47,21 +76,22 @@ impl<'a> Visitor<'a> for TopLevelTypeGenerator<'a> { } fn visit_struct_def(&mut self, struct_def: &'a StructDef) { - let mut struct_def_generator = StructDefGenerator::new(self.type_name); + let mut struct_def_generator = + StructDefGenerator::new(self.type_name, self.generated_types); struct_def_generator.visit_struct_def(struct_def); self.tokens.extend(struct_def_generator.finalize()); } fn visit_enum_def(&mut self, enum_def: &'a EnumDef) { - let mut enum_def_generator = EnumDefGenerator::new(self.type_name); + let mut enum_def_generator = EnumDefGenerator::new(self.type_name, self.generated_types); enum_def_generator.visit_enum_def(enum_def); self.tokens.extend(enum_def_generator.finalize()); } } -#[derive(Default)] struct StructDefGenerator<'a> { type_name: &'a str, + generated_types: &'a Vec<&'a Type>, is_tuple_struct: bool, props_tokens: Tokens, encode_tokens: Tokens, @@ -69,9 +99,10 @@ struct StructDefGenerator<'a> { } impl<'a> StructDefGenerator<'a> { - fn new(type_name: &'a str) -> Self { + fn new(type_name: &'a str, generated_types: &'a Vec<&'a Type>) -> Self { Self { type_name, + generated_types, is_tuple_struct: false, props_tokens: Tokens::new(), encode_tokens: Tokens::new(), @@ -80,44 +111,57 @@ impl<'a> StructDefGenerator<'a> { } pub(crate) fn finalize(self) -> Tokens { - if self.is_tuple_struct { - Tokens::new() - } else { - quote! { - [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] - public sealed partial class $(self.type_name) : global::Substrate.NetApi.Model.Types.Base.BaseType + quote! { + [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] + public sealed partial class $(self.type_name) : global::Substrate.NetApi.Model.Types.Base.BaseType + { + $(self.props_tokens) + + $(block_comment(vec![""])) + public override string TypeName() => $(quoted(self.type_name)); + + $(block_comment(vec![""])) + public override byte[] Encode() { - $(self.props_tokens) - - $(block_comment(vec![""])) - public override string TypeName() => $(quoted(self.type_name)); - - $(block_comment(vec![""])) - public override byte[] Encode() - { - var result = new List(); - $(self.encode_tokens) - return result.ToArray(); - } - - $(block_comment(vec![""])) - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - $(self.decode_tokens) - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); - } + var result = new List(); + $(self.encode_tokens) + return result.ToArray(); + } + + $(block_comment(vec![""])) + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + $(self.decode_tokens) + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); } } } } + + fn tuple_struct(&mut self, struct_def: &'a StructDef) { + if struct_def.fields().is_empty() { + return; + } + let value_type = generate_struct_def_code_with_enums(struct_def, self.generated_types); + quote_in! { self.props_tokens => + public $(&value_type) Value { get; set; }$['\r'] + }; + quote_in! { self.encode_tokens => + result.AddRange(Value.Encode());$['\r'] + }; + quote_in! { self.decode_tokens => + Value = new $(&value_type)();$['\r'] + Value.Decode(byteArray, ref p);$['\r'] + }; + } } -impl<'ast> Visitor<'ast> for StructDefGenerator<'ast> { - fn visit_struct_def(&mut self, struct_def: &'ast StructDef) { +impl<'a> Visitor<'a> for StructDefGenerator<'a> { + fn visit_struct_def(&mut self, struct_def: &'a StructDef) { let is_regular_struct = struct_def.fields().iter().all(|f| f.name().is_some()); let is_tuple_struct = struct_def.fields().iter().all(|f| f.name().is_none()); if !is_regular_struct && !is_tuple_struct { @@ -125,11 +169,16 @@ impl<'ast> Visitor<'ast> for StructDefGenerator<'ast> { } self.is_tuple_struct = is_tuple_struct; + if is_tuple_struct { + self.tuple_struct(struct_def); + return; + } visitor::accept_struct_def(struct_def, self); } - fn visit_struct_field(&mut self, struct_field: &'ast StructField) { - let type_decl_code = generate_type_decl_code(struct_field.type_decl()); + fn visit_struct_field(&mut self, struct_field: &'a StructField) { + let type_decl_code = + generate_type_decl_code_with_enums(struct_field.type_decl(), self.generated_types); self.props_tokens.push(); self.props_tokens @@ -147,25 +196,22 @@ impl<'ast> Visitor<'ast> for StructDefGenerator<'ast> { $(&field_name_pascal) = new $(&type_decl_code)();$['\r'] $(&field_name_pascal).Decode(byteArray, ref p);$['\r'] }; - } else { - quote_in! { self.props_tokens => - $(&type_decl_code), - }; } } } -#[derive(Default)] struct EnumDefGenerator<'a> { type_name: &'a str, + generated_types: &'a Vec<&'a Type>, enum_tokens: Tokens, class_tokens: Tokens, } impl<'a> EnumDefGenerator<'a> { - pub(crate) fn new(type_name: &'a str) -> Self { + pub(crate) fn new(type_name: &'a str, generated_types: &'a Vec<&'a Type>) -> Self { Self { type_name, + generated_types, enum_tokens: Tokens::new(), class_tokens: Tokens::new(), } @@ -179,7 +225,7 @@ impl<'a> EnumDefGenerator<'a> { $(self.enum_tokens) } - public sealed class $(&class_name) : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust<$(self.type_name)> + public sealed partial class $(&class_name) : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust<$(self.type_name)> { public $(&class_name)() { @@ -196,11 +242,11 @@ impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { $(summary_comment(enum_variant.docs())) }; quote_in! { self.enum_tokens => - $(enum_variant.name()), + $(enum_variant.name()),$['\r'] }; let type_decl_code = if let Some(type_decl) = enum_variant.type_decl().as_ref() { - generate_type_decl_code(type_decl) + generate_type_decl_code_with_enums(type_decl, self.generated_types) } else { primitive_type_to_dotnet(PrimitiveType::Null).into() }; @@ -210,25 +256,20 @@ impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { } } -#[derive(Default)] -struct TypeDeclGenerator { +struct TypeDeclGenerator<'a> { code: String, - path: String, + generated_types: &'a Vec<&'a Type>, } -impl<'ast> Visitor<'ast> for TypeDeclGenerator { - fn visit_optional_type_decl(&mut self, optional_type_decl: &'ast TypeDecl) { +impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { + fn visit_optional_type_decl(&mut self, optional_type_decl: &'a TypeDecl) { self.code .push_str("global::Substrate.NetApi.Model.Types.Base.BaseOpt<"); visitor::accept_type_decl(optional_type_decl, self); self.code.push('>'); } - fn visit_result_type_decl( - &mut self, - ok_type_decl: &'ast TypeDecl, - err_type_decl: &'ast TypeDecl, - ) { + fn visit_result_type_decl(&mut self, ok_type_decl: &'a TypeDecl, err_type_decl: &'a TypeDecl) { self.code.push_str("Result<"); visitor::accept_type_decl(ok_type_decl, self); self.code.push_str(", "); @@ -236,16 +277,30 @@ impl<'ast> Visitor<'ast> for TypeDeclGenerator { self.code.push('>'); } - fn visit_vector_type_decl(&mut self, vector_type_decl: &'ast TypeDecl) { - self.code.push_str("Vec<"); + fn visit_vector_type_decl(&mut self, vector_type_decl: &'a TypeDecl) { + self.code + .push_str("global::Substrate.NetApi.Model.Types.Base.BaseVec<"); visitor::accept_type_decl(vector_type_decl, self); self.code.push('>'); } - fn visit_struct_def(&mut self, struct_def: &'ast StructDef) { - let mut struct_def_generator = StructTypeGenerator::new(self.path.clone()); - struct_def_generator.visit_struct_def(struct_def); - self.code.push_str(&struct_def_generator.code); + fn visit_struct_def(&mut self, struct_def: &'a StructDef) { + if struct_def.fields().is_empty() { + return; + } + if struct_def.fields().len() == 1 { + visitor::accept_type_decl(struct_def.fields()[0].type_decl(), self); + } else { + self.code + .push_str("global::Substrate.NetApi.Model.Types.Base.BaseTuple<"); + for field in struct_def.fields() { + visitor::accept_type_decl(field.type_decl(), self); + if struct_def.fields().last() != Some(field) { + self.code.push(','); + } + } + self.code.push('>'); + } } fn visit_primitive_type_id(&mut self, primitive_type_id: PrimitiveType) { @@ -253,19 +308,22 @@ impl<'ast> Visitor<'ast> for TypeDeclGenerator { .push_str(primitive_type_to_dotnet(primitive_type_id)); } - fn visit_user_defined_type_id(&mut self, user_defined_type_id: &'ast str) { - if !self.path.is_empty() { - self.code.push_str(&self.path); - self.code.push_str("::"); - } - self.code.push_str(user_defined_type_id); + fn visit_user_defined_type_id(&mut self, user_defined_type_id: &'a str) { + let is_enum = self + .generated_types + .iter() + .find(|&&t| t.name() == user_defined_type_id) + .map(|&t| matches!(t.def(), TypeDef::Enum(_))) + .unwrap_or_default(); + let type_id = if is_enum { + &format!("Enum{}", user_defined_type_id) + } else { + user_defined_type_id + }; + self.code.push_str(type_id); } - fn visit_map_type_decl( - &mut self, - key_type_decl: &'ast TypeDecl, - value_type_decl: &'ast TypeDecl, - ) { + fn visit_map_type_decl(&mut self, key_type_decl: &'a TypeDecl, value_type_decl: &'a TypeDecl) { self.code.push_str("BTreeMap<"); visitor::accept_type_decl(key_type_decl, self); self.code.push_str(", "); @@ -273,60 +331,13 @@ impl<'ast> Visitor<'ast> for TypeDeclGenerator { self.code.push('>'); } - fn visit_array_type_decl(&mut self, item_type_decl: &'ast TypeDecl, len: u32) { + fn visit_array_type_decl(&mut self, item_type_decl: &'a TypeDecl, len: u32) { self.code.push('['); visitor::accept_type_decl(item_type_decl, self); self.code.push_str(&format!("; {len}]")); } } -struct StructTypeGenerator { - code: String, - path: String, -} - -impl StructTypeGenerator { - fn new(path: String) -> Self { - Self { - code: String::new(), - path, - } - } -} - -impl<'ast> Visitor<'ast> for StructTypeGenerator { - fn visit_struct_def(&mut self, struct_def: &'ast StructDef) { - let is_regular_struct = struct_def.fields().iter().all(|f| f.name().is_some()); - let is_tuple_struct = struct_def.fields().iter().all(|f| f.name().is_none()); - if !is_regular_struct && !is_tuple_struct { - panic!("Struct must be either regular or tuple"); - } - if is_regular_struct { - self.code.push('{'); - } else { - self.code.push('('); - } - visitor::accept_struct_def(struct_def, self); - if is_regular_struct { - self.code.push('}'); - } else { - self.code.push(')'); - } - } - - fn visit_struct_field(&mut self, struct_field: &'ast StructField) { - let type_decl_code = - generate_type_decl_with_path(struct_field.type_decl(), self.path.clone()); - - if let Some(field_name) = struct_field.name() { - self.code - .push_str(&format!("{field_name}: {type_decl_code},")); - } else { - self.code.push_str(&format!("{type_decl_code},")); - } - } -} - fn primitive_type_to_dotnet(primitive_type: PrimitiveType) -> &'static str { match primitive_type { PrimitiveType::U8 => "global::Substrate.NetApi.Model.Types.Primitive.U8", @@ -343,9 +354,11 @@ fn primitive_type_to_dotnet(primitive_type: PrimitiveType) -> &'static str { PrimitiveType::Str => "global::Substrate.NetApi.Model.Types.Primitive.Str", PrimitiveType::Char => "global::Substrate.NetApi.Model.Types.Primitive.PrimChar", PrimitiveType::Null => "global::Substrate.NetApi.Model.Types.Base.BaseVoid", - PrimitiveType::ActorId => "ActorId", - PrimitiveType::CodeId => "CodeId", - PrimitiveType::MessageId => "MessageId", + PrimitiveType::ActorId => "global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId", + PrimitiveType::CodeId => "global::Substrate.Gear.Api.Generated.Model.gprimitives.CodeId", + PrimitiveType::MessageId => { + "global::Substrate.Gear.Api.Generated.Model.gprimitives.MessageId" + } PrimitiveType::H160 => "H160", PrimitiveType::H256 => "H256", PrimitiveType::U256 => "U256", diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap.new b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap.new deleted file mode 100644 index 902abe25..00000000 --- a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap.new +++ /dev/null @@ -1,15 +0,0 @@ ---- -source: rs/client-gen-dotnet/tests/generator.rs -assertion_line: 91 -expression: "gen(idl, \"Basic\")" ---- -public partial record struct MyParam { - pub f1: u32, - pub f2: Vec, - pub f3: Option<(u8,u32,)>, } - public enum MyParam2 { - Variant1, - Variant2, - Variant3, - Variant4, - Variant5, } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap index 5af38207..9a8aa2e3 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -1,266 +1,129 @@ --- -source: rs/client-gen/tests/generator.rs +source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(IDL, \"Service\")" --- -// Code generated by sails-client-gen. DO NOT EDIT. -#[allow(unused_imports)] -use sails_rs::collections::BTreeMap; -#[allow(unused_imports)] -use sails_rs::{ - calls::{Activation, Call, Query, Remoting, RemotingAction}, - prelude::*, - String, -}; -pub struct ServiceFactory { - #[allow(dead_code)] - remoting: R, -} -impl ServiceFactory { - #[allow(unused)] - pub fn new(remoting: R) -> Self { - Self { remoting } - } -} -impl traits::ServiceFactory for ServiceFactory { - type Args = R::Args; - /// New constructor - fn new(&self, a: u32) -> impl Activation { - RemotingAction::<_, service_factory::io::New>::new(self.remoting.clone(), a) - } -} - -pub mod service_factory { - use super::*; - pub mod io { - use super::*; - use sails_rs::calls::ActionIo; - pub struct New(()); - impl New { - #[allow(dead_code)] - pub fn encode_call(a: u32) -> Vec { - ::encode_call(&a) - } - } - impl ActionIo for New { - const ROUTE: &'static [u8] = &[12, 78, 101, 119]; - type Params = u32; - type Reply = (); - } - } -} -pub struct Service { - remoting: R, -} -impl Service { - pub fn new(remoting: R) -> Self { - Self { remoting } - } -} -impl traits::Service for Service { - type Args = R::Args; - /// Some description - fn do_this( - &mut self, - p1: u32, - p2: String, - p3: (Option, u8), - p4: ThisThatSvcAppTupleStruct, - ) -> impl Call { - RemotingAction::<_, service::io::DoThis>::new(self.remoting.clone(), (p1, p2, p3, p4)) - } - /// Some multiline description - /// Second line - /// Third line - fn do_that( - &mut self, - param: ThisThatSvcAppDoThatParam, - ) -> impl Call, Args = R::Args> { - RemotingAction::<_, service::io::DoThat>::new(self.remoting.clone(), param) - } - /// This is a query - fn this(&self, v1: Vec) -> impl Query { - RemotingAction::<_, service::io::This>::new(self.remoting.clone(), v1) - } - /// This is a second query - /// This is a second line - fn that(&self, v1: ()) -> impl Query, Args = R::Args> { - RemotingAction::<_, service::io::That>::new(self.remoting.clone(), v1) - } -} +/// +/// ThisThatSvcAppTupleStruct docs +/// +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } -pub mod service { - use super::*; + /// + public override string TypeName() => "ThisThatSvcAppTupleStruct"; - pub mod io { - use super::*; - use sails_rs::calls::ActionIo; - pub struct DoThis(()); - impl DoThis { - #[allow(dead_code)] - pub fn encode_call( - p1: u32, - p2: String, - p3: (Option, u8), - p4: super::ThisThatSvcAppTupleStruct, - ) -> Vec { - ::encode_call(&(p1, p2, p3, p4)) - } - } - impl ActionIo for DoThis { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; - type Params = ( - u32, - String, - (Option, u8), - super::ThisThatSvcAppTupleStruct, - ); - type Reply = (String, u32); - } - pub struct DoThat(()); - impl DoThat { - #[allow(dead_code)] - pub fn encode_call(param: super::ThisThatSvcAppDoThatParam) -> Vec { - ::encode_call(¶m) - } - } - impl ActionIo for DoThat { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; - type Params = super::ThisThatSvcAppDoThatParam; - type Reply = Result<(String, u32), (String,)>; - } - pub struct This(()); - impl This { - #[allow(dead_code)] - pub fn encode_call(v1: Vec) -> Vec { - ::encode_call(&v1) - } - } - impl ActionIo for This { - const ROUTE: &'static [u8] = &[16, 84, 104, 105, 115]; - type Params = Vec; - type Reply = u32; - } - pub struct That(()); - impl That { - #[allow(dead_code)] - pub fn encode_call(v1: ()) -> Vec { - ::encode_call(&v1) - } - } - impl ActionIo for That { - const ROUTE: &'static [u8] = &[16, 84, 104, 97, 116]; - type Params = (); - type Reply = Result; - } + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(Value.Encode()); + return result.ToArray(); } - #[allow(dead_code)] - #[cfg(not(target_arch = "wasm32"))] - pub mod events { - use super::*; - use sails_rs::events::*; - #[derive(PartialEq, Debug, Encode, Decode)] - #[codec(crate = sails_rs::scale_codec)] - pub enum ServiceEvents { - /// `This` Done - ThisDone(u32), - /// `That` Done too - ThatDone { p1: String }, - } - impl EventIo for ServiceEvents { - const ROUTE: &'static [u8] = &[]; - const EVENT_NAMES: &'static [&'static [u8]] = &[ - &[32, 84, 104, 105, 115, 68, 111, 110, 101], - &[32, 84, 104, 97, 116, 68, 111, 110, 101], - ]; - type Event = Self; - } - pub fn listener>>(remoting: R) -> impl Listener { - RemotingListener::<_, ServiceEvents>::new(remoting) - } + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); + Value.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); } } -/// ThisThatSvcAppTupleStruct docs -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub struct ThisThatSvcAppTupleStruct( - /// field `bool` - pub bool, -); + +/// /// ThisThatSvcAppDoThatParam docs -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub struct ThisThatSvcAppDoThatParam { +/// +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + /// /// field `query` - pub query: u32, + /// + public global::Substrate.NetApi.Model.Types.Primitive.U32 Query { get; set; } + /// /// field `result` - pub result: String, + /// + public global::Substrate.NetApi.Model.Types.Primitive.Str Result { get; set; } + /// /// field `p3` - pub p3: ThisThatSvcAppManyVariants, + /// + public EnumThisThatSvcAppManyVariants P3 { get; set; } + + /// + public override string TypeName() => "ThisThatSvcAppDoThatParam"; + + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(Query.Encode()); + result.AddRange(Result.Encode()); + result.AddRange(P3.Encode()); + return result.ToArray(); + } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + Query = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + Query.Decode(byteArray, ref p); + Result = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + Result.Decode(byteArray, ref p); + P3 = new EnumThisThatSvcAppManyVariants(); + P3.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); + } } + +/// /// ThisThatSvcAppManyVariants docs -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub enum ThisThatSvcAppManyVariants { +/// +public enum ThisThatSvcAppManyVariants +{ + /// /// variant `One` + /// One, + /// /// variant `Two` - Two(u32), - Three(Option), - Four { - a: u32, - b: Option, - }, - Five((String, u32)), - Six((u32,)), -} -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub enum T { - One, + /// + Two, + Three, + Four, + Five, + Six, } -pub mod traits { - use super::*; - #[allow(dead_code)] - pub trait ServiceFactory { - type Args; - #[allow(clippy::new_ret_no_self)] - #[allow(clippy::wrong_self_convention)] - fn new(&self, a: u32) -> impl Activation; - } - - #[allow(clippy::type_complexity)] - pub trait Service { - type Args; - fn do_this( - &mut self, - p1: u32, - p2: String, - p3: (Option, u8), - p4: ThisThatSvcAppTupleStruct, - ) -> impl Call; - fn do_that( - &mut self, - param: ThisThatSvcAppDoThatParam, - ) -> impl Call, Args = Self::Args>; - fn this(&self, v1: Vec) -> impl Query; - fn that(&self, v1: ()) -> impl Query, Args = Self::Args>; +public sealed partial class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumThisThatSvcAppManyVariants() + { + this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); + this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); + this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); + this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); + this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); + this.AddTypeDecoder(ThisThatSvcAppManyVariants.Six); } } -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -extern crate std; +public enum T +{ + One, +} -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -pub mod mockall { - use super::*; - use sails_rs::mockall::*; - mock! { pub Service {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::Service for Service { type Args = A; fn do_this (&mut self, p1: u32,p2: String,p3: (Option,u8,),p4: ThisThatSvcAppTupleStruct,) -> MockCall;fn do_that (&mut self, param: ThisThatSvcAppDoThatParam,) -> MockCall>;fn this (& self, v1: Vec,) -> MockQuery;fn that (& self, v1: (),) -> MockQuery>; } } +public sealed partial class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumT() + { + this.AddTypeDecoder(T.One); + } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new deleted file mode 100644 index 75c8ce5f..00000000 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap.new +++ /dev/null @@ -1,96 +0,0 @@ ---- -source: rs/client-gen-dotnet/tests/generator.rs -assertion_line: 65 -expression: "gen(IDL, \"Service\")" ---- -/// -/// ThisThatSvcAppTupleStruct docs -/// - -/// -/// ThisThatSvcAppDoThatParam docs -/// -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - /// - /// field `query` - /// - public global::Substrate.NetApi.Model.Types.Primitive.U32 Query { get; set; } - /// - /// field `result` - /// - public global::Substrate.NetApi.Model.Types.Primitive.Str Result { get; set; } - /// - /// field `p3` - /// - public ThisThatSvcAppManyVariants P3 { get; set; } - - /// - public override string TypeName() => "ThisThatSvcAppDoThatParam"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(Query.Encode()); - result.AddRange(Result.Encode()); - result.AddRange(P3.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - Query = new global::Substrate.NetApi.Model.Types.Primitive.U32(); - Query.Decode(byteArray, ref p); - Result = new global::Substrate.NetApi.Model.Types.Primitive.Str(); - Result.Decode(byteArray, ref p); - P3 = new ThisThatSvcAppManyVariants(); - P3.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); - } -} - -/// -/// ThisThatSvcAppManyVariants docs -/// -public enum ThisThatSvcAppManyVariants -{ - /// - /// variant `One` - /// One, - /// - /// variant `Two` - /// Two,Three,Four,Five,Six, -} - -public sealed class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumThisThatSvcAppManyVariants() - { - this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); - this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); - this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); - this.AddTypeDecoder<{a: global::Substrate.NetApi.Model.Types.Primitive.U32,b: global::Substrate.NetApi.Model.Types.Base.BaseOpt,}>(ThisThatSvcAppManyVariants.Four); - this.AddTypeDecoder<(global::Substrate.NetApi.Model.Types.Primitive.Str,global::Substrate.NetApi.Model.Types.Primitive.U32,)>(ThisThatSvcAppManyVariants.Five); - this.AddTypeDecoder<(global::Substrate.NetApi.Model.Types.Primitive.U32,)>(ThisThatSvcAppManyVariants.Six); - } -} - -public enum T -{ - One, -} - -public sealed class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumT() - { - this.AddTypeDecoder(T.One); - } -} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap index ba3df807..10327e82 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -1,206 +1,105 @@ --- -source: rs/client-gen/tests/generator.rs +source: rs/client-gen-dotnet/tests/generator.rs expression: code --- -// Code generated by sails-client-gen. DO NOT EDIT. -#[allow(unused_imports)] -use my_crate::sails::collections::BTreeMap; -#[allow(unused_imports)] -use my_crate::sails::{ - calls::{Activation, Call, Query, Remoting, RemotingAction}, - prelude::*, - String, -}; -pub struct ServiceFactory { - #[allow(dead_code)] - remoting: R, -} -impl ServiceFactory { - #[allow(unused)] - pub fn new(remoting: R) -> Self { - Self { remoting } - } -} -impl traits::ServiceFactory for ServiceFactory { - type Args = R::Args; - fn new(&self, a: u32) -> impl Activation { - RemotingAction::<_, service_factory::io::New>::new(self.remoting.clone(), a) - } -} +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } + + /// + public override string TypeName() => "ThisThatSvcAppTupleStruct"; -pub mod service_factory { - use super::*; - pub mod io { - use super::*; - use my_crate::sails::calls::ActionIo; - pub struct New(()); - impl New { - #[allow(dead_code)] - pub fn encode_call(a: u32) -> Vec { - ::encode_call(&a) - } - } - impl ActionIo for New { - const ROUTE: &'static [u8] = &[12, 78, 101, 119]; - type Params = u32; - type Reply = (); - } + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(Value.Encode()); + return result.ToArray(); } -} -pub struct Service { - remoting: R, -} -impl Service { - pub fn new(remoting: R) -> Self { - Self { remoting } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); + Value.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); } } -impl traits::Service for Service { - type Args = R::Args; - fn do_this( - &mut self, - p1: u32, - p2: String, - p3: (Option, u8), - p4: ThisThatSvcAppTupleStruct, - ) -> impl Call { - RemotingAction::<_, service::io::DoThis>::new(self.remoting.clone(), (p1, p2, p3, p4)) - } - fn do_that( - &mut self, - param: ThisThatSvcAppDoThatParam, - ) -> impl Call, Args = R::Args> { - RemotingAction::<_, service::io::DoThat>::new(self.remoting.clone(), param) - } - fn this(&self, v1: Vec) -> impl Query { - RemotingAction::<_, service::io::This>::new(self.remoting.clone(), v1) + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } + public global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } + public EnumThisThatSvcAppManyVariants P3 { get; set; } + + /// + public override string TypeName() => "ThisThatSvcAppDoThatParam"; + + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(P1.Encode()); + result.AddRange(P2.Encode()); + result.AddRange(P3.Encode()); + return result.ToArray(); } - fn that(&self, v1: ()) -> impl Query, Args = R::Args> { - RemotingAction::<_, service::io::That>::new(self.remoting.clone(), v1) + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + P1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + P1.Decode(byteArray, ref p); + P2 = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + P2.Decode(byteArray, ref p); + P3 = new EnumThisThatSvcAppManyVariants(); + P3.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); } } -pub mod service { - use super::*; +public enum ThisThatSvcAppManyVariants +{ + One, + Two, + Three, + Four, + Five, + Six, +} - pub mod io { - use super::*; - use my_crate::sails::calls::ActionIo; - pub struct DoThis(()); - impl DoThis { - #[allow(dead_code)] - pub fn encode_call( - p1: u32, - p2: String, - p3: (Option, u8), - p4: super::ThisThatSvcAppTupleStruct, - ) -> Vec { - ::encode_call(&(p1, p2, p3, p4)) - } - } - impl ActionIo for DoThis { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; - type Params = ( - u32, - String, - (Option, u8), - super::ThisThatSvcAppTupleStruct, - ); - type Reply = (String, u32); - } - pub struct DoThat(()); - impl DoThat { - #[allow(dead_code)] - pub fn encode_call(param: super::ThisThatSvcAppDoThatParam) -> Vec { - ::encode_call(¶m) - } - } - impl ActionIo for DoThat { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; - type Params = super::ThisThatSvcAppDoThatParam; - type Reply = Result<(String, u32), (String,)>; - } - pub struct This(()); - impl This { - #[allow(dead_code)] - pub fn encode_call(v1: Vec) -> Vec { - ::encode_call(&v1) - } - } - impl ActionIo for This { - const ROUTE: &'static [u8] = &[16, 84, 104, 105, 115]; - type Params = Vec; - type Reply = u32; - } - pub struct That(()); - impl That { - #[allow(dead_code)] - pub fn encode_call(v1: ()) -> Vec { - ::encode_call(&v1) - } - } - impl ActionIo for That { - const ROUTE: &'static [u8] = &[16, 84, 104, 97, 116]; - type Params = (); - type Reply = Result; - } +public sealed partial class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumThisThatSvcAppManyVariants() + { + this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); + this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); + this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); + this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); + this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); + this.AddTypeDecoder(ThisThatSvcAppManyVariants.Six); } } -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = my_crate::sails::scale_codec)] -#[scale_info(crate = my_crate::sails::scale_info)] -pub struct ThisThatSvcAppTupleStruct(pub bool); -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = my_crate::sails::scale_codec)] -#[scale_info(crate = my_crate::sails::scale_info)] -pub struct ThisThatSvcAppDoThatParam { - pub p1: u32, - pub p2: String, - pub p3: ThisThatSvcAppManyVariants, -} -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = my_crate::sails::scale_codec)] -#[scale_info(crate = my_crate::sails::scale_info)] -pub enum ThisThatSvcAppManyVariants { - One, - Two(u32), - Three(Option), - Four { a: u32, b: Option }, - Five((String, u32)), - Six((u32,)), -} -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = my_crate::sails::scale_codec)] -#[scale_info(crate = my_crate::sails::scale_info)] -pub enum T { + +public enum T +{ One, } -pub mod traits { - use super::*; - #[allow(dead_code)] - pub trait ServiceFactory { - type Args; - #[allow(clippy::new_ret_no_self)] - #[allow(clippy::wrong_self_convention)] - fn new(&self, a: u32) -> impl Activation; - } - - #[allow(clippy::type_complexity)] - pub trait Service { - type Args; - fn do_this( - &mut self, - p1: u32, - p2: String, - p3: (Option, u8), - p4: ThisThatSvcAppTupleStruct, - ) -> impl Call; - fn do_that( - &mut self, - param: ThisThatSvcAppDoThatParam, - ) -> impl Call, Args = Self::Args>; - fn this(&self, v1: Vec) -> impl Query; - fn that(&self, v1: ()) -> impl Query, Args = Self::Args>; +public sealed partial class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumT() + { + this.AddTypeDecoder(T.One); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap.new b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap.new deleted file mode 100644 index 1a4c1287..00000000 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap.new +++ /dev/null @@ -1,72 +0,0 @@ ---- -source: rs/client-gen-dotnet/tests/generator.rs -assertion_line: 198 -expression: code ---- -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - public global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } - public global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } - public ThisThatSvcAppManyVariants P3 { get; set; } - - /// - public override string TypeName() => "ThisThatSvcAppDoThatParam"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(P1.Encode()); - result.AddRange(P2.Encode()); - result.AddRange(P3.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - P1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); - P1.Decode(byteArray, ref p); - P2 = new global::Substrate.NetApi.Model.Types.Primitive.Str(); - P2.Decode(byteArray, ref p); - P3 = new ThisThatSvcAppManyVariants(); - P3.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); - } -} - -public enum ThisThatSvcAppManyVariants -{ - One,Two,Three,Four,Five,Six, -} - -public sealed class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumThisThatSvcAppManyVariants() - { - this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); - this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); - this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); - this.AddTypeDecoder<{a: global::Substrate.NetApi.Model.Types.Primitive.U32,b: global::Substrate.NetApi.Model.Types.Base.BaseOpt,}>(ThisThatSvcAppManyVariants.Four); - this.AddTypeDecoder<(global::Substrate.NetApi.Model.Types.Primitive.Str,global::Substrate.NetApi.Model.Types.Primitive.U32,)>(ThisThatSvcAppManyVariants.Five); - this.AddTypeDecoder<(global::Substrate.NetApi.Model.Types.Primitive.U32,)>(ThisThatSvcAppManyVariants.Six); - } -} - -public enum T -{ - One, -} - -public sealed class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumT() - { - this.AddTypeDecoder(T.One); - } -} From 01a2a51a79a93347657064a40488c29cb93ed5ab Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 25 Oct 2024 16:02:26 +0200 Subject: [PATCH 06/54] wip: dotnet generators --- rs/client-gen-dotnet/src/ctor_generators.rs | 213 ++++++------------ rs/client-gen-dotnet/src/helpers.rs | 9 +- rs/client-gen-dotnet/src/root_generator.rs | 26 ++- .../src/service_generators.rs | 127 ++--------- rs/client-gen-dotnet/src/type_generators.rs | 54 ++++- .../tests/snapshots/generator__full.snap | 45 +++- .../generator__full_with_sails_path.snap | 42 +++- 7 files changed, 243 insertions(+), 273 deletions(-) diff --git a/rs/client-gen-dotnet/src/ctor_generators.rs b/rs/client-gen-dotnet/src/ctor_generators.rs index 326899e6..3743597f 100644 --- a/rs/client-gen-dotnet/src/ctor_generators.rs +++ b/rs/client-gen-dotnet/src/ctor_generators.rs @@ -1,178 +1,99 @@ -use crate::{ - helpers::*, io_generators::generate_io_struct, type_generators::generate_type_decl_code, -}; +use crate::{helpers::*, type_generators::TypeDeclGenerator}; use convert_case::{Case, Casing}; +use csharp::{block_comment, Tokens}; use genco::prelude::*; -use rust::Tokens; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; pub(crate) struct CtorFactoryGenerator<'a> { - service_name: &'a str, - sails_path: &'a str, - tokens: Tokens, - io_tokens: Tokens, + service_name: String, + type_generator: TypeDeclGenerator<'a>, + class_tokens: Tokens, + interface_tokens: Tokens, } impl<'a> CtorFactoryGenerator<'a> { - pub(crate) fn new(service_name: &'a str, sails_path: &'a str) -> Self { + pub(crate) fn new(service_name: String, type_generator: TypeDeclGenerator<'a>) -> Self { Self { service_name, - sails_path, - tokens: Tokens::new(), - io_tokens: Tokens::new(), + type_generator, + class_tokens: Tokens::new(), + interface_tokens: Tokens::new(), } } pub(crate) fn finalize(self) -> Tokens { - let service_name_snake = self.service_name.to_case(Case::Snake); + let class_name = format!("{}Factory", self.service_name); quote! { - $(self.tokens) - $['\n'] - pub mod $(service_name_snake)_factory { - use super::*; - pub mod io { - use super::*; - use $(self.sails_path)::calls::ActionIo; - $(self.io_tokens) - } - } - } - } -} - -impl<'a, 'ast> Visitor<'ast> for CtorFactoryGenerator<'a> { - fn visit_ctor(&mut self, ctor: &'ast Ctor) { - quote_in! {self.tokens => - pub struct $(self.service_name)Factory { - #[allow(dead_code)] - remoting: R, + public interface I$(&class_name) + { + $(self.interface_tokens) } + $['\n'] + public partial class $(&class_name) : I$(&class_name) + { + private readonly IRemoting remoting; - impl $(self.service_name)Factory { - #[allow(unused)] - pub fn new(remoting: R) -> Self { - Self { - remoting, - } + public $(&class_name)(IRemoting remoting) + { + this.remoting = remoting; } - } - - impl traits::$(self.service_name)Factory for $(self.service_name)Factory $("{") - type Args = R::Args; - }; - visitor::accept_ctor(ctor, self); - - quote_in! { self.tokens => - $['\r'] $("}") - }; - } - - fn visit_ctor_func(&mut self, func: &'ast CtorFunc) { - let fn_name = func.name(); - let fn_name_snake = fn_name.to_case(Case::Snake); - let fn_name_snake = fn_name_snake.as_str(); - - for doc in func.docs() { - quote_in! { self.tokens => - $['\r'] $("///") $doc - }; - } - - quote_in! { self.tokens => - $['\r'] fn $fn_name_snake$("(")&self, - }; - - visitor::accept_ctor_func(func, self); - - let args = encoded_args(func.params()); - - let service_name_snake = self.service_name.to_case(Case::Snake); - let params_type = format!("{service_name_snake}_factory::io::{fn_name}"); - - quote_in! { self.tokens => - $(")") -> impl Activation { - RemotingAction::<_, $params_type>::new(self.remoting.clone(), $args) + $(self.class_tokens) } - }; - - let route_bytes = path_bytes(fn_name).0; - let struct_tokens = generate_io_struct(fn_name, func.params(), None, route_bytes.as_str()); - - quote_in! { self.io_tokens => - $struct_tokens - }; - } - - fn visit_func_param(&mut self, func_param: &'ast FuncParam) { - let type_decl_code = generate_type_decl_code(func_param.type_decl()); - quote_in! { self.tokens => - $(func_param.name()): $(type_decl_code), - }; - } -} - -pub(crate) struct CtorTraitGenerator { - service_name: String, - tokens: Tokens, -} - -impl CtorTraitGenerator { - pub(crate) fn new(service_name: String) -> Self { - Self { - service_name, - tokens: Tokens::new(), + $['\n'] } } - - pub(crate) fn finalize(self) -> Tokens { - self.tokens - } } -impl<'ast> Visitor<'ast> for CtorTraitGenerator { - fn visit_ctor(&mut self, ctor: &'ast Ctor) { - quote_in! {self.tokens => - #[allow(dead_code)] - pub trait $(&self.service_name)Factory $("{") - type Args; - }; - +impl<'a> Visitor<'a> for CtorFactoryGenerator<'a> { + fn visit_ctor(&mut self, ctor: &'a Ctor) { visitor::accept_ctor(ctor, self); - - quote_in! {self.tokens => - $['\r'] $("}") - }; } - fn visit_ctor_func(&mut self, func: &'ast CtorFunc) { - let fn_name = func.name(); - let fn_name_snake = fn_name.to_case(Case::Snake); - let fn_name_snake = fn_name_snake.as_str(); - - if fn_name_snake == "new" { - quote_in! {self.tokens => - #[allow(clippy::new_ret_no_self)] - #[allow(clippy::wrong_self_convention)] - }; - } - - quote_in! {self.tokens => - $['\r'] fn $fn_name_snake$("(")&self, + fn visit_ctor_func(&mut self, func: &'a CtorFunc) { + let func_name_pascal = func.name().to_case(Case::Pascal); + + self.interface_tokens.push(); + self.interface_tokens.append(summary_comment(func.docs())); + self.interface_tokens.push(); + + let route_bytes = path_bytes(func.name()).0; + let args = encoded_fn_args(func.params()); + let args_with_type = func + .params() + .iter() + .map(|p| { + format!( + "{} {}", + self.type_generator.generate_type_decl(p.type_decl()), + p.name().to_case(Case::Camel) + ) + }) + .collect::>() + .join(",\r"); + + let type_decls = func + .params() + .iter() + .map(|p| p.type_decl()) + .collect::>(); + let tuple_arg_type = self.type_generator.generate_types_as_tuple(type_decls); + + quote_in! { self.interface_tokens => + IActivation $(&func_name_pascal)($['\r'] + $(&args_with_type));$['\r'] }; - visitor::accept_ctor_func(func, self); - - quote_in! {self.tokens => - $(")") -> impl Activation; - }; - } - - fn visit_func_param(&mut self, func_param: &'ast FuncParam) { - let type_decl_code = generate_type_decl_code(func_param.type_decl()); - - quote_in! { self.tokens => - $(func_param.name()): $(type_decl_code), + quote_in! { self.class_tokens => + $(block_comment(vec![""])) + public IActivation $(&func_name_pascal)($['\r'] + $(&args_with_type)) + { + return new RemotingAction<$(&tuple_arg_type)>( + this.remoting, + new byte[] { $(&route_bytes) }, + new $(&tuple_arg_type)($(&args))); + } }; } } diff --git a/rs/client-gen-dotnet/src/helpers.rs b/rs/client-gen-dotnet/src/helpers.rs index 49eb238e..c86afdc4 100644 --- a/rs/client-gen-dotnet/src/helpers.rs +++ b/rs/client-gen-dotnet/src/helpers.rs @@ -1,3 +1,4 @@ +use convert_case::Casing; use genco::{ lang::{csharp::Tokens, Csharp}, tokens::{FormatInto, ItemStr}, @@ -11,13 +12,11 @@ pub(crate) fn path_bytes(path: &str) -> (String, usize) { } else { let service_path_bytes = path.encode(); let service_path_encoded_length = service_path_bytes.len(); - let mut service_path_bytes = service_path_bytes + let service_path_bytes = service_path_bytes .into_iter() .map(|x| x.to_string()) .collect::>() - .join(","); - - service_path_bytes.push(','); + .join(", "); (service_path_bytes, service_path_encoded_length) } @@ -38,7 +37,7 @@ pub(crate) fn method_bytes(fn_name: &str) -> (String, usize) { pub(crate) fn encoded_fn_args(params: &[FuncParam]) -> String { params .iter() - .map(|a| a.name()) + .map(|a| a.name().to_case(convert_case::Case::Camel)) .collect::>() .join(", ") } diff --git a/rs/client-gen-dotnet/src/root_generator.rs b/rs/client-gen-dotnet/src/root_generator.rs index 36dc955a..86e90915 100644 --- a/rs/client-gen-dotnet/src/root_generator.rs +++ b/rs/client-gen-dotnet/src/root_generator.rs @@ -10,8 +10,6 @@ use std::collections::HashMap; pub(crate) struct RootGenerator<'a> { tokens: Tokens, - traits_tokens: Tokens, - mocks_tokens: Tokens, anonymous_service_name: &'a str, external_types: HashMap<&'a str, &'a str>, generated_types: Vec<&'a Type>, @@ -23,10 +21,8 @@ impl<'a> RootGenerator<'a> { external_types: HashMap<&'a str, &'a str>, ) -> Self { Self { - anonymous_service_name, tokens: Tokens::new(), - traits_tokens: Tokens::new(), - mocks_tokens: Tokens::new(), + anonymous_service_name, external_types, generated_types: Vec::new(), } @@ -43,9 +39,25 @@ impl<'a> RootGenerator<'a> { } impl<'a> Visitor<'a> for RootGenerator<'a> { - fn visit_ctor(&mut self, ctor: &'a Ctor) {} + fn visit_ctor(&mut self, ctor: &'a Ctor) { + let mut ctor_gen = CtorFactoryGenerator::new( + self.anonymous_service_name.to_case(Case::Pascal), + TypeDeclGenerator::new(&self.generated_types), + ); + ctor_gen.visit_ctor(ctor); + self.tokens.extend(ctor_gen.finalize()); + } - fn visit_service(&mut self, service: &'a Service) {} + fn visit_service(&mut self, service: &'a Service) { + let service_name = if service.name().is_empty() { + self.anonymous_service_name.to_case(Case::Pascal) + } else { + service.name().to_case(Case::Pascal) + }; + let mut service_gen = ServiceClientGenerator::new(service_name); + service_gen.visit_service(service); + self.tokens.extend(service_gen.finalize()); + } fn visit_type(&mut self, t: &'a Type) { if self.external_types.contains_key(t.name()) { diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/rs/client-gen-dotnet/src/service_generators.rs index 429ec550..a00ac4f7 100644 --- a/rs/client-gen-dotnet/src/service_generators.rs +++ b/rs/client-gen-dotnet/src/service_generators.rs @@ -1,80 +1,47 @@ +use crate::helpers::*; +use crate::type_generators::generate_type_decl_code; use convert_case::{Case, Casing}; +use csharp::Tokens; use genco::prelude::*; -use rust::Tokens; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; -use crate::helpers::*; -use crate::type_generators::generate_type_decl_code; - -/// Generates a trait with service methods -pub(crate) struct ServiceTraitGenerator { +/// Generates a client that implements service trait +pub(crate) struct ServiceClientGenerator { service_name: String, - tokens: Tokens, + interface_tokens: Tokens, + class_tokens: Tokens, } -impl ServiceTraitGenerator { +impl ServiceClientGenerator { pub(crate) fn new(service_name: String) -> Self { Self { service_name, - tokens: Tokens::new(), + interface_tokens: Tokens::new(), + class_tokens: Tokens::new(), } } pub(crate) fn finalize(self) -> Tokens { + let name = &self.service_name; quote! { - $['\n'] - #[allow(clippy::type_complexity)] - pub trait $(&self.service_name) { - type Args; - $(self.tokens) + public interface I$name + { + $(self.interface_tokens) } - } - } -} -impl<'ast> Visitor<'ast> for ServiceTraitGenerator { - fn visit_service(&mut self, service: &'ast Service) { - visitor::accept_service(service, self); - } - - fn visit_service_func(&mut self, func: &'ast ServiceFunc) { - let mutability = if func.is_query() { "" } else { "mut" }; - let fn_name = func.name().to_case(Case::Snake); - - let mut params_tokens = Tokens::new(); - for param in func.params() { - let type_decl_code = generate_type_decl_code(param.type_decl()); - quote_in! {params_tokens => - $(param.name()): $(type_decl_code), - }; - } - - let output_type_decl_code = generate_type_decl_code(func.output()); - let output_trait = if func.is_query() { "Query" } else { "Call" }; + public partial class $name : I$name + { + private readonly IRemoting remoting; - quote_in! { self.tokens=> - $['\r'] fn $fn_name (&$mutability self, $params_tokens) -> impl $output_trait; - }; - } -} - -/// Generates a client that implements service trait -pub(crate) struct ServiceClientGenerator { - service_name: String, - tokens: Tokens, -} + public $name(IRemoting remoting) + { + this.remoting = remoting; + } -impl ServiceClientGenerator { - pub(crate) fn new(service_name: String) -> Self { - Self { - service_name, - tokens: Tokens::new(), + $(self.class_tokens) + } } } - - pub(crate) fn finalize(self) -> Tokens { - self.tokens - } } // using quote_in instead of tokens.append @@ -82,60 +49,12 @@ impl<'ast> Visitor<'ast> for ServiceClientGenerator { fn visit_service(&mut self, service: &'ast Service) { let name = &self.service_name; - quote_in! {self.tokens => - pub struct $name { - remoting: R, - } - - impl $name { - pub fn new(remoting: R) -> Self { - Self { remoting } - } - } - - impl traits::$name for $name - $("{") - type Args = R::Args; - }; - visitor::accept_service(service, self); - - quote_in! {self.tokens => - $("}") - }; } fn visit_service_func(&mut self, func: &'ast ServiceFunc) { let mutability = if func.is_query() { "" } else { "mut" }; let fn_name = func.name(); let fn_name_snake = fn_name.to_case(Case::Snake); - - let mut params_tokens = Tokens::new(); - for param in func.params() { - let type_decl_code = generate_type_decl_code(param.type_decl()); - quote_in! {params_tokens => - $(param.name()): $(type_decl_code), - }; - } - - let output_type_decl_code = generate_type_decl_code(func.output()); - let output_trait = if func.is_query() { "Query" } else { "Call" }; - - let args = encoded_args(func.params()); - - let service_name_snake = self.service_name.to_case(Case::Snake); - let params_type = format!("{service_name_snake}::io::{fn_name}"); - - for doc in func.docs() { - quote_in! { self.tokens => - $['\r'] $("///") $doc - }; - } - - quote_in! {self.tokens => - $['\r'] fn $fn_name_snake (&$mutability self, $params_tokens) -> impl $output_trait { - RemotingAction::<_, $params_type>::new(self.remoting.clone(), $args) - } - }; } } diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index 969357e2..b658270e 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -256,11 +256,56 @@ impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { } } -struct TypeDeclGenerator<'a> { +pub(crate) struct TypeDeclGenerator<'a> { code: String, generated_types: &'a Vec<&'a Type>, } +impl<'a> TypeDeclGenerator<'a> { + pub(crate) fn new(generated_types: &'a Vec<&'a Type>) -> Self { + Self { + code: String::new(), + generated_types, + } + } + + pub(crate) fn generate_type_decl(&mut self, type_decl: &'a TypeDecl) -> String { + visitor::accept_type_decl(type_decl, self); + let code = std::mem::take(&mut self.code); + code + } + + pub(crate) fn generate_types_as_tuple(&mut self, type_decls: Vec<&'a TypeDecl>) -> String { + if type_decls.is_empty() { + } else if type_decls.len() == 1 { + visitor::accept_type_decl(type_decls[0], self); + } else { + self.code + .push_str("global::Substrate.NetApi.Model.Types.Base.BaseTuple<"); + self.join_type_decls(type_decls, ", "); + self.code.push('>'); + } + let code = std::mem::take(&mut self.code); + code + } + + fn join_type_decls>( + &mut self, + type_decls: I, + separator: &str, + ) { + let prev_code = std::mem::take(&mut self.code); + let mut type_decls_str: Vec = Vec::new(); + let iter = type_decls.into_iter(); + for type_decl in iter { + visitor::accept_type_decl(type_decl, self); + type_decls_str.push(std::mem::take(&mut self.code)); + } + _ = std::mem::replace(&mut self.code, prev_code); + self.code.push_str(type_decls_str.join(separator).as_str()); + } +} + impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { fn visit_optional_type_decl(&mut self, optional_type_decl: &'a TypeDecl) { self.code @@ -293,12 +338,7 @@ impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { } else { self.code .push_str("global::Substrate.NetApi.Model.Types.Base.BaseTuple<"); - for field in struct_def.fields() { - visitor::accept_type_decl(field.type_decl(), self); - if struct_def.fields().last() != Some(field) { - self.code.push(','); - } - } + self.join_type_decls(struct_def.fields().iter().map(|f| f.type_decl()), ", "); self.code.push('>'); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap index 9a8aa2e3..725fea7b 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -2,6 +2,47 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(IDL, \"Service\")" --- +public interface IServiceFactory +{ + /// + /// New constructor + /// + IActivation New( + global::Substrate.NetApi.Model.Types.Primitive.U32 a); +} + +public partial class ServiceFactory : IServiceFactory +{ + private readonly IRemoting remoting; + + public ServiceFactory(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public IActivation New( + global::Substrate.NetApi.Model.Types.Primitive.U32 a) + { + return new RemotingAction( + this.remoting, + new byte[] { 12, 78, 101, 119 }, + new global::Substrate.NetApi.Model.Types.Primitive.U32(a)); + } +} + +public interface IService +{} + +public partial class Service : IService +{ + private readonly IRemoting remoting; + + public Service(IRemoting remoting) + { + this.remoting = remoting; + } +} /// /// ThisThatSvcAppTupleStruct docs /// @@ -109,8 +150,8 @@ public sealed partial class EnumThisThatSvcAppManyVariants : global::Substrate.N this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); - this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); - this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); + this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); + this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); this.AddTypeDecoder(ThisThatSvcAppManyVariants.Six); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap index 10327e82..16304c75 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -2,6 +2,44 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: code --- +public interface IServiceFactory +{ + IActivation New( + global::Substrate.NetApi.Model.Types.Primitive.U32 a); +} + +public partial class ServiceFactory : IServiceFactory +{ + private readonly IRemoting remoting; + + public ServiceFactory(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public IActivation New( + global::Substrate.NetApi.Model.Types.Primitive.U32 a) + { + return new RemotingAction( + this.remoting, + new byte[] { 12, 78, 101, 119 }, + new global::Substrate.NetApi.Model.Types.Primitive.U32(a)); + } +} + +public interface IService +{} + +public partial class Service : IService +{ + private readonly IRemoting remoting; + + public Service(IRemoting remoting) + { + this.remoting = remoting; + } +} [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { @@ -85,8 +123,8 @@ public sealed partial class EnumThisThatSvcAppManyVariants : global::Substrate.N this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); - this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); - this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); + this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); + this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); this.AddTypeDecoder(ThisThatSvcAppManyVariants.Six); } } From c998fa65157a84ec5795a506899e543ad991c241 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 25 Oct 2024 19:25:14 +0200 Subject: [PATCH 07/54] wip: dotnet generator --- rs/client-gen-dotnet/src/root_generator.rs | 9 ++- .../src/service_generators.rs | 77 ++++++++++++++---- rs/client-gen-dotnet/src/type_generators.rs | 16 ++-- .../tests/snapshots/generator__full.snap | 80 +++++++++++++++---- .../generator__full_with_sails_path.snap | 80 +++++++++++++++---- 5 files changed, 206 insertions(+), 56 deletions(-) diff --git a/rs/client-gen-dotnet/src/root_generator.rs b/rs/client-gen-dotnet/src/root_generator.rs index 86e90915..b383f9fc 100644 --- a/rs/client-gen-dotnet/src/root_generator.rs +++ b/rs/client-gen-dotnet/src/root_generator.rs @@ -50,11 +50,14 @@ impl<'a> Visitor<'a> for RootGenerator<'a> { fn visit_service(&mut self, service: &'a Service) { let service_name = if service.name().is_empty() { - self.anonymous_service_name.to_case(Case::Pascal) + self.anonymous_service_name } else { - service.name().to_case(Case::Pascal) + service.name() }; - let mut service_gen = ServiceClientGenerator::new(service_name); + let mut service_gen = ServiceClientGenerator::new( + service_name.to_owned(), + TypeDeclGenerator::new(&self.generated_types), + ); service_gen.visit_service(service); self.tokens.extend(service_gen.finalize()); } diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/rs/client-gen-dotnet/src/service_generators.rs index a00ac4f7..557ef10b 100644 --- a/rs/client-gen-dotnet/src/service_generators.rs +++ b/rs/client-gen-dotnet/src/service_generators.rs @@ -1,28 +1,34 @@ -use crate::helpers::*; -use crate::type_generators::generate_type_decl_code; +use crate::{helpers::*, type_generators::TypeDeclGenerator}; use convert_case::{Case, Casing}; -use csharp::Tokens; +use csharp::{block_comment, Tokens}; use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; +const BASE_TUPLE_RUST: &str = "global::Substrate.NetApi.Model.Types.Base.BaseTupleRust"; +const IQUERY: &str = "global::Sails.Remoting.Abstractions.IQuery"; +const ICALL: &str = "global::Sails.Remoting.Abstractions.ICall"; + /// Generates a client that implements service trait -pub(crate) struct ServiceClientGenerator { +pub(crate) struct ServiceClientGenerator<'a> { service_name: String, + type_generator: TypeDeclGenerator<'a>, interface_tokens: Tokens, class_tokens: Tokens, } -impl ServiceClientGenerator { - pub(crate) fn new(service_name: String) -> Self { +impl<'a> ServiceClientGenerator<'a> { + pub(crate) fn new(service_name: String, type_generator: TypeDeclGenerator<'a>) -> Self { Self { service_name, + type_generator, interface_tokens: Tokens::new(), class_tokens: Tokens::new(), } } pub(crate) fn finalize(self) -> Tokens { - let name = &self.service_name; + let name = &self.service_name.to_case(Case::Pascal); + quote! { public interface I$name { @@ -45,16 +51,57 @@ impl ServiceClientGenerator { } // using quote_in instead of tokens.append -impl<'ast> Visitor<'ast> for ServiceClientGenerator { - fn visit_service(&mut self, service: &'ast Service) { - let name = &self.service_name; - +impl<'a> Visitor<'a> for ServiceClientGenerator<'a> { + fn visit_service(&mut self, service: &'a Service) { visitor::accept_service(service, self); } - fn visit_service_func(&mut self, func: &'ast ServiceFunc) { - let mutability = if func.is_query() { "" } else { "mut" }; - let fn_name = func.name(); - let fn_name_snake = fn_name.to_case(Case::Snake); + fn visit_service_func(&mut self, func: &'a ServiceFunc) { + let func_name_pascal = &func.name().to_case(Case::Pascal); + let return_type = if func.is_query() { IQUERY } else { ICALL }; + + let service_route_bytes = path_bytes(self.service_name.as_str()).0; + let func_route_bytes = path_bytes(func.name()).0; + let route_bytes = vec![service_route_bytes, func_route_bytes].join(", "); + + let args = encoded_fn_args(func.params()); + let args_with_type = func + .params() + .iter() + .map(|p| { + format!( + "{} {}", + self.type_generator.generate_type_decl(p.type_decl()), + p.name().to_case(Case::Camel) + ) + }) + .collect::>() + .join(",\r"); + + // let type_decls = func + // .params() + // .iter() + // .map(|p| p.type_decl()) + // .collect::>(); + // let tuple_arg_type = self.type_generator.generate_types_as_tuple(type_decls); + let func_return_type = &self.type_generator.generate_type_decl(func.output()); + + quote_in! { self.interface_tokens => + $return_type<$func_return_type> $func_name_pascal($['\r'] + $(&args_with_type));$['\r'] + }; + + quote_in! { self.class_tokens => + $(block_comment(vec![""])) + public $return_type<$func_return_type> $func_name_pascal($['\r'] + $(&args_with_type)) + { + return new RemotingAction<$func_return_type>( + this.remoting, + new byte[] { $(&route_bytes) }, + new $(BASE_TUPLE_RUST)($(&args)) + ); + } + }; } } diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index b658270e..104e8b48 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -1,4 +1,4 @@ -use crate::helpers::summary_comment; +use crate::helpers::*; use convert_case::{Case, Casing}; use csharp::{block_comment, Tokens}; use genco::prelude::*; @@ -136,7 +136,7 @@ impl<'a> StructDefGenerator<'a> { var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); + global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } } @@ -151,11 +151,11 @@ impl<'a> StructDefGenerator<'a> { public $(&value_type) Value { get; set; }$['\r'] }; quote_in! { self.encode_tokens => - result.AddRange(Value.Encode());$['\r'] + result.AddRange(this.Value.Encode());$['\r'] }; quote_in! { self.decode_tokens => - Value = new $(&value_type)();$['\r'] - Value.Decode(byteArray, ref p);$['\r'] + this.Value = new $(&value_type)();$['\r'] + this.Value.Decode(byteArray, ref p);$['\r'] }; } } @@ -190,11 +190,11 @@ impl<'a> Visitor<'a> for StructDefGenerator<'a> { public $(&type_decl_code) $(&field_name_pascal) { get; set; }$['\r'] }; quote_in! { self.encode_tokens => - result.AddRange($(&field_name_pascal).Encode());$['\r'] + result.AddRange(this.$(&field_name_pascal).Encode());$['\r'] }; quote_in! { self.decode_tokens => - $(&field_name_pascal) = new $(&type_decl_code)();$['\r'] - $(&field_name_pascal).Decode(byteArray, ref p);$['\r'] + this.$(&field_name_pascal) = new $(&type_decl_code)();$['\r'] + this.$(&field_name_pascal).Decode(byteArray, ref p);$['\r'] }; } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap index 725fea7b..9106592e 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -32,7 +32,16 @@ public partial class ServiceFactory : IServiceFactory } public interface IService -{} +{ + global::Sails.Remoting.Abstractions.ICall> DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); + global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( + ThisThatSvcAppDoThatParam param); + global::Sails.Remoting.Abstractions.IQuery This( + global::Substrate.NetApi.Model.Types.Base.BaseVec v1); + global::Sails.Remoting.Abstractions.IQuery> That( + global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); +} public partial class Service : IService { @@ -42,6 +51,47 @@ public partial class Service : IService { this.remoting = remoting; } + + /// + public global::Sails.Remoting.Abstractions.ICall> DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) + { + return new RemotingAction>( + this.remoting, + new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115 }, + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( + ThisThatSvcAppDoThatParam param) + { + return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( + this.remoting, + new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116 }, + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery This( + global::Substrate.NetApi.Model.Types.Base.BaseVec v1) + { + return new RemotingAction( + this.remoting, + new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115 }, + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery> That( + global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) + { + return new RemotingAction>( + this.remoting, + new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116 }, + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) + ); + } } /// /// ThisThatSvcAppTupleStruct docs @@ -58,7 +108,7 @@ public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi public override byte[] Encode() { var result = new List(); - result.AddRange(Value.Encode()); + result.AddRange(this.Value.Encode()); return result.ToArray(); } @@ -66,12 +116,12 @@ public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi public override void Decode(byte[] byteArray, ref int p) { var start = p; - Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); - Value.Decode(byteArray, ref p); + this.Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); + this.Value.Decode(byteArray, ref p); var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); + global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } @@ -101,9 +151,9 @@ public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi public override byte[] Encode() { var result = new List(); - result.AddRange(Query.Encode()); - result.AddRange(Result.Encode()); - result.AddRange(P3.Encode()); + result.AddRange(this.Query.Encode()); + result.AddRange(this.Result.Encode()); + result.AddRange(this.P3.Encode()); return result.ToArray(); } @@ -111,16 +161,16 @@ public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi public override void Decode(byte[] byteArray, ref int p) { var start = p; - Query = new global::Substrate.NetApi.Model.Types.Primitive.U32(); - Query.Decode(byteArray, ref p); - Result = new global::Substrate.NetApi.Model.Types.Primitive.Str(); - Result.Decode(byteArray, ref p); - P3 = new EnumThisThatSvcAppManyVariants(); - P3.Decode(byteArray, ref p); + this.Query = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + this.Query.Decode(byteArray, ref p); + this.Result = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + this.Result.Decode(byteArray, ref p); + this.P3 = new EnumThisThatSvcAppManyVariants(); + this.P3.Decode(byteArray, ref p); var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); + global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap index 16304c75..fc72a988 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -29,7 +29,16 @@ public partial class ServiceFactory : IServiceFactory } public interface IService -{} +{ + global::Sails.Remoting.Abstractions.ICall> DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); + global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( + ThisThatSvcAppDoThatParam param); + global::Sails.Remoting.Abstractions.IQuery This( + global::Substrate.NetApi.Model.Types.Base.BaseVec v1); + global::Sails.Remoting.Abstractions.IQuery> That( + global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); +} public partial class Service : IService { @@ -39,6 +48,47 @@ public partial class Service : IService { this.remoting = remoting; } + + /// + public global::Sails.Remoting.Abstractions.ICall> DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) + { + return new RemotingAction>( + this.remoting, + new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115 }, + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( + ThisThatSvcAppDoThatParam param) + { + return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( + this.remoting, + new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116 }, + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery This( + global::Substrate.NetApi.Model.Types.Base.BaseVec v1) + { + return new RemotingAction( + this.remoting, + new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115 }, + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery> That( + global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) + { + return new RemotingAction>( + this.remoting, + new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116 }, + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) + ); + } } [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType @@ -52,7 +102,7 @@ public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi public override byte[] Encode() { var result = new List(); - result.AddRange(Value.Encode()); + result.AddRange(this.Value.Encode()); return result.ToArray(); } @@ -60,12 +110,12 @@ public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi public override void Decode(byte[] byteArray, ref int p) { var start = p; - Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); - Value.Decode(byteArray, ref p); + this.Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); + this.Value.Decode(byteArray, ref p); var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); + global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } @@ -83,9 +133,9 @@ public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi public override byte[] Encode() { var result = new List(); - result.AddRange(P1.Encode()); - result.AddRange(P2.Encode()); - result.AddRange(P3.Encode()); + result.AddRange(this.P1.Encode()); + result.AddRange(this.P2.Encode()); + result.AddRange(this.P3.Encode()); return result.ToArray(); } @@ -93,16 +143,16 @@ public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi public override void Decode(byte[] byteArray, ref int p) { var start = p; - P1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); - P1.Decode(byteArray, ref p); - P2 = new global::Substrate.NetApi.Model.Types.Primitive.Str(); - P2.Decode(byteArray, ref p); - P3 = new EnumThisThatSvcAppManyVariants(); - P3.Decode(byteArray, ref p); + this.P1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + this.P1.Decode(byteArray, ref p); + this.P2 = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + this.P2.Decode(byteArray, ref p); + this.P3 = new EnumThisThatSvcAppManyVariants(); + this.P3.Decode(byteArray, ref p); var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, Bytes, 0, bytesLength); + global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } From 4889a21d06aedc14404d232f58955e7e560afe2c Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 25 Oct 2024 19:40:23 +0200 Subject: [PATCH 08/54] wip: type generator --- rs/client-gen-dotnet/src/root_generator.rs | 5 ++- rs/client-gen-dotnet/src/type_generators.rs | 39 +++++++++++++-------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/rs/client-gen-dotnet/src/root_generator.rs b/rs/client-gen-dotnet/src/root_generator.rs index b383f9fc..c6ae83f7 100644 --- a/rs/client-gen-dotnet/src/root_generator.rs +++ b/rs/client-gen-dotnet/src/root_generator.rs @@ -30,7 +30,10 @@ impl<'a> RootGenerator<'a> { pub(crate) fn finalize(mut self) -> Tokens { for &type_ in &self.generated_types { - let mut type_gen = TopLevelTypeGenerator::new(&type_.name(), &self.generated_types); + let mut type_gen = TopLevelTypeGenerator::new( + &type_.name(), + TypeDeclGenerator::new(&self.generated_types), + ); type_gen.visit_type(type_); self.tokens.extend(type_gen.finalize()); } diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index 104e8b48..8f393d37 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -48,15 +48,15 @@ pub(crate) fn generate_type_decl_with_path(type_decl: &TypeDecl, path: String) - pub(crate) struct TopLevelTypeGenerator<'a> { type_name: &'a str, - generated_types: &'a Vec<&'a Type>, + type_generator: TypeDeclGenerator<'a>, tokens: Tokens, } impl<'a> TopLevelTypeGenerator<'a> { - pub(crate) fn new(type_name: &'a str, generated_types: &'a Vec<&'a Type>) -> Self { + pub(crate) fn new(type_name: &'a str, type_generator: TypeDeclGenerator<'a>) -> Self { Self { type_name, - generated_types, + type_generator, tokens: Tokens::new(), } } @@ -77,13 +77,14 @@ impl<'a> Visitor<'a> for TopLevelTypeGenerator<'a> { fn visit_struct_def(&mut self, struct_def: &'a StructDef) { let mut struct_def_generator = - StructDefGenerator::new(self.type_name, self.generated_types); + StructDefGenerator::new(self.type_name, self.type_generator.clone()); struct_def_generator.visit_struct_def(struct_def); self.tokens.extend(struct_def_generator.finalize()); } fn visit_enum_def(&mut self, enum_def: &'a EnumDef) { - let mut enum_def_generator = EnumDefGenerator::new(self.type_name, self.generated_types); + let mut enum_def_generator = + EnumDefGenerator::new(self.type_name, self.type_generator.clone()); enum_def_generator.visit_enum_def(enum_def); self.tokens.extend(enum_def_generator.finalize()); } @@ -91,7 +92,7 @@ impl<'a> Visitor<'a> for TopLevelTypeGenerator<'a> { struct StructDefGenerator<'a> { type_name: &'a str, - generated_types: &'a Vec<&'a Type>, + type_generator: TypeDeclGenerator<'a>, is_tuple_struct: bool, props_tokens: Tokens, encode_tokens: Tokens, @@ -99,10 +100,10 @@ struct StructDefGenerator<'a> { } impl<'a> StructDefGenerator<'a> { - fn new(type_name: &'a str, generated_types: &'a Vec<&'a Type>) -> Self { + fn new(type_name: &'a str, type_generator: TypeDeclGenerator<'a>) -> Self { Self { type_name, - generated_types, + type_generator, is_tuple_struct: false, props_tokens: Tokens::new(), encode_tokens: Tokens::new(), @@ -146,7 +147,7 @@ impl<'a> StructDefGenerator<'a> { if struct_def.fields().is_empty() { return; } - let value_type = generate_struct_def_code_with_enums(struct_def, self.generated_types); + let value_type = self.type_generator.generate_struct_def(struct_def); quote_in! { self.props_tokens => public $(&value_type) Value { get; set; }$['\r'] }; @@ -177,8 +178,9 @@ impl<'a> Visitor<'a> for StructDefGenerator<'a> { } fn visit_struct_field(&mut self, struct_field: &'a StructField) { - let type_decl_code = - generate_type_decl_code_with_enums(struct_field.type_decl(), self.generated_types); + let type_decl_code = self + .type_generator + .generate_type_decl(struct_field.type_decl()); self.props_tokens.push(); self.props_tokens @@ -202,16 +204,16 @@ impl<'a> Visitor<'a> for StructDefGenerator<'a> { struct EnumDefGenerator<'a> { type_name: &'a str, - generated_types: &'a Vec<&'a Type>, + type_generator: TypeDeclGenerator<'a>, enum_tokens: Tokens, class_tokens: Tokens, } impl<'a> EnumDefGenerator<'a> { - pub(crate) fn new(type_name: &'a str, generated_types: &'a Vec<&'a Type>) -> Self { + pub(crate) fn new(type_name: &'a str, type_generator: TypeDeclGenerator<'a>) -> Self { Self { type_name, - generated_types, + type_generator, enum_tokens: Tokens::new(), class_tokens: Tokens::new(), } @@ -246,7 +248,7 @@ impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { }; let type_decl_code = if let Some(type_decl) = enum_variant.type_decl().as_ref() { - generate_type_decl_code_with_enums(type_decl, self.generated_types) + self.type_generator.generate_type_decl(type_decl) } else { primitive_type_to_dotnet(PrimitiveType::Null).into() }; @@ -256,6 +258,7 @@ impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { } } +#[derive(Clone)] pub(crate) struct TypeDeclGenerator<'a> { code: String, generated_types: &'a Vec<&'a Type>, @@ -275,6 +278,12 @@ impl<'a> TypeDeclGenerator<'a> { code } + pub(crate) fn generate_struct_def(&mut self, struct_def: &'a StructDef) -> String { + visitor::accept_struct_def(struct_def, self); + let code = std::mem::take(&mut self.code); + code + } + pub(crate) fn generate_types_as_tuple(&mut self, type_decls: Vec<&'a TypeDecl>) -> String { if type_decls.is_empty() { } else if type_decls.len() == 1 { From 50fac7167cdfc30e7f8f96b7e585b4205e7d881b Mon Sep 17 00:00:00 2001 From: vobradovich Date: Mon, 28 Oct 2024 18:05:29 +0100 Subject: [PATCH 09/54] wip: event generator --- rs/client-gen-dotnet/src/ctor_generators.rs | 21 +- rs/client-gen-dotnet/src/events_generator.rs | 168 +++--- rs/client-gen-dotnet/src/helpers.rs | 22 - rs/client-gen-dotnet/src/io_generators.rs | 128 ----- rs/client-gen-dotnet/src/lib.rs | 40 +- rs/client-gen-dotnet/src/mock_generator.rs | 64 --- rs/client-gen-dotnet/src/root_generator.rs | 23 +- .../src/service_generators.rs | 28 +- rs/client-gen-dotnet/src/type_generators.rs | 123 ++-- .../snapshots/generator__basic_works.snap | 176 +++--- .../snapshots/generator__events_works.snap | 219 +++---- .../snapshots/generator__external_types.snap | 125 ++-- .../tests/snapshots/generator__full.snap | 95 +++- .../generator__full_with_sails_path.snap | 29 +- .../generator__multiple_services.snap | 165 ++---- .../snapshots/generator__nonzero_works.snap | 133 ++--- .../snapshots/generator__rmrk_works.snap | 538 ++++++++---------- 17 files changed, 901 insertions(+), 1196 deletions(-) delete mode 100644 rs/client-gen-dotnet/src/io_generators.rs delete mode 100644 rs/client-gen-dotnet/src/mock_generator.rs diff --git a/rs/client-gen-dotnet/src/ctor_generators.rs b/rs/client-gen-dotnet/src/ctor_generators.rs index 3743597f..04c8212c 100644 --- a/rs/client-gen-dotnet/src/ctor_generators.rs +++ b/rs/client-gen-dotnet/src/ctor_generators.rs @@ -23,6 +23,8 @@ impl<'a> CtorFactoryGenerator<'a> { pub(crate) fn finalize(self) -> Tokens { let class_name = format!("{}Factory", self.service_name); + let remoting = &csharp::import("global::Sails.Remoting.Abstractions", "IRemoting"); + quote! { public interface I$(&class_name) { @@ -31,9 +33,9 @@ impl<'a> CtorFactoryGenerator<'a> { $['\n'] public partial class $(&class_name) : I$(&class_name) { - private readonly IRemoting remoting; + private readonly $remoting remoting; - public $(&class_name)(IRemoting remoting) + public $(&class_name)($remoting remoting) { this.remoting = remoting; } @@ -51,13 +53,13 @@ impl<'a> Visitor<'a> for CtorFactoryGenerator<'a> { } fn visit_ctor_func(&mut self, func: &'a CtorFunc) { - let func_name_pascal = func.name().to_case(Case::Pascal); + let func_name_pascal = &func.name().to_case(Case::Pascal); self.interface_tokens.push(); self.interface_tokens.append(summary_comment(func.docs())); self.interface_tokens.push(); - let route_bytes = path_bytes(func.name()).0; + let route_bytes = &path_bytes(func.name()).0; let args = encoded_fn_args(func.params()); let args_with_type = func .params() @@ -79,19 +81,22 @@ impl<'a> Visitor<'a> for CtorFactoryGenerator<'a> { .collect::>(); let tuple_arg_type = self.type_generator.generate_types_as_tuple(type_decls); + let activation = &csharp::import("global::Sails.Remoting.Abstractions", "IActivation"); + let action = &csharp::import("global::Sails.Remoting.Abstractions", "RemotingAction"); + quote_in! { self.interface_tokens => - IActivation $(&func_name_pascal)($['\r'] + $activation $func_name_pascal($['\r'] $(&args_with_type));$['\r'] }; quote_in! { self.class_tokens => $(block_comment(vec![""])) - public IActivation $(&func_name_pascal)($['\r'] + public $activation $func_name_pascal($['\r'] $(&args_with_type)) { - return new RemotingAction<$(&tuple_arg_type)>( + return new $action<$(&tuple_arg_type)>( this.remoting, - new byte[] { $(&route_bytes) }, + [$route_bytes], new $(&tuple_arg_type)($(&args))); } }; diff --git a/rs/client-gen-dotnet/src/events_generator.rs b/rs/client-gen-dotnet/src/events_generator.rs index f94591b4..05831808 100644 --- a/rs/client-gen-dotnet/src/events_generator.rs +++ b/rs/client-gen-dotnet/src/events_generator.rs @@ -1,97 +1,127 @@ -use crate::helpers::{method_bytes, path_bytes}; +use crate::helpers::*; +use crate::type_generators::{primitive_type_to_dotnet, TypeDeclGenerator}; +use convert_case::{Case, Casing}; +use csharp::Tokens; use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; -pub(crate) struct EventsModuleGenerator<'a> { +pub(crate) struct EventsGenerator<'a> { service_name: &'a str, - path: &'a str, - sails_path: &'a str, - tokens: rust::Tokens, + type_generator: TypeDeclGenerator<'a>, + enum_tokens: Tokens, + class_tokens: Tokens, + listener_tokens: Tokens, } -impl<'a> EventsModuleGenerator<'a> { - pub(crate) fn new(service_name: &'a str, path: &'a str, sails_path: &'a str) -> Self { +impl<'a> EventsGenerator<'a> { + pub(crate) fn new(service_name: &'a str, type_generator: TypeDeclGenerator<'a>) -> Self { Self { service_name, - path, - sails_path, - tokens: rust::Tokens::new(), + type_generator, + enum_tokens: Tokens::new(), + class_tokens: Tokens::new(), + listener_tokens: Tokens::new(), } } - pub(crate) fn finalize(self) -> rust::Tokens { - self.tokens - } -} + pub(crate) fn finalize(self) -> Tokens { + let name = &self.service_name.to_case(Case::Pascal); + let enum_name = &format!("{}Events", name); + let class_name = &format!("Enum{}Events", name); + let listener_name = &format!("{}Listener", name); -impl<'a, 'ast> Visitor<'ast> for EventsModuleGenerator<'a> { - fn visit_service(&mut self, service: &'ast Service) { - let events_name = format!("{}Events", self.service_name); - let (service_path_bytes, _) = path_bytes(self.path); - let event_names_bytes = service - .events() - .iter() - .map(|e| method_bytes(e.name()).0) - .collect::>() - .join("], &["); + let system_buffer = &csharp::import("global::System", "Buffer"); + let listener = &csharp::import("global::Sails.Remoting.Abstractions", "IRemotingListener"); - quote_in! { self.tokens => + quote! { + public enum $enum_name + { + $(self.enum_tokens) + } $['\n'] - #[allow(dead_code)] - #[cfg(not(target_arch = "wasm32"))] - pub mod events $("{") - use super::*; - use $(self.sails_path)::events::*; - #[derive(PartialEq, Debug, Encode, Decode)] - #[codec(crate = $(self.sails_path)::scale_codec)] - pub enum $(&events_name) $("{") - }; + public sealed partial class $class_name : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust<$enum_name> + { + public $class_name() + { + $(self.class_tokens) + } + } + $['\n'] + public partial class $listener_name : $listener<$class_name> + { + private static readonly byte[][] EventRoutes = + [ + $(self.listener_tokens) + ]; - visitor::accept_service(service, self); + private readonly $listener remoting; - quote_in! { self.tokens => - $['\r'] $("}") - }; + public $listener_name($listener remoting) + { + this.remoting = remoting; + } - quote_in! { self.tokens => - impl EventIo for $(&events_name) { - const ROUTE: &'static [u8] = &[$service_path_bytes]; - const EVENT_NAMES: &'static [&'static [u8]] = &[&[$event_names_bytes]]; - type Event = Self; - } + public async global::System.Collections.Generic.IAsyncEnumerable<$class_name> ListenAsync( + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + { + await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) + { + byte idx = 0; + foreach (var route in EventRoutes) + { + if (route.Length > bytes.Length) + { + continue; + } + if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) + { + var bytesLength = bytes.Length - route.Length + 1; + var data = new byte[bytesLength]; + data[0] = idx; + $system_buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); - pub fn listener>>(remoting: R) -> impl Listener<$(&events_name)> { - RemotingListener::<_, $(&events_name)>::new(remoting) + var p = 0; + $class_name ev = new(); + ev.Decode(bytes, ref p); + yield return ev; + } + idx++; + } + } + } } + $['\n'] } + } +} - quote_in! { self.tokens => - $['\r'] $("}") - }; +impl<'a> Visitor<'a> for EventsGenerator<'a> { + fn visit_service(&mut self, service: &'a Service) { + visitor::accept_service(service, self); } - fn visit_service_event(&mut self, event: &'ast ServiceEvent) { - if let Some(type_decl) = event.type_decl().as_ref() { - for doc in event.docs() { - quote_in! { self.tokens => - $['\r'] $("///") $doc - }; - } + fn visit_service_event(&mut self, event: &'a ServiceEvent) { + let name = &self.service_name.to_case(Case::Pascal); + let service_route_bytes = path_bytes(self.service_name).0; + let event_route_bytes = path_bytes(event.name()).0; + let route_bytes = [service_route_bytes, event_route_bytes].join(", "); - let type_decl_code = crate::type_generators::generate_type_decl_code(type_decl); - if type_decl_code.starts_with('{') { - quote_in! { self.tokens => - $['\r'] $(event.name()) $(type_decl_code), - }; - } else { - quote_in! { self.tokens => - $['\r'] $(event.name())($(type_decl_code)) , - }; - } + quote_in! { self.listener_tokens => + [$(&route_bytes)],$['\r'] + }; + + quote_in! { self.enum_tokens => + $(summary_comment(event.docs())) + $(event.name()),$['\r'] + }; + + let type_decl_code = if let Some(type_decl) = event.type_decl().as_ref() { + self.type_generator.generate_type_decl(type_decl) } else { - quote_in! { self.tokens => - $['\r'] $(event.name()), - }; + primitive_type_to_dotnet(PrimitiveType::Null).into() + }; + quote_in! { self.class_tokens => + this.AddTypeDecoder<$(type_decl_code)>($(name)Events.$(event.name()));$['\r'] } } } diff --git a/rs/client-gen-dotnet/src/helpers.rs b/rs/client-gen-dotnet/src/helpers.rs index c86afdc4..e7d24390 100644 --- a/rs/client-gen-dotnet/src/helpers.rs +++ b/rs/client-gen-dotnet/src/helpers.rs @@ -22,18 +22,6 @@ pub(crate) fn path_bytes(path: &str) -> (String, usize) { } } -pub(crate) fn method_bytes(fn_name: &str) -> (String, usize) { - let route_bytes = fn_name.encode(); - let route_encoded_length = route_bytes.len(); - let route_bytes = route_bytes - .into_iter() - .map(|x| x.to_string()) - .collect::>() - .join(","); - - (route_bytes, route_encoded_length) -} - pub(crate) fn encoded_fn_args(params: &[FuncParam]) -> String { params .iter() @@ -42,16 +30,6 @@ pub(crate) fn encoded_fn_args(params: &[FuncParam]) -> String { .join(", ") } -pub(crate) fn encoded_args(params: &[FuncParam]) -> String { - if params.len() == 1 { - return params[0].name().to_owned(); - } - - let arg_names = encoded_fn_args(params); - - format!("({arg_names})") -} - pub fn summary_comment(comment: T) -> SummaryComment where T: IntoIterator, diff --git a/rs/client-gen-dotnet/src/io_generators.rs b/rs/client-gen-dotnet/src/io_generators.rs deleted file mode 100644 index 70823ab2..00000000 --- a/rs/client-gen-dotnet/src/io_generators.rs +++ /dev/null @@ -1,128 +0,0 @@ -use crate::helpers::*; -use crate::type_generators::generate_type_decl_with_path; -use genco::prelude::*; -use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; - -pub(crate) struct IoModuleGenerator<'a> { - path: &'a str, - sails_path: &'a str, - tokens: rust::Tokens, -} - -impl<'a> IoModuleGenerator<'a> { - pub(crate) fn new(path: &'a str, sails_path: &'a str) -> Self { - Self { - path, - sails_path, - tokens: rust::Tokens::new(), - } - } - - pub(crate) fn finalize(self) -> rust::Tokens { - quote!( - $['\n'] - pub mod io { - use super::*; - use $(self.sails_path)::calls::ActionIo; - $(self.tokens) - } - ) - } -} - -impl<'a, 'ast> Visitor<'ast> for IoModuleGenerator<'a> { - fn visit_service(&mut self, service: &'ast Service) { - visitor::accept_service(service, self); - } - - fn visit_service_func(&mut self, func: &'ast ServiceFunc) { - let fn_name = func.name(); - let (service_path_bytes, _) = path_bytes(self.path); - let (route_bytes, _) = method_bytes(fn_name); - - let struct_tokens = generate_io_struct( - fn_name, - func.params(), - Some(func.output()), - format!("{service_path_bytes}{route_bytes}").as_str(), - ); - - quote_in! { self.tokens => - $struct_tokens - }; - } -} - -pub(crate) fn generate_io_struct( - fn_name: &str, - fn_params: &[FuncParam], - fn_output: Option<&TypeDecl>, - route_bytes: &str, -) -> rust::Tokens { - let params_len = fn_params.len(); - let mut struct_param_tokens = rust::Tokens::new(); - let mut encode_call_args = rust::Tokens::new(); - let mut encode_call_names = rust::Tokens::new(); - for func_param in fn_params { - let type_decl_code = - generate_type_decl_with_path(func_param.type_decl(), "super".to_owned()); - quote_in! { struct_param_tokens => - $(&type_decl_code), - }; - quote_in! { encode_call_args => - $(func_param.name()): $(&type_decl_code), - }; - quote_in! { encode_call_names => - $(func_param.name()), - }; - } - - let param_tokens = match params_len { - 0 => quote!(()), - 1 => quote!($(generate_type_decl_with_path(fn_params[0].type_decl(), "super".to_owned()))), - _ => quote!(($struct_param_tokens)), - }; - - let func_output = fn_output.map_or("()".to_owned(), |output| { - generate_type_decl_with_path(output, "super".to_owned()) - }); - - let encode_call_tokens = match params_len { - 0 => quote!( - impl $fn_name { - #[allow(dead_code)] - pub fn encode_call() -> Vec { - <$fn_name as ActionIo>::encode_call(&()) - } - } - ), - 1 => quote!( - impl $fn_name { - #[allow(dead_code)] - pub fn encode_call($encode_call_args) -> Vec { - <$fn_name as ActionIo>::encode_call(&$(fn_params[0].name())) - } - } - ), - _ => quote!( - impl $fn_name { - #[allow(dead_code)] - pub fn encode_call($encode_call_args) -> Vec { - <$fn_name as ActionIo>::encode_call(&($encode_call_names)) - } - } - ), - }; - - quote! { - pub struct $fn_name (()); - - $encode_call_tokens - - impl ActionIo for $fn_name { - const ROUTE: &'static [u8] = &[$route_bytes]; - type Params = $param_tokens; - type Reply = $func_output; - } - } -} diff --git a/rs/client-gen-dotnet/src/lib.rs b/rs/client-gen-dotnet/src/lib.rs index 11c88339..3c6c79b5 100644 --- a/rs/client-gen-dotnet/src/lib.rs +++ b/rs/client-gen-dotnet/src/lib.rs @@ -2,19 +2,15 @@ use anyhow::{Context, Result}; use convert_case::{Case, Casing}; use root_generator::RootGenerator; use sails_idl_parser::ast::visitor; -use std::{collections::HashMap, ffi::OsStr, fs, io::Write, path::Path}; +use std::{collections::HashMap, ffi::OsStr, fs, path::Path}; mod ctor_generators; mod events_generator; mod helpers; -mod io_generators; -mod mock_generator; mod root_generator; mod service_generators; mod type_generators; -const BASE_NAMESPACE: &str = "sails_rs"; - pub struct IdlPath<'a>(&'a Path); pub struct IdlString<'a>(&'a str); pub struct ClientGenerator<'a, S> { @@ -48,7 +44,7 @@ impl<'a, S> ClientGenerator<'a, S> { /// /// Following code generates `use my_crate::MyParam as MyFuncParam;` /// ``` - /// let code = sails_client_gen::ClientGenerator::from_idl("") + /// let code = sails_client_gen_dotnet::ClientGenerator::from_idl("") /// .with_external_type("MyFuncParam", "my_crate::MyParam"); /// ``` pub fn with_external_type(self, name: &'a str, path: &'a str) -> Self { @@ -144,35 +140,3 @@ impl<'a> ClientGenerator<'a, IdlString<'a>> { Ok(()) } } - -// not using prettyplease since it's bad at reporting syntax errors and also removes comments -// TODO(holykol): Fallback if rustfmt is not in PATH would be nice -fn pretty_with_rustfmt(code: &str) -> String { - use std::process::Command; - let mut child = Command::new("rustfmt") - .arg("--config") - .arg("format_strings=false") - .stdin(std::process::Stdio::piped()) - .stdout(std::process::Stdio::piped()) - .spawn() - .expect("Failed to spawn rustfmt"); - - let child_stdin = child.stdin.as_mut().expect("Failed to open stdin"); - child_stdin - .write_all(code.as_bytes()) - .expect("Failed to write to rustfmt"); - - let output = child - .wait_with_output() - .expect("Failed to wait for rustfmt"); - - if !output.status.success() { - panic!( - "rustfmt failed with status: {}\n{}", - output.status, - String::from_utf8(output.stderr).expect("Failed to read rustfmt stderr") - ); - } - - String::from_utf8(output.stdout).expect("Failed to read rustfmt output") -} diff --git a/rs/client-gen-dotnet/src/mock_generator.rs b/rs/client-gen-dotnet/src/mock_generator.rs deleted file mode 100644 index bacdcdad..00000000 --- a/rs/client-gen-dotnet/src/mock_generator.rs +++ /dev/null @@ -1,64 +0,0 @@ -use crate::type_generators::generate_type_decl_code; -use convert_case::{Case, Casing}; -use genco::prelude::*; -use rust::Tokens; -use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; - -pub(crate) struct MockGenerator<'a> { - service_name: &'a str, - tokens: rust::Tokens, -} - -impl<'a> MockGenerator<'a> { - pub(crate) fn new(service_name: &'a str) -> Self { - Self { - service_name, - tokens: rust::Tokens::new(), - } - } - - pub(crate) fn finalize(self) -> rust::Tokens { - quote! { - mock! { - pub $(self.service_name) {} - - #[allow(refining_impl_trait)] - #[allow(clippy::type_complexity)] - impl traits::$(self.service_name) for $(self.service_name) { - type Args = A; - $(self.tokens) - } - } - } - } -} - -impl<'a, 'ast> Visitor<'ast> for MockGenerator<'a> { - fn visit_service(&mut self, service: &'ast Service) { - visitor::accept_service(service, self); - } - - fn visit_service_func(&mut self, func: &'ast ServiceFunc) { - let mutability = if func.is_query() { "" } else { "mut" }; - let fn_name = func.name().to_case(Case::Snake); - - let mut params_tokens = Tokens::new(); - for param in func.params() { - let type_decl_code = generate_type_decl_code(param.type_decl()); - quote_in! {params_tokens => - $(param.name()): $(type_decl_code), - }; - } - - let output_type_decl_code = generate_type_decl_code(func.output()); - let output_mock = if func.is_query() { - "MockQuery" - } else { - "MockCall" - }; - - quote_in! { self.tokens=> - fn $fn_name (&$mutability self, $params_tokens) -> $output_mock; - }; - } -} diff --git a/rs/client-gen-dotnet/src/root_generator.rs b/rs/client-gen-dotnet/src/root_generator.rs index c6ae83f7..5c2e1bfc 100644 --- a/rs/client-gen-dotnet/src/root_generator.rs +++ b/rs/client-gen-dotnet/src/root_generator.rs @@ -1,10 +1,7 @@ -use crate::{ - ctor_generators::*, events_generator::*, io_generators::*, mock_generator::MockGenerator, - service_generators::*, type_generators::*, -}; +use crate::{ctor_generators::*, events_generator::*, service_generators::*, type_generators::*}; use convert_case::{Case, Casing}; use csharp::Tokens; -use genco::prelude::*; +use genco::{prelude::*, tokens::ItemStr}; use sails_idl_parser::{ast::visitor::Visitor, ast::*}; use std::collections::HashMap; @@ -20,8 +17,13 @@ impl<'a> RootGenerator<'a> { anonymous_service_name: &'a str, external_types: HashMap<&'a str, &'a str>, ) -> Self { + let mut tokens = Tokens::new(); + tokens.append(ItemStr::Static( + "#pragma warning disable RCS0056 // A line is too long", + )); + tokens.line(); Self { - tokens: Tokens::new(), + tokens, anonymous_service_name, external_types, generated_types: Vec::new(), @@ -31,7 +33,7 @@ impl<'a> RootGenerator<'a> { pub(crate) fn finalize(mut self) -> Tokens { for &type_ in &self.generated_types { let mut type_gen = TopLevelTypeGenerator::new( - &type_.name(), + type_.name(), TypeDeclGenerator::new(&self.generated_types), ); type_gen.visit_type(type_); @@ -63,6 +65,13 @@ impl<'a> Visitor<'a> for RootGenerator<'a> { ); service_gen.visit_service(service); self.tokens.extend(service_gen.finalize()); + + if !service.events().is_empty() { + let mut events_mod_gen = + EventsGenerator::new(service_name, TypeDeclGenerator::new(&self.generated_types)); + events_mod_gen.visit_service(service); + self.tokens.extend(events_mod_gen.finalize()); + } } fn visit_type(&mut self, t: &'a Type) { diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/rs/client-gen-dotnet/src/service_generators.rs index 557ef10b..111aa9cb 100644 --- a/rs/client-gen-dotnet/src/service_generators.rs +++ b/rs/client-gen-dotnet/src/service_generators.rs @@ -28,24 +28,26 @@ impl<'a> ServiceClientGenerator<'a> { pub(crate) fn finalize(self) -> Tokens { let name = &self.service_name.to_case(Case::Pascal); + let remoting = &csharp::import("global::Sails.Remoting.Abstractions", "IRemoting"); quote! { - public interface I$name + public interface I$name$['\r'] { - $(self.interface_tokens) + $(self.interface_tokens)$['\r'] } - - public partial class $name : I$name + $['\n'] + public partial class $name : I$name$['\r'] { - private readonly IRemoting remoting; + private readonly $remoting remoting; - public $name(IRemoting remoting) + public $name($remoting remoting) { this.remoting = remoting; } $(self.class_tokens) } + $['\n'] } } } @@ -62,7 +64,7 @@ impl<'a> Visitor<'a> for ServiceClientGenerator<'a> { let service_route_bytes = path_bytes(self.service_name.as_str()).0; let func_route_bytes = path_bytes(func.name()).0; - let route_bytes = vec![service_route_bytes, func_route_bytes].join(", "); + let route_bytes = [service_route_bytes, func_route_bytes].join(", "); let args = encoded_fn_args(func.params()); let args_with_type = func @@ -78,14 +80,10 @@ impl<'a> Visitor<'a> for ServiceClientGenerator<'a> { .collect::>() .join(",\r"); - // let type_decls = func - // .params() - // .iter() - // .map(|p| p.type_decl()) - // .collect::>(); - // let tuple_arg_type = self.type_generator.generate_types_as_tuple(type_decls); let func_return_type = &self.type_generator.generate_type_decl(func.output()); + let action = &csharp::import("global::Sails.Remoting.Abstractions", "RemotingAction"); + quote_in! { self.interface_tokens => $return_type<$func_return_type> $func_name_pascal($['\r'] $(&args_with_type));$['\r'] @@ -96,9 +94,9 @@ impl<'a> Visitor<'a> for ServiceClientGenerator<'a> { public $return_type<$func_return_type> $func_name_pascal($['\r'] $(&args_with_type)) { - return new RemotingAction<$func_return_type>( + return new $action<$func_return_type>( this.remoting, - new byte[] { $(&route_bytes) }, + [$(&route_bytes)], new $(BASE_TUPLE_RUST)($(&args)) ); } diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index 8f393d37..669c015c 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -4,46 +4,25 @@ use csharp::{block_comment, Tokens}; use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; -pub(crate) fn generate_type_decl_code<'a>(type_decl: &TypeDecl) -> String { - let mut type_decl_generator = TypeDeclGenerator { - code: String::new(), - generated_types: &Vec::new(), +macro_rules! base { + ($t: expr) => { + concat!("global::Substrate.NetApi.Model.Types.Base.", $t) }; - visitor::accept_type_decl(type_decl, &mut type_decl_generator); - type_decl_generator.code } -pub(crate) fn generate_type_decl_code_with_enums<'a>( - type_decl: &TypeDecl, - generated_types: &'a Vec<&'a Type>, -) -> String { - let mut type_decl_generator = TypeDeclGenerator { - code: String::new(), - generated_types, - }; - visitor::accept_type_decl(type_decl, &mut type_decl_generator); - type_decl_generator.code -} - -pub(crate) fn generate_struct_def_code_with_enums<'a>( - struct_def: &StructDef, - generated_types: &'a Vec<&'a Type>, -) -> String { - let mut type_decl_generator = TypeDeclGenerator { - code: String::new(), - generated_types, +macro_rules! primitive { + ($t: expr) => { + concat!("global::Substrate.NetApi.Model.Types.Primitive.", $t) }; - visitor::accept_struct_def(struct_def, &mut type_decl_generator); - type_decl_generator.code } -pub(crate) fn generate_type_decl_with_path(type_decl: &TypeDecl, path: String) -> String { - let mut type_decl_generator = TypeDeclGenerator { - code: String::new(), - generated_types: &Vec::new(), +macro_rules! gprimitives { + ($t: expr) => { + concat!( + "global::Substrate.Gear.Api.Generated.Model.gprimitives.", + $t + ) }; - visitor::accept_type_decl(type_decl, &mut type_decl_generator); - type_decl_generator.code } pub(crate) struct TopLevelTypeGenerator<'a> { @@ -112,6 +91,9 @@ impl<'a> StructDefGenerator<'a> { } pub(crate) fn finalize(self) -> Tokens { + let system_array = &csharp::import("global::System", "Array"); + let generic_list = csharp::import("global::System.Collections.Generic", "List"); + quote! { [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class $(self.type_name) : global::Substrate.NetApi.Model.Types.Base.BaseType @@ -124,7 +106,7 @@ impl<'a> StructDefGenerator<'a> { $(block_comment(vec![""])) public override byte[] Encode() { - var result = new List(); + var result = new $generic_list(); $(self.encode_tokens) return result.ToArray(); } @@ -137,7 +119,7 @@ impl<'a> StructDefGenerator<'a> { var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + $system_array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } } @@ -149,7 +131,7 @@ impl<'a> StructDefGenerator<'a> { } let value_type = self.type_generator.generate_struct_def(struct_def); quote_in! { self.props_tokens => - public $(&value_type) Value { get; set; }$['\r'] + public required $(&value_type) Value { get; set; }$['\r'] }; quote_in! { self.encode_tokens => result.AddRange(this.Value.Encode());$['\r'] @@ -189,7 +171,7 @@ impl<'a> Visitor<'a> for StructDefGenerator<'a> { if let Some(field_name) = struct_field.name() { let field_name_pascal = field_name.to_case(Case::Pascal); quote_in! { self.props_tokens => - public $(&type_decl_code) $(&field_name_pascal) { get; set; }$['\r'] + public required $(&type_decl_code) $(&field_name_pascal) { get; set; }$['\r'] }; quote_in! { self.encode_tokens => result.AddRange(this.$(&field_name_pascal).Encode());$['\r'] @@ -242,8 +224,6 @@ impl<'ast> Visitor<'ast> for EnumDefGenerator<'ast> { fn visit_enum_variant(&mut self, enum_variant: &'ast EnumVariant) { quote_in! { self.enum_tokens => $(summary_comment(enum_variant.docs())) - }; - quote_in! { self.enum_tokens => $(enum_variant.name()),$['\r'] }; @@ -274,14 +254,12 @@ impl<'a> TypeDeclGenerator<'a> { pub(crate) fn generate_type_decl(&mut self, type_decl: &'a TypeDecl) -> String { visitor::accept_type_decl(type_decl, self); - let code = std::mem::take(&mut self.code); - code + std::mem::take(&mut self.code) } pub(crate) fn generate_struct_def(&mut self, struct_def: &'a StructDef) -> String { visitor::accept_struct_def(struct_def, self); - let code = std::mem::take(&mut self.code); - code + std::mem::take(&mut self.code) } pub(crate) fn generate_types_as_tuple(&mut self, type_decls: Vec<&'a TypeDecl>) -> String { @@ -289,13 +267,11 @@ impl<'a> TypeDeclGenerator<'a> { } else if type_decls.len() == 1 { visitor::accept_type_decl(type_decls[0], self); } else { - self.code - .push_str("global::Substrate.NetApi.Model.Types.Base.BaseTuple<"); + self.code.push_str(base!("BaseTuple<")); self.join_type_decls(type_decls, ", "); self.code.push('>'); } - let code = std::mem::take(&mut self.code); - code + std::mem::take(&mut self.code) } fn join_type_decls>( @@ -317,8 +293,7 @@ impl<'a> TypeDeclGenerator<'a> { impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { fn visit_optional_type_decl(&mut self, optional_type_decl: &'a TypeDecl) { - self.code - .push_str("global::Substrate.NetApi.Model.Types.Base.BaseOpt<"); + self.code.push_str(base!("BaseOpt<")); visitor::accept_type_decl(optional_type_decl, self); self.code.push('>'); } @@ -332,8 +307,7 @@ impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { } fn visit_vector_type_decl(&mut self, vector_type_decl: &'a TypeDecl) { - self.code - .push_str("global::Substrate.NetApi.Model.Types.Base.BaseVec<"); + self.code.push_str(base!("BaseVec<")); visitor::accept_type_decl(vector_type_decl, self); self.code.push('>'); } @@ -345,8 +319,7 @@ impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { if struct_def.fields().len() == 1 { visitor::accept_type_decl(struct_def.fields()[0].type_decl(), self); } else { - self.code - .push_str("global::Substrate.NetApi.Model.Types.Base.BaseTuple<"); + self.code.push_str(base!("BaseTuple<")); self.join_type_decls(struct_def.fields().iter().map(|f| f.type_decl()), ", "); self.code.push('>'); } @@ -365,7 +338,7 @@ impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { .map(|&t| matches!(t.def(), TypeDef::Enum(_))) .unwrap_or_default(); let type_id = if is_enum { - &format!("Enum{}", user_defined_type_id) + &format!("Enum{}", user_defined_type_id) // Enum prefix } else { user_defined_type_id }; @@ -387,33 +360,31 @@ impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { } } -fn primitive_type_to_dotnet(primitive_type: PrimitiveType) -> &'static str { +pub(crate) fn primitive_type_to_dotnet(primitive_type: PrimitiveType) -> &'static str { match primitive_type { - PrimitiveType::U8 => "global::Substrate.NetApi.Model.Types.Primitive.U8", - PrimitiveType::U16 => "global::Substrate.NetApi.Model.Types.Primitive.U16", - PrimitiveType::U32 => "global::Substrate.NetApi.Model.Types.Primitive.U32", - PrimitiveType::U64 => "global::Substrate.NetApi.Model.Types.Primitive.U64", - PrimitiveType::U128 => "global::Substrate.NetApi.Model.Types.Primitive.U128", - PrimitiveType::I8 => "global::Substrate.NetApi.Model.Types.Primitive.I8", - PrimitiveType::I16 => "global::Substrate.NetApi.Model.Types.Primitive.I16", - PrimitiveType::I32 => "global::Substrate.NetApi.Model.Types.Primitive.I32", - PrimitiveType::I64 => "global::Substrate.NetApi.Model.Types.Primitive.I64", - PrimitiveType::I128 => "global::Substrate.NetApi.Model.Types.Primitive.I128", - PrimitiveType::Bool => "global::Substrate.NetApi.Model.Types.Primitive.Bool", - PrimitiveType::Str => "global::Substrate.NetApi.Model.Types.Primitive.Str", - PrimitiveType::Char => "global::Substrate.NetApi.Model.Types.Primitive.PrimChar", - PrimitiveType::Null => "global::Substrate.NetApi.Model.Types.Base.BaseVoid", - PrimitiveType::ActorId => "global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId", - PrimitiveType::CodeId => "global::Substrate.Gear.Api.Generated.Model.gprimitives.CodeId", - PrimitiveType::MessageId => { - "global::Substrate.Gear.Api.Generated.Model.gprimitives.MessageId" - } + PrimitiveType::U8 => primitive!("U8"), + PrimitiveType::U16 => primitive!("U16"), + PrimitiveType::U32 => primitive!("U32"), + PrimitiveType::U64 => primitive!("U64"), + PrimitiveType::U128 => primitive!("U128"), + PrimitiveType::I8 => primitive!("I8"), + PrimitiveType::I16 => primitive!("I16"), + PrimitiveType::I32 => primitive!("I32"), + PrimitiveType::I64 => primitive!("I64"), + PrimitiveType::I128 => primitive!("I128"), + PrimitiveType::Bool => primitive!("Bool"), + PrimitiveType::Str => primitive!("Str"), + PrimitiveType::Char => primitive!("PrimChar"), + PrimitiveType::Null => base!("BaseVoid"), + PrimitiveType::ActorId => gprimitives!("ActorId"), + PrimitiveType::CodeId => gprimitives!("CodeId"), + PrimitiveType::MessageId => gprimitives!("MessageId"), PrimitiveType::H160 => "H160", - PrimitiveType::H256 => "H256", + PrimitiveType::H256 => "global::Substrate.Gear.Api.Generated.Model.primitive_types.H256", PrimitiveType::U256 => "U256", PrimitiveType::NonZeroU8 => "NonZeroU8", PrimitiveType::NonZeroU16 => "NonZeroU16", - PrimitiveType::NonZeroU32 => "NonZeroU32", + PrimitiveType::NonZeroU32 => "global::Substrate.Gear.Api.Generated.Types.Base.NonZeroU32", PrimitiveType::NonZeroU64 => "NonZeroU64", PrimitiveType::NonZeroU128 => "NonZeroU128", PrimitiveType::NonZeroU256 => "NonZeroU256", diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap index 3b9a729d..f5c0dbcf 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap @@ -1,104 +1,106 @@ --- -source: rs/client-gen/tests/generator.rs +source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"Basic\")" --- -// Code generated by sails-client-gen. DO NOT EDIT. -#[allow(unused_imports)] -use sails_rs::collections::BTreeMap; -#[allow(unused_imports)] -use sails_rs::{ - calls::{Activation, Call, Query, Remoting, RemotingAction}, - prelude::*, - String, -}; -pub struct Basic { - remoting: R, +using global::Sails.Remoting.Abstractions; +using global::System; +using global::System.Collections.Generic; + +#pragma warning disable RCS0056 // A line is too long + +public interface IBasic +{ + global::Sails.Remoting.Abstractions.ICall DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); + global::Sails.Remoting.Abstractions.ICall DoThat( + global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } -impl Basic { - pub fn new(remoting: R) -> Self { - Self { remoting } + +public partial class Basic : IBasic +{ + private readonly IRemoting remoting; + + public Basic(IRemoting remoting) + { + this.remoting = remoting; } -} -impl traits::Basic for Basic { - type Args = R::Args; - fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call { - RemotingAction::<_, basic::io::DoThis>::new(self.remoting.clone(), (p1, p2)) + + /// + public global::Sails.Remoting.Abstractions.ICall DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) + { + return new RemotingAction( + this.remoting, + [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 105, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) + ); } - fn do_that(&mut self, p1: (u8, u32)) -> impl Call { - RemotingAction::<_, basic::io::DoThat>::new(self.remoting.clone(), p1) + /// + public global::Sails.Remoting.Abstractions.ICall DoThat( + global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) + { + return new RemotingAction( + this.remoting, + [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 97, 116], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) + ); } } -pub mod basic { - use super::*; +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public required global::Substrate.NetApi.Model.Types.Primitive.U32 F1 { get; set; } + public required global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } + public required global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } - pub mod io { - use super::*; - use sails_rs::calls::ActionIo; - pub struct DoThis(()); - impl DoThis { - #[allow(dead_code)] - pub fn encode_call(p1: u32, p2: super::MyParam) -> Vec { - ::encode_call(&(p1, p2)) - } - } - impl ActionIo for DoThis { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; - type Params = (u32, super::MyParam); - type Reply = u16; - } - pub struct DoThat(()); - impl DoThat { - #[allow(dead_code)] - pub fn encode_call(p1: (u8, u32)) -> Vec { - ::encode_call(&p1) - } - } - impl ActionIo for DoThat { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; - type Params = (u8, u32); - type Reply = u8; - } - } -} -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub struct MyParam { - pub f1: u32, - pub f2: Vec, - pub f3: Option<(u8, u32)>, -} -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub enum MyParam2 { - Variant1, - Variant2(u32), - Variant3((u32,)), - Variant4((u8, u32)), - Variant5 { f1: String, f2: Vec }, -} + /// + public override string TypeName() => "MyParam"; -pub mod traits { - use super::*; + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(this.F1.Encode()); + result.AddRange(this.F2.Encode()); + result.AddRange(this.F3.Encode()); + return result.ToArray(); + } - #[allow(clippy::type_complexity)] - pub trait Basic { - type Args; - fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call; - fn do_that(&mut self, p1: (u8, u32)) -> impl Call; + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + this.F1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + this.F1.Decode(byteArray, ref p); + this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.F2.Decode(byteArray, ref p); + this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); + this.F3.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -extern crate std; +public enum MyParam2 +{ + Variant1, + Variant2, + Variant3, + Variant4, + Variant5, +} -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -pub mod mockall { - use super::*; - use sails_rs::mockall::*; - mock! { pub Basic {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::Basic for Basic { type Args = A; fn do_this (&mut self, p1: u32,p2: MyParam,) -> MockCall;fn do_that (&mut self, p1: (u8,u32,),) -> MockCall; } } +public sealed partial class EnumMyParam2 : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumMyParam2() + { + this.AddTypeDecoder(MyParam2.Variant1); + this.AddTypeDecoder(MyParam2.Variant2); + this.AddTypeDecoder(MyParam2.Variant3); + this.AddTypeDecoder>(MyParam2.Variant4); + this.AddTypeDecoder>>(MyParam2.Variant5); + } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap index 66295658..706f3e0a 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap @@ -1,116 +1,139 @@ --- -source: rs/client-gen/tests/generator.rs +source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"ServiceWithEvents\")" --- -// Code generated by sails-client-gen. DO NOT EDIT. -#[allow(unused_imports)] -use sails_rs::collections::BTreeMap; -#[allow(unused_imports)] -use sails_rs::{ - calls::{Activation, Call, Query, Remoting, RemotingAction}, - prelude::*, - String, -}; -pub struct ServiceWithEvents { - remoting: R, +using global::Sails.Remoting.Abstractions; +using global::System; +using global::System.Collections.Generic; + +#pragma warning disable RCS0056 // A line is too long + +public interface IServiceWithEvents +{ + global::Sails.Remoting.Abstractions.ICall DoThis( + NonZeroU256 p1, MyParam p2); } -impl ServiceWithEvents { - pub fn new(remoting: R) -> Self { - Self { remoting } + +public partial class ServiceWithEvents : IServiceWithEvents +{ + private readonly IRemoting remoting; + + public ServiceWithEvents(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public global::Sails.Remoting.Abstractions.ICall DoThis( + NonZeroU256 p1, MyParam p2) + { + return new RemotingAction( + this.remoting, + [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 24, 68, 111, 84, 104, 105, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) + ); } } -impl traits::ServiceWithEvents for ServiceWithEvents { - type Args = R::Args; - fn do_this( - &mut self, - p1: NonZeroU256, - p2: MyParam, - ) -> impl Call { - RemotingAction::<_, service_with_events::io::DoThis>::new(self.remoting.clone(), (p1, p2)) + +public enum ServiceWithEventsEvents +{ + One, + Two, + Three, + Reset, +} + +public sealed partial class EnumServiceWithEventsEvents : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumServiceWithEventsEvents() + { + this.AddTypeDecoder(ServiceWithEventsEvents.One); + this.AddTypeDecoder>(ServiceWithEventsEvents.Two); + this.AddTypeDecoder(ServiceWithEventsEvents.Three); + this.AddTypeDecoder(ServiceWithEventsEvents.Reset); } } -pub mod service_with_events { - use super::*; - - pub mod io { - use super::*; - use sails_rs::calls::ActionIo; - pub struct DoThis(()); - impl DoThis { - #[allow(dead_code)] - pub fn encode_call(p1: NonZeroU256, p2: super::MyParam) -> Vec { - ::encode_call(&(p1, p2)) - } - } - impl ActionIo for DoThis { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; - type Params = (NonZeroU256, super::MyParam); - type Reply = NonZeroU64; - } +public partial class ServiceWithEventsListener : IRemotingListener +{ + private static readonly byte[][] EventRoutes = + [ + [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 79, 110, 101], + [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 84, 119, 111], + [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 84, 104, 114, 101, 101], + [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 82, 101, 115, 101, 116], + ]; + + private readonly IRemotingListener remoting; + + public ServiceWithEventsListener(IRemotingListener remoting) + { + this.remoting = remoting; } - #[allow(dead_code)] - #[cfg(not(target_arch = "wasm32"))] - pub mod events { - use super::*; - use sails_rs::events::*; - #[derive(PartialEq, Debug, Encode, Decode)] - #[codec(crate = sails_rs::scale_codec)] - pub enum ServiceWithEventsEvents { - One(u64), - Two { id: u8, reference: u64 }, - Three(MyParam), - Reset, - } - impl EventIo for ServiceWithEventsEvents { - const ROUTE: &'static [u8] = &[]; - const EVENT_NAMES: &'static [&'static [u8]] = &[ - &[12, 79, 110, 101], - &[12, 84, 119, 111], - &[20, 84, 104, 114, 101, 101], - &[20, 82, 101, 115, 101, 116], - ]; - type Event = Self; - } - pub fn listener>>( - remoting: R, - ) -> impl Listener { - RemotingListener::<_, ServiceWithEventsEvents>::new(remoting) + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync( + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + { + await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) + { + byte idx = 0; + foreach (var route in EventRoutes) + { + if (route.Length > bytes.Length) + { + continue; + } + if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) + { + var bytesLength = bytes.Length - route.Length + 1; + var data = new byte[bytesLength]; + data[0] = idx; + Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); + + var p = 0; + EnumServiceWithEventsEvents ev = new(); + ev.Decode(bytes, ref p); + yield return ev; + } + idx++; + } } } } -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub struct MyParam { - pub f1: NonZeroU256, - pub f2: Vec, - pub f3: Option<(NonZeroU64, NonZeroU256)>, -} -pub mod traits { - use super::*; - - #[allow(clippy::type_complexity)] - pub trait ServiceWithEvents { - type Args; - fn do_this( - &mut self, - p1: NonZeroU256, - p2: MyParam, - ) -> impl Call; - } -} +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public required NonZeroU256 F1 { get; set; } + public required global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } + public required global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -extern crate std; + /// + public override string TypeName() => "MyParam"; -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -pub mod mockall { - use super::*; - use sails_rs::mockall::*; - mock! { pub ServiceWithEvents {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::ServiceWithEvents for ServiceWithEvents { type Args = A; fn do_this (&mut self, p1: NonZeroU256,p2: MyParam,) -> MockCall; } } + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(this.F1.Encode()); + result.AddRange(this.F2.Encode()); + result.AddRange(this.F3.Encode()); + return result.ToArray(); + } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + this.F1 = new NonZeroU256(); + this.F1.Decode(byteArray, ref p); + this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.F2.Decode(byteArray, ref p); + this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); + this.F3.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap index 8828daa1..0d8e3da2 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap @@ -1,86 +1,67 @@ --- -source: rs/client-gen/tests/generator.rs +source: rs/client-gen-dotnet/tests/generator.rs expression: code --- -// Code generated by sails-client-gen. DO NOT EDIT. -#[allow(unused_imports)] -use my_crate::sails::collections::BTreeMap; -#[allow(unused_imports)] -use my_crate::sails::{ - calls::{Activation, Call, Query, Remoting, RemotingAction}, - prelude::*, - String, -}; -#[allow(unused_imports)] -use my_crate::MyParam; -pub struct Service { - remoting: R, +using global::Sails.Remoting.Abstractions; + +#pragma warning disable RCS0056 // A line is too long + +public interface IService +{ + global::Sails.Remoting.Abstractions.ICall DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); + global::Sails.Remoting.Abstractions.ICall DoThat( + global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } -impl Service { - pub fn new(remoting: R) -> Self { - Self { remoting } + +public partial class Service : IService +{ + private readonly IRemoting remoting; + + public Service(IRemoting remoting) + { + this.remoting = remoting; } -} -impl traits::Service for Service { - type Args = R::Args; - fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call { - RemotingAction::<_, service::io::DoThis>::new(self.remoting.clone(), (p1, p2)) + + /// + public global::Sails.Remoting.Abstractions.ICall DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) + { + return new RemotingAction( + this.remoting, + [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) + ); } - fn do_that(&mut self, p1: (u8, u32)) -> impl Call { - RemotingAction::<_, service::io::DoThat>::new(self.remoting.clone(), p1) + /// + public global::Sails.Remoting.Abstractions.ICall DoThat( + global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) + { + return new RemotingAction( + this.remoting, + [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) + ); } } -pub mod service { - use super::*; - - pub mod io { - use super::*; - use my_crate::sails::calls::ActionIo; - pub struct DoThis(()); - impl DoThis { - #[allow(dead_code)] - pub fn encode_call(p1: u32, p2: super::MyParam) -> Vec { - ::encode_call(&(p1, p2)) - } - } - impl ActionIo for DoThis { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; - type Params = (u32, super::MyParam); - type Reply = u16; - } - pub struct DoThat(()); - impl DoThat { - #[allow(dead_code)] - pub fn encode_call(p1: (u8, u32)) -> Vec { - ::encode_call(&p1) - } - } - impl ActionIo for DoThat { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; - type Params = (u8, u32); - type Reply = u8; - } - } -} -#[derive(Encode, Decode, TypeInfo)] -#[codec(crate = my_crate::sails::scale_codec)] -#[scale_info(crate = my_crate::sails::scale_info)] -pub enum MyParam2 { +public enum MyParam2 +{ Variant1, - Variant2(u32), - Variant3((u32,)), - Variant4((u8, u32)), - Variant5 { f1: String, f2: Vec }, + Variant2, + Variant3, + Variant4, + Variant5, } -pub mod traits { - use super::*; - - #[allow(clippy::type_complexity)] - pub trait Service { - type Args; - fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call; - fn do_that(&mut self, p1: (u8, u32)) -> impl Call; +public sealed partial class EnumMyParam2 : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumMyParam2() + { + this.AddTypeDecoder(MyParam2.Variant1); + this.AddTypeDecoder(MyParam2.Variant2); + this.AddTypeDecoder(MyParam2.Variant3); + this.AddTypeDecoder>(MyParam2.Variant4); + this.AddTypeDecoder>>(MyParam2.Variant5); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap index 9106592e..81d77ab1 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -2,6 +2,12 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(IDL, \"Service\")" --- +using global::Sails.Remoting.Abstractions; +using global::System; +using global::System.Collections.Generic; + +#pragma warning disable RCS0056 // A line is too long + public interface IServiceFactory { /// @@ -26,7 +32,7 @@ public partial class ServiceFactory : IServiceFactory { return new RemotingAction( this.remoting, - new byte[] { 12, 78, 101, 119 }, + [12, 78, 101, 119], new global::Substrate.NetApi.Model.Types.Primitive.U32(a)); } } @@ -58,7 +64,7 @@ public partial class Service : IService { return new RemotingAction>( this.remoting, - new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115 }, + [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) ); } @@ -68,7 +74,7 @@ public partial class Service : IService { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, - new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116 }, + [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } @@ -78,7 +84,7 @@ public partial class Service : IService { return new RemotingAction( this.remoting, - new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115 }, + [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } @@ -88,18 +94,85 @@ public partial class Service : IService { return new RemotingAction>( this.remoting, - new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116 }, + [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } } + +public enum ServiceEvents +{ + /// + /// `This` Done + /// + ThisDone, + /// + /// `That` Done too + /// + ThatDone, +} + +public sealed partial class EnumServiceEvents : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumServiceEvents() + { + this.AddTypeDecoder(ServiceEvents.ThisDone); + this.AddTypeDecoder(ServiceEvents.ThatDone); + } +} + +public partial class ServiceListener : IRemotingListener +{ + private static readonly byte[][] EventRoutes = + [ + [28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 105, 115, 68, 111, 110, 101], + [28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 97, 116, 68, 111, 110, 101], + ]; + + private readonly IRemotingListener remoting; + + public ServiceListener(IRemotingListener remoting) + { + this.remoting = remoting; + } + + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync( + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + { + await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) + { + byte idx = 0; + foreach (var route in EventRoutes) + { + if (route.Length > bytes.Length) + { + continue; + } + if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) + { + var bytesLength = bytes.Length - route.Length + 1; + var data = new byte[bytesLength]; + data[0] = idx; + Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); + + var p = 0; + EnumServiceEvents ev = new(); + ev.Decode(bytes, ref p); + yield return ev; + } + idx++; + } + } + } +} + /// /// ThisThatSvcAppTupleStruct docs /// [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { - public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } + public required global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } /// public override string TypeName() => "ThisThatSvcAppTupleStruct"; @@ -121,7 +194,7 @@ public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } @@ -134,15 +207,15 @@ public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi /// /// field `query` /// - public global::Substrate.NetApi.Model.Types.Primitive.U32 Query { get; set; } + public required global::Substrate.NetApi.Model.Types.Primitive.U32 Query { get; set; } /// /// field `result` /// - public global::Substrate.NetApi.Model.Types.Primitive.Str Result { get; set; } + public required global::Substrate.NetApi.Model.Types.Primitive.Str Result { get; set; } /// /// field `p3` /// - public EnumThisThatSvcAppManyVariants P3 { get; set; } + public required EnumThisThatSvcAppManyVariants P3 { get; set; } /// public override string TypeName() => "ThisThatSvcAppDoThatParam"; @@ -170,7 +243,7 @@ public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap index fc72a988..0c40a5d0 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -2,6 +2,12 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: code --- +using global::Sails.Remoting.Abstractions; +using global::System; +using global::System.Collections.Generic; + +#pragma warning disable RCS0056 // A line is too long + public interface IServiceFactory { IActivation New( @@ -23,7 +29,7 @@ public partial class ServiceFactory : IServiceFactory { return new RemotingAction( this.remoting, - new byte[] { 12, 78, 101, 119 }, + [12, 78, 101, 119], new global::Substrate.NetApi.Model.Types.Primitive.U32(a)); } } @@ -55,7 +61,7 @@ public partial class Service : IService { return new RemotingAction>( this.remoting, - new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115 }, + [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) ); } @@ -65,7 +71,7 @@ public partial class Service : IService { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, - new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116 }, + [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } @@ -75,7 +81,7 @@ public partial class Service : IService { return new RemotingAction( this.remoting, - new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115 }, + [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } @@ -85,15 +91,16 @@ public partial class Service : IService { return new RemotingAction>( this.remoting, - new byte[] { 28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116 }, + [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } } + [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { - public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } + public required global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } /// public override string TypeName() => "ThisThatSvcAppTupleStruct"; @@ -115,16 +122,16 @@ public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType { - public global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } - public global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } - public EnumThisThatSvcAppManyVariants P3 { get; set; } + public required global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } + public required global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } + public required EnumThisThatSvcAppManyVariants P3 { get; set; } /// public override string TypeName() => "ThisThatSvcAppDoThatParam"; @@ -152,7 +159,7 @@ public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; - global::System.Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap index c3950115..50dc46b5 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap @@ -1,128 +1,73 @@ --- -source: rs/client-gen/tests/generator.rs +source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"Multiple\")" --- -// Code generated by sails-client-gen. DO NOT EDIT. -#[allow(unused_imports)] -use sails_rs::collections::BTreeMap; -#[allow(unused_imports)] -use sails_rs::{ - calls::{Activation, Call, Query, Remoting, RemotingAction}, - prelude::*, - String, -}; -pub struct Multiple { - remoting: R, -} -impl Multiple { - pub fn new(remoting: R) -> Self { - Self { remoting } - } -} -impl traits::Multiple for Multiple { - type Args = R::Args; - fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call { - RemotingAction::<_, multiple::io::DoThis>::new(self.remoting.clone(), (p1, p2)) - } - fn do_that(&mut self, p1: (u8, u32)) -> impl Call { - RemotingAction::<_, multiple::io::DoThat>::new(self.remoting.clone(), p1) - } +using global::Sails.Remoting.Abstractions; + +#pragma warning disable RCS0056 // A line is too long + +public interface IMultiple +{ + global::Sails.Remoting.Abstractions.ICall DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); + global::Sails.Remoting.Abstractions.ICall DoThat( + global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } -pub mod multiple { - use super::*; +public partial class Multiple : IMultiple +{ + private readonly IRemoting remoting; - pub mod io { - use super::*; - use sails_rs::calls::ActionIo; - pub struct DoThis(()); - impl DoThis { - #[allow(dead_code)] - pub fn encode_call(p1: u32, p2: super::MyParam) -> Vec { - ::encode_call(&(p1, p2)) - } - } - impl ActionIo for DoThis { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; - type Params = (u32, super::MyParam); - type Reply = u16; - } - pub struct DoThat(()); - impl DoThat { - #[allow(dead_code)] - pub fn encode_call(p1: (u8, u32)) -> Vec { - ::encode_call(&p1) - } - } - impl ActionIo for DoThat { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 97, 116]; - type Params = (u8, u32); - type Reply = u8; - } + public Multiple(IRemoting remoting) + { + this.remoting = remoting; } -} -pub struct Named { - remoting: R, -} -impl Named { - pub fn new(remoting: R) -> Self { - Self { remoting } + + /// + public global::Sails.Remoting.Abstractions.ICall DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) + { + return new RemotingAction( + this.remoting, + [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 105, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) + ); } -} -impl traits::Named for Named { - type Args = R::Args; - fn that(&self, p1: u32) -> impl Query { - RemotingAction::<_, named::io::That>::new(self.remoting.clone(), p1) + /// + public global::Sails.Remoting.Abstractions.ICall DoThat( + global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) + { + return new RemotingAction( + this.remoting, + [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 97, 116], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) + ); } } -pub mod named { - use super::*; - - pub mod io { - use super::*; - use sails_rs::calls::ActionIo; - pub struct That(()); - impl That { - #[allow(dead_code)] - pub fn encode_call(p1: u32) -> Vec { - ::encode_call(&p1) - } - } - impl ActionIo for That { - const ROUTE: &'static [u8] = &[20, 78, 97, 109, 101, 100, 16, 84, 104, 97, 116]; - type Params = u32; - type Reply = String; - } - } +public interface INamed +{ + global::Sails.Remoting.Abstractions.IQuery That( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1); } -pub mod traits { - use super::*; +public partial class Named : INamed +{ + private readonly IRemoting remoting; - #[allow(clippy::type_complexity)] - pub trait Multiple { - type Args; - fn do_this(&mut self, p1: u32, p2: MyParam) -> impl Call; - fn do_that(&mut self, p1: (u8, u32)) -> impl Call; + public Named(IRemoting remoting) + { + this.remoting = remoting; } - #[allow(clippy::type_complexity)] - pub trait Named { - type Args; - fn that(&self, p1: u32) -> impl Query; + /// + public global::Sails.Remoting.Abstractions.IQuery That( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1) + { + return new RemotingAction( + this.remoting, + [20, 78, 97, 109, 101, 100, 16, 84, 104, 97, 116], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) + ); } } - -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -extern crate std; - -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -pub mod mockall { - use super::*; - use sails_rs::mockall::*; - mock! { pub Multiple {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::Multiple for Multiple { type Args = A; fn do_this (&mut self, p1: u32,p2: MyParam,) -> MockCall;fn do_that (&mut self, p1: (u8,u32,),) -> MockCall; } } - mock! { pub Named {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::Named for Named { type Args = A; fn that (& self, p1: u32,) -> MockQuery; } } -} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap index 997e75aa..656ee63b 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap @@ -1,86 +1,73 @@ --- -source: rs/client-gen/tests/generator.rs +source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"NonZeroParams\")" --- -// Code generated by sails-client-gen. DO NOT EDIT. -#[allow(unused_imports)] -use sails_rs::collections::BTreeMap; -#[allow(unused_imports)] -use sails_rs::{ - calls::{Activation, Call, Query, Remoting, RemotingAction}, - prelude::*, - String, -}; -pub struct NonZeroParams { - remoting: R, -} -impl NonZeroParams { - pub fn new(remoting: R) -> Self { - Self { remoting } - } -} -impl traits::NonZeroParams for NonZeroParams { - type Args = R::Args; - fn do_this( - &mut self, - p1: NonZeroU256, - p2: MyParam, - ) -> impl Call { - RemotingAction::<_, non_zero_params::io::DoThis>::new(self.remoting.clone(), (p1, p2)) - } -} +using global::Sails.Remoting.Abstractions; +using global::System; +using global::System.Collections.Generic; -pub mod non_zero_params { - use super::*; +#pragma warning disable RCS0056 // A line is too long - pub mod io { - use super::*; - use sails_rs::calls::ActionIo; - pub struct DoThis(()); - impl DoThis { - #[allow(dead_code)] - pub fn encode_call(p1: NonZeroU256, p2: super::MyParam) -> Vec { - ::encode_call(&(p1, p2)) - } - } - impl ActionIo for DoThis { - const ROUTE: &'static [u8] = &[24, 68, 111, 84, 104, 105, 115]; - type Params = (NonZeroU256, super::MyParam); - type Reply = NonZeroU64; - } - } -} -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub struct MyParam { - pub f1: NonZeroU256, - pub f2: Vec, - pub f3: Option<(NonZeroU64, NonZeroU256)>, +public interface INonZeroParams +{ + global::Sails.Remoting.Abstractions.ICall DoThis( + NonZeroU256 p1, MyParam p2); } -pub mod traits { - use super::*; +public partial class NonZeroParams : INonZeroParams +{ + private readonly IRemoting remoting; - #[allow(clippy::type_complexity)] - pub trait NonZeroParams { - type Args; - fn do_this( - &mut self, - p1: NonZeroU256, - p2: MyParam, - ) -> impl Call; + public NonZeroParams(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public global::Sails.Remoting.Abstractions.ICall DoThis( + NonZeroU256 p1, MyParam p2) + { + return new RemotingAction( + this.remoting, + [52, 78, 111, 110, 90, 101, 114, 111, 80, 97, 114, 97, 109, 115, 24, 68, 111, 84, 104, 105, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) + ); } } -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -extern crate std; +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public required NonZeroU256 F1 { get; set; } + public required global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } + public required global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } + + /// + public override string TypeName() => "MyParam"; -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -pub mod mockall { - use super::*; - use sails_rs::mockall::*; - mock! { pub NonZeroParams {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::NonZeroParams for NonZeroParams { type Args = A; fn do_this (&mut self, p1: NonZeroU256,p2: MyParam,) -> MockCall; } } + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(this.F1.Encode()); + result.AddRange(this.F2.Encode()); + result.AddRange(this.F3.Encode()); + return result.ToArray(); + } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + this.F1 = new NonZeroU256(); + this.F1.Decode(byteArray, ref p); + this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.F2.Decode(byteArray, ref p); + this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); + this.F3.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap index ae8cde16..c8fdb2d7 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap @@ -1,255 +1,152 @@ --- -source: rs/client-gen/tests/generator.rs +source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"RmrkCatalog\")" --- -// Code generated by sails-client-gen. DO NOT EDIT. -#[allow(unused_imports)] -use sails_rs::collections::BTreeMap; -#[allow(unused_imports)] -use sails_rs::{ - calls::{Activation, Call, Query, Remoting, RemotingAction}, - prelude::*, - String, -}; -pub struct RmrkCatalogFactory { - #[allow(dead_code)] - remoting: R, -} -impl RmrkCatalogFactory { - #[allow(unused)] - pub fn new(remoting: R) -> Self { - Self { remoting } - } +using global::Sails.Remoting.Abstractions; +using global::System; +using global::System.Collections.Generic; + +#pragma warning disable RCS0056 // A line is too long + +public interface IRmrkCatalogFactory +{ + IActivation New( + ); } -impl traits::RmrkCatalogFactory for RmrkCatalogFactory { - type Args = R::Args; - fn new(&self) -> impl Activation { - RemotingAction::<_, rmrk_catalog_factory::io::New>::new(self.remoting.clone(), ()) + +public partial class RmrkCatalogFactory : IRmrkCatalogFactory +{ + private readonly IRemoting remoting; + + public RmrkCatalogFactory(IRemoting remoting) + { + this.remoting = remoting; } -} -pub mod rmrk_catalog_factory { - use super::*; - pub mod io { - use super::*; - use sails_rs::calls::ActionIo; - pub struct New(()); - impl New { - #[allow(dead_code)] - pub fn encode_call() -> Vec { - ::encode_call(&()) - } - } - impl ActionIo for New { - const ROUTE: &'static [u8] = &[12, 78, 101, 119]; - type Params = (); - type Reply = (); - } + /// + public IActivation New( + ) + { + return new RemotingAction<>( + this.remoting, + [12, 78, 101, 119], + new ()); } } -pub struct RmrkCatalog { - remoting: R, + +public interface IRmrkCatalog +{ + global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds); + global::Sails.Remoting.Abstractions.ICall, Error>> AddParts( + BTreeMap parts); + global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); + global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts( + global::Substrate.NetApi.Model.Types.Base.BaseVec partIds); + global::Sails.Remoting.Abstractions.ICall> ResetEquippables( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId); + global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId); + global::Sails.Remoting.Abstractions.IQuery> Equippable( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); + global::Sails.Remoting.Abstractions.IQuery> Part( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId); } -impl RmrkCatalog { - pub fn new(remoting: R) -> Self { - Self { remoting } + +public partial class RmrkCatalog : IRmrkCatalog +{ + private readonly IRemoting remoting; + + public RmrkCatalog(IRemoting remoting) + { + this.remoting = remoting; } -} -impl traits::RmrkCatalog for RmrkCatalog { - type Args = R::Args; - fn add_equippables( - &mut self, - part_id: u32, - collection_ids: Vec, - ) -> impl Call), Error>, Args = R::Args> { - RemotingAction::<_, rmrk_catalog::io::AddEquippables>::new( - self.remoting.clone(), - (part_id, collection_ids), - ) + + /// + public global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds) + { + return new RemotingAction>, Error>>( + this.remoting, + [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 56, 65, 100, 100, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionIds) + ); } - fn add_parts( - &mut self, - parts: BTreeMap, - ) -> impl Call, Error>, Args = R::Args> { - RemotingAction::<_, rmrk_catalog::io::AddParts>::new(self.remoting.clone(), parts) + /// + public global::Sails.Remoting.Abstractions.ICall, Error>> AddParts( + BTreeMap parts) + { + return new RemotingAction, Error>>( + this.remoting, + [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 32, 65, 100, 100, 80, 97, 114, 116, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(parts) + ); } - fn remove_equippable( - &mut self, - part_id: u32, - collection_id: ActorId, - ) -> impl Call, Args = R::Args> { - RemotingAction::<_, rmrk_catalog::io::RemoveEquippable>::new( - self.remoting.clone(), - (part_id, collection_id), - ) + /// + public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) + { + return new RemotingAction, Error>>( + this.remoting, + [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 109, 111, 118, 101, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) + ); } - fn remove_parts( - &mut self, - part_ids: Vec, - ) -> impl Call, Error>, Args = R::Args> { - RemotingAction::<_, rmrk_catalog::io::RemoveParts>::new(self.remoting.clone(), part_ids) + /// + public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts( + global::Substrate.NetApi.Model.Types.Base.BaseVec partIds) + { + return new RemotingAction, Error>>( + this.remoting, + [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 44, 82, 101, 109, 111, 118, 101, 80, 97, 114, 116, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partIds) + ); } - fn reset_equippables( - &mut self, - part_id: u32, - ) -> impl Call, Args = R::Args> { - RemotingAction::<_, rmrk_catalog::io::ResetEquippables>::new(self.remoting.clone(), part_id) + /// + public global::Sails.Remoting.Abstractions.ICall> ResetEquippables( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId) + { + return new RemotingAction>( + this.remoting, + [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 115, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) + ); } - fn set_equippables_to_all( - &mut self, - part_id: u32, - ) -> impl Call, Args = R::Args> { - RemotingAction::<_, rmrk_catalog::io::SetEquippablesToAll>::new( - self.remoting.clone(), - part_id, - ) + /// + public global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId) + { + return new RemotingAction>( + this.remoting, + [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 76, 83, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115, 84, 111, 65, 108, 108], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) + ); } - fn equippable( - &self, - part_id: u32, - collection_id: ActorId, - ) -> impl Query, Args = R::Args> { - RemotingAction::<_, rmrk_catalog::io::Equippable>::new( - self.remoting.clone(), - (part_id, collection_id), - ) + /// + public global::Sails.Remoting.Abstractions.IQuery> Equippable( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) + { + return new RemotingAction>( + this.remoting, + [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 40, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) + ); } - fn part(&self, part_id: u32) -> impl Query, Args = R::Args> { - RemotingAction::<_, rmrk_catalog::io::Part>::new(self.remoting.clone(), part_id) + /// + public global::Sails.Remoting.Abstractions.IQuery> Part( + global::Substrate.NetApi.Model.Types.Primitive.U32 partId) + { + return new RemotingAction>( + this.remoting, + [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 16, 80, 97, 114, 116], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) + ); } } -pub mod rmrk_catalog { - use super::*; - - pub mod io { - use super::*; - use sails_rs::calls::ActionIo; - pub struct AddEquippables(()); - impl AddEquippables { - #[allow(dead_code)] - pub fn encode_call(part_id: u32, collection_ids: Vec) -> Vec { - ::encode_call(&(part_id, collection_ids)) - } - } - impl ActionIo for AddEquippables { - const ROUTE: &'static [u8] = &[ - 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 56, 65, 100, 100, 69, 113, - 117, 105, 112, 112, 97, 98, 108, 101, 115, - ]; - type Params = (u32, Vec); - type Reply = Result<(u32, Vec), super::Error>; - } - pub struct AddParts(()); - impl AddParts { - #[allow(dead_code)] - pub fn encode_call(parts: BTreeMap) -> Vec { - ::encode_call(&parts) - } - } - impl ActionIo for AddParts { - const ROUTE: &'static [u8] = &[ - 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 32, 65, 100, 100, 80, 97, - 114, 116, 115, - ]; - type Params = BTreeMap; - type Reply = Result, super::Error>; - } - pub struct RemoveEquippable(()); - impl RemoveEquippable { - #[allow(dead_code)] - pub fn encode_call(part_id: u32, collection_id: ActorId) -> Vec { - ::encode_call(&(part_id, collection_id)) - } - } - impl ActionIo for RemoveEquippable { - const ROUTE: &'static [u8] = &[ - 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 109, 111, 118, - 101, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, - ]; - type Params = (u32, ActorId); - type Reply = Result<(u32, ActorId), super::Error>; - } - pub struct RemoveParts(()); - impl RemoveParts { - #[allow(dead_code)] - pub fn encode_call(part_ids: Vec) -> Vec { - ::encode_call(&part_ids) - } - } - impl ActionIo for RemoveParts { - const ROUTE: &'static [u8] = &[ - 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 44, 82, 101, 109, 111, 118, - 101, 80, 97, 114, 116, 115, - ]; - type Params = Vec; - type Reply = Result, super::Error>; - } - pub struct ResetEquippables(()); - impl ResetEquippables { - #[allow(dead_code)] - pub fn encode_call(part_id: u32) -> Vec { - ::encode_call(&part_id) - } - } - impl ActionIo for ResetEquippables { - const ROUTE: &'static [u8] = &[ - 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 115, 101, 116, - 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115, - ]; - type Params = u32; - type Reply = Result<(), super::Error>; - } - pub struct SetEquippablesToAll(()); - impl SetEquippablesToAll { - #[allow(dead_code)] - pub fn encode_call(part_id: u32) -> Vec { - ::encode_call(&part_id) - } - } - impl ActionIo for SetEquippablesToAll { - const ROUTE: &'static [u8] = &[ - 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 76, 83, 101, 116, 69, 113, - 117, 105, 112, 112, 97, 98, 108, 101, 115, 84, 111, 65, 108, 108, - ]; - type Params = u32; - type Reply = Result<(), super::Error>; - } - pub struct Equippable(()); - impl Equippable { - #[allow(dead_code)] - pub fn encode_call(part_id: u32, collection_id: ActorId) -> Vec { - ::encode_call(&(part_id, collection_id)) - } - } - impl ActionIo for Equippable { - const ROUTE: &'static [u8] = &[ - 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 40, 69, 113, 117, 105, 112, - 112, 97, 98, 108, 101, - ]; - type Params = (u32, ActorId); - type Reply = Result; - } - pub struct Part(()); - impl Part { - #[allow(dead_code)] - pub fn encode_call(part_id: u32) -> Vec { - ::encode_call(&part_id) - } - } - impl ActionIo for Part { - const ROUTE: &'static [u8] = &[ - 44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 16, 80, 97, 114, 116, - ]; - type Params = u32; - type Reply = Option; - } - } -} -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub enum Error { +public enum Error +{ PartIdCantBeZero, BadConfig, PartAlreadyExists, @@ -258,94 +155,121 @@ pub enum Error { WrongPartFormat, NotAllowedToCall, } -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub enum Part { - Fixed(FixedPart), - Slot(SlotPart), + +public sealed partial class EnumError : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumError() + { + this.AddTypeDecoder(Error.PartIdCantBeZero); + this.AddTypeDecoder(Error.BadConfig); + this.AddTypeDecoder(Error.PartAlreadyExists); + this.AddTypeDecoder(Error.ZeroLengthPassed); + this.AddTypeDecoder(Error.PartDoesNotExist); + this.AddTypeDecoder(Error.WrongPartFormat); + this.AddTypeDecoder(Error.NotAllowedToCall); + } +} + +public enum Part +{ + Fixed, + Slot, +} + +public sealed partial class EnumPart : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumPart() + { + this.AddTypeDecoder(Part.Fixed); + this.AddTypeDecoder(Part.Slot); + } } -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub struct FixedPart { + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class FixedPart : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + /// /// An optional zIndex of base part layer. /// specifies the stack order of an element. /// An element with greater stack order is always in front of an element with a lower stack order. - pub z: Option, + /// + public required global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } + /// /// The metadata URI of the part. - pub metadata_uri: String, + /// + public required global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } + + /// + public override string TypeName() => "FixedPart"; + + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(this.Z.Encode()); + result.AddRange(this.MetadataUri.Encode()); + return result.ToArray(); + } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + this.Z = new global::Substrate.NetApi.Model.Types.Base.BaseOpt(); + this.Z.Decode(byteArray, ref p); + this.MetadataUri = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + this.MetadataUri.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + } } -#[derive(PartialEq, Clone, Debug, Encode, Decode, TypeInfo)] -#[codec(crate = sails_rs::scale_codec)] -#[scale_info(crate = sails_rs::scale_info)] -pub struct SlotPart { + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class SlotPart : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + /// /// Array of whitelisted collections that can be equipped in the given slot. Used with slot parts only. - pub equippable: Vec, + /// + public required global::Substrate.NetApi.Model.Types.Base.BaseVec Equippable { get; set; } + /// /// An optional zIndex of base part layer. /// specifies the stack order of an element. /// An element with greater stack order is always in front of an element with a lower stack order. - pub z: Option, + /// + public required global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } + /// /// The metadata URI of the part. - pub metadata_uri: String, -} + /// + public required global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } -pub mod traits { - use super::*; - #[allow(dead_code)] - pub trait RmrkCatalogFactory { - type Args; - #[allow(clippy::new_ret_no_self)] - #[allow(clippy::wrong_self_convention)] - fn new(&self) -> impl Activation; - } + /// + public override string TypeName() => "SlotPart"; - #[allow(clippy::type_complexity)] - pub trait RmrkCatalog { - type Args; - fn add_equippables( - &mut self, - part_id: u32, - collection_ids: Vec, - ) -> impl Call), Error>, Args = Self::Args>; - fn add_parts( - &mut self, - parts: BTreeMap, - ) -> impl Call, Error>, Args = Self::Args>; - fn remove_equippable( - &mut self, - part_id: u32, - collection_id: ActorId, - ) -> impl Call, Args = Self::Args>; - fn remove_parts( - &mut self, - part_ids: Vec, - ) -> impl Call, Error>, Args = Self::Args>; - fn reset_equippables( - &mut self, - part_id: u32, - ) -> impl Call, Args = Self::Args>; - fn set_equippables_to_all( - &mut self, - part_id: u32, - ) -> impl Call, Args = Self::Args>; - fn equippable( - &self, - part_id: u32, - collection_id: ActorId, - ) -> impl Query, Args = Self::Args>; - fn part(&self, part_id: u32) -> impl Query, Args = Self::Args>; + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(this.Equippable.Encode()); + result.AddRange(this.Z.Encode()); + result.AddRange(this.MetadataUri.Encode()); + return result.ToArray(); } -} -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -extern crate std; - -#[cfg(feature = "with_mocks")] -#[cfg(not(target_arch = "wasm32"))] -pub mod mockall { - use super::*; - use sails_rs::mockall::*; - mock! { pub RmrkCatalog {} #[allow(refining_impl_trait)] #[allow(clippy::type_complexity)] impl traits::RmrkCatalog for RmrkCatalog { type Args = A; fn add_equippables (&mut self, part_id: u32,collection_ids: Vec,) -> MockCall,), Error>>;fn add_parts (&mut self, parts: BTreeMap,) -> MockCall, Error>>;fn remove_equippable (&mut self, part_id: u32,collection_id: ActorId,) -> MockCall>;fn remove_parts (&mut self, part_ids: Vec,) -> MockCall, Error>>;fn reset_equippables (&mut self, part_id: u32,) -> MockCall>;fn set_equippables_to_all (&mut self, part_id: u32,) -> MockCall>;fn equippable (& self, part_id: u32,collection_id: ActorId,) -> MockQuery>;fn part (& self, part_id: u32,) -> MockQuery>; } } + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + this.Equippable = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.Equippable.Decode(byteArray, ref p); + this.Z = new global::Substrate.NetApi.Model.Types.Base.BaseOpt(); + this.Z.Decode(byteArray, ref p); + this.MetadataUri = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + this.MetadataUri.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + } } From dab60dfab69c6bb57418fd098946cff634110e7e Mon Sep 17 00:00:00 2001 From: vobradovich Date: Mon, 28 Oct 2024 18:20:05 +0100 Subject: [PATCH 10/54] fix new lines --- rs/client-gen-dotnet/src/ctor_generators.rs | 2 +- rs/client-gen-dotnet/src/service_generators.rs | 2 +- .../tests/snapshots/generator__basic_works.snap | 4 ++-- .../tests/snapshots/generator__events_works.snap | 4 ++-- .../tests/snapshots/generator__external_types.snap | 4 ++-- .../tests/snapshots/generator__full.snap | 4 ++-- .../snapshots/generator__full_with_sails_path.snap | 4 ++-- .../snapshots/generator__multiple_services.snap | 4 ++-- .../tests/snapshots/generator__nonzero_works.snap | 4 ++-- .../tests/snapshots/generator__rmrk_works.snap | 12 ++++++------ 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/rs/client-gen-dotnet/src/ctor_generators.rs b/rs/client-gen-dotnet/src/ctor_generators.rs index 04c8212c..afdb1d6c 100644 --- a/rs/client-gen-dotnet/src/ctor_generators.rs +++ b/rs/client-gen-dotnet/src/ctor_generators.rs @@ -72,7 +72,7 @@ impl<'a> Visitor<'a> for CtorFactoryGenerator<'a> { ) }) .collect::>() - .join(",\r"); + .join(", "); let type_decls = func .params() diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/rs/client-gen-dotnet/src/service_generators.rs index 111aa9cb..3132a610 100644 --- a/rs/client-gen-dotnet/src/service_generators.rs +++ b/rs/client-gen-dotnet/src/service_generators.rs @@ -78,7 +78,7 @@ impl<'a> Visitor<'a> for ServiceClientGenerator<'a> { ) }) .collect::>() - .join(",\r"); + .join(", "); let func_return_type = &self.type_generator.generate_type_decl(func.output()); diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap index f5c0dbcf..6d9a7755 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap @@ -11,7 +11,7 @@ using global::System.Collections.Generic; public interface IBasic { global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); global::Sails.Remoting.Abstractions.ICall DoThat( global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } @@ -27,7 +27,7 @@ public partial class Basic : IBasic /// public global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap index 706f3e0a..df278a23 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap @@ -11,7 +11,7 @@ using global::System.Collections.Generic; public interface IServiceWithEvents { global::Sails.Remoting.Abstractions.ICall DoThis( - NonZeroU256 p1, MyParam p2); + NonZeroU256 p1, MyParam p2); } public partial class ServiceWithEvents : IServiceWithEvents @@ -25,7 +25,7 @@ public partial class ServiceWithEvents : IServiceWithEvents /// public global::Sails.Remoting.Abstractions.ICall DoThis( - NonZeroU256 p1, MyParam p2) + NonZeroU256 p1, MyParam p2) { return new RemotingAction( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap index 0d8e3da2..5f95629e 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap @@ -9,7 +9,7 @@ using global::Sails.Remoting.Abstractions; public interface IService { global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); global::Sails.Remoting.Abstractions.ICall DoThat( global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } @@ -25,7 +25,7 @@ public partial class Service : IService /// public global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap index 81d77ab1..aea53e2c 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -40,7 +40,7 @@ public partial class ServiceFactory : IServiceFactory public interface IService { global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( ThisThatSvcAppDoThatParam param); global::Sails.Remoting.Abstractions.IQuery This( @@ -60,7 +60,7 @@ public partial class Service : IService /// public global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap index 0c40a5d0..2eae0fb7 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -37,7 +37,7 @@ public partial class ServiceFactory : IServiceFactory public interface IService { global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( ThisThatSvcAppDoThatParam param); global::Sails.Remoting.Abstractions.IQuery This( @@ -57,7 +57,7 @@ public partial class Service : IService /// public global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap index 50dc46b5..e3b4a5ef 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap @@ -9,7 +9,7 @@ using global::Sails.Remoting.Abstractions; public interface IMultiple { global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); global::Sails.Remoting.Abstractions.ICall DoThat( global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } @@ -25,7 +25,7 @@ public partial class Multiple : IMultiple /// public global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap index 656ee63b..228dfef6 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap @@ -11,7 +11,7 @@ using global::System.Collections.Generic; public interface INonZeroParams { global::Sails.Remoting.Abstractions.ICall DoThis( - NonZeroU256 p1, MyParam p2); + NonZeroU256 p1, MyParam p2); } public partial class NonZeroParams : INonZeroParams @@ -25,7 +25,7 @@ public partial class NonZeroParams : INonZeroParams /// public global::Sails.Remoting.Abstractions.ICall DoThis( - NonZeroU256 p1, MyParam p2) + NonZeroU256 p1, MyParam p2) { return new RemotingAction( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap index c8fdb2d7..d7d8cc5f 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap @@ -37,11 +37,11 @@ public partial class RmrkCatalogFactory : IRmrkCatalogFactory public interface IRmrkCatalog { global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds); + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds); global::Sails.Remoting.Abstractions.ICall, Error>> AddParts( BTreeMap parts); global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts( global::Substrate.NetApi.Model.Types.Base.BaseVec partIds); global::Sails.Remoting.Abstractions.ICall> ResetEquippables( @@ -49,7 +49,7 @@ public interface IRmrkCatalog global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll( global::Substrate.NetApi.Model.Types.Primitive.U32 partId); global::Sails.Remoting.Abstractions.IQuery> Equippable( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); global::Sails.Remoting.Abstractions.IQuery> Part( global::Substrate.NetApi.Model.Types.Primitive.U32 partId); } @@ -65,7 +65,7 @@ public partial class RmrkCatalog : IRmrkCatalog /// public global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds) + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds) { return new RemotingAction>, Error>>( this.remoting, @@ -85,7 +85,7 @@ public partial class RmrkCatalog : IRmrkCatalog } /// public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { return new RemotingAction, Error>>( this.remoting, @@ -125,7 +125,7 @@ public partial class RmrkCatalog : IRmrkCatalog } /// public global::Sails.Remoting.Abstractions.IQuery> Equippable( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) + global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { return new RemotingAction>( this.remoting, From 4e0a69c8cb45c3857bb0f11d46b2086c38d41621 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 29 Oct 2024 15:12:53 +0100 Subject: [PATCH 11/54] generator build, csbindgen --- Cargo.lock | 13 +++++++- Cargo.toml | 1 + rs/client-gen-dotnet/Cargo.toml | 6 ++++ rs/client-gen-dotnet/build.rs | 8 +++++ rs/client-gen-dotnet/src/ctor_generators.rs | 18 +++++++---- rs/client-gen-dotnet/src/lib.rs | 32 +++++++++++++++++++ .../tests/snapshots/generator__full.snap | 6 ++-- .../generator__full_with_sails_path.snap | 6 ++-- .../snapshots/generator__rmrk_works.snap | 10 +++--- 9 files changed, 79 insertions(+), 21 deletions(-) create mode 100644 rs/client-gen-dotnet/build.rs diff --git a/Cargo.lock b/Cargo.lock index 7a5697dc..ac43bd45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1331,6 +1331,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "csbindgen" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c26b9831049b947d154bba920e4124053def72447be6fb106a96f483874b482a" +dependencies = [ + "regex", + "syn 2.0.82", +] + [[package]] name = "curve25519-dalek" version = "2.1.3" @@ -6202,6 +6212,7 @@ version = "0.6.1" dependencies = [ "anyhow", "convert_case 0.6.0", + "csbindgen", "genco", "insta", "itertools 0.13.0", @@ -8968,7 +8979,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fd8a144f..9077de2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ cargo-generate = "0.21" cargo_metadata = "0.18" clap = "4.5" convert-case = { package = "convert_case", version = "0.6" } +csbindgen = "1.9.3" futures = { version = "0.3", default-features = false } genco = "0.17" git-download = "0.1" diff --git a/rs/client-gen-dotnet/Cargo.toml b/rs/client-gen-dotnet/Cargo.toml index 390ec8f6..490d91aa 100644 --- a/rs/client-gen-dotnet/Cargo.toml +++ b/rs/client-gen-dotnet/Cargo.toml @@ -8,6 +8,12 @@ edition.workspace = true license.workspace = true repository.workspace = true +[lib] +crate-type = ["cdylib", "lib"] + +[build-dependencies] +csbindgen.workspace = true + [dependencies] anyhow.workspace = true convert-case.workspace = true diff --git a/rs/client-gen-dotnet/build.rs b/rs/client-gen-dotnet/build.rs new file mode 100644 index 00000000..6bb55191 --- /dev/null +++ b/rs/client-gen-dotnet/build.rs @@ -0,0 +1,8 @@ +fn main() { + csbindgen::Builder::default() + .input_extern_file("src/lib.rs") + .csharp_dll_name("sails_client_gen_dotnet") + .csharp_namespace("Sails.ClientGenerator") + .generate_csharp_file("../../net/src/Sails.ClientGenerator/NativeMethods.g.cs") + .unwrap(); +} diff --git a/rs/client-gen-dotnet/src/ctor_generators.rs b/rs/client-gen-dotnet/src/ctor_generators.rs index afdb1d6c..10b3d262 100644 --- a/rs/client-gen-dotnet/src/ctor_generators.rs +++ b/rs/client-gen-dotnet/src/ctor_generators.rs @@ -1,4 +1,7 @@ -use crate::{helpers::*, type_generators::TypeDeclGenerator}; +use crate::{ + helpers::*, + type_generators::{primitive_type_to_dotnet, TypeDeclGenerator}, +}; use convert_case::{Case, Casing}; use csharp::{block_comment, Tokens}; use genco::prelude::*; @@ -79,26 +82,29 @@ impl<'a> Visitor<'a> for CtorFactoryGenerator<'a> { .iter() .map(|p| p.type_decl()) .collect::>(); - let tuple_arg_type = self.type_generator.generate_types_as_tuple(type_decls); + let tuple_arg_type = if type_decls.is_empty() { + primitive_type_to_dotnet(PrimitiveType::Null).to_string() + } else { + self.type_generator.generate_types_as_tuple(type_decls) + }; let activation = &csharp::import("global::Sails.Remoting.Abstractions", "IActivation"); let action = &csharp::import("global::Sails.Remoting.Abstractions", "RemotingAction"); quote_in! { self.interface_tokens => - $activation $func_name_pascal($['\r'] - $(&args_with_type));$['\r'] + $activation $func_name_pascal($(&args_with_type));$['\r'] }; quote_in! { self.class_tokens => $(block_comment(vec![""])) - public $activation $func_name_pascal($['\r'] - $(&args_with_type)) + public $activation $func_name_pascal($(&args_with_type)) { return new $action<$(&tuple_arg_type)>( this.remoting, [$route_bytes], new $(&tuple_arg_type)($(&args))); } + $['\n'] }; } } diff --git a/rs/client-gen-dotnet/src/lib.rs b/rs/client-gen-dotnet/src/lib.rs index 3c6c79b5..bf6a9b3b 100644 --- a/rs/client-gen-dotnet/src/lib.rs +++ b/rs/client-gen-dotnet/src/lib.rs @@ -140,3 +140,35 @@ impl<'a> ClientGenerator<'a, IdlString<'a>> { Ok(()) } } + +/// # Safety +/// +/// Function [`free_c_string`] should be called after this function +#[no_mangle] +pub unsafe extern "C" fn generate_dotnet_client( + program_utf8: *const u8, + program_len: i32, + service_name_utf8: *const u8, + service_name_len: i32, +) -> *const std::ffi::c_char { + let slice = unsafe { std::slice::from_raw_parts(program_utf8, program_len as usize) }; + let program = unsafe { String::from_utf8_unchecked(slice.to_vec()) }; + let slice = unsafe { std::slice::from_raw_parts(service_name_utf8, service_name_len as usize) }; + let service_name = unsafe { String::from_utf8_unchecked(slice.to_vec()) }; + + let res = ClientGenerator::from_idl(program.as_str()) + .generate(service_name.as_str()) + .expect("failed to generate client"); + std::ffi::CString::new(res) + .expect("failed to create cstring") + .into_raw() +} + +/// # Safety +/// +/// This function should not be called before the [`generate_dotnet_client`] +#[no_mangle] +pub unsafe extern "C" fn free_c_string(str: *mut std::ffi::c_char) { + // drop + _ = unsafe { std::ffi::CString::from_raw(str) }; +} diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap index aea53e2c..20d4a6c6 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -13,8 +13,7 @@ public interface IServiceFactory /// /// New constructor /// - IActivation New( - global::Substrate.NetApi.Model.Types.Primitive.U32 a); + IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); } public partial class ServiceFactory : IServiceFactory @@ -27,8 +26,7 @@ public partial class ServiceFactory : IServiceFactory } /// - public IActivation New( - global::Substrate.NetApi.Model.Types.Primitive.U32 a) + public IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a) { return new RemotingAction( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap index 2eae0fb7..8f48ace9 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -10,8 +10,7 @@ using global::System.Collections.Generic; public interface IServiceFactory { - IActivation New( - global::Substrate.NetApi.Model.Types.Primitive.U32 a); + IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); } public partial class ServiceFactory : IServiceFactory @@ -24,8 +23,7 @@ public partial class ServiceFactory : IServiceFactory } /// - public IActivation New( - global::Substrate.NetApi.Model.Types.Primitive.U32 a) + public IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a) { return new RemotingAction( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap index d7d8cc5f..b35fc5cd 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap @@ -10,8 +10,7 @@ using global::System.Collections.Generic; public interface IRmrkCatalogFactory { - IActivation New( - ); + IActivation New(); } public partial class RmrkCatalogFactory : IRmrkCatalogFactory @@ -24,13 +23,12 @@ public partial class RmrkCatalogFactory : IRmrkCatalogFactory } /// - public IActivation New( - ) + public IActivation New() { - return new RemotingAction<>( + return new RemotingAction( this.remoting, [12, 78, 101, 119], - new ()); + new global::Substrate.NetApi.Model.Types.Base.BaseVoid()); } } From 5a1bf008eaaba461b4e9ecc168d0d146831331cb Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 29 Oct 2024 15:18:58 +0100 Subject: [PATCH 12/54] dotnet SailsClientGenerator --- Sails.Net.sln | 17 +- net/Directory.Build.props | 7 + net/Directory.Packages.props | 14 +- .../Sails.ClientGenerator/NativeMethods.g.cs | 40 + .../Sails.ClientGenerator.csproj | 25 + .../SailsClientGenerator.cs | 48 +- .../InMemoryAdditionalText.cs | 20 + .../Sails.ClientGenerator.Tests.csproj | 39 + .../SailsClientGeneratorTests.cs | 39 + ...rTests.Generate_DemoIdl#demo.g.verified.cs | 701 ++++++++++++++++++ .../Sails.ClientGenerator.Tests/idl/demo.idl | 91 +++ 11 files changed, 1009 insertions(+), 32 deletions(-) create mode 100644 net/src/Sails.ClientGenerator/NativeMethods.g.cs create mode 100644 net/tests/Sails.ClientGenerator.Tests/InMemoryAdditionalText.cs create mode 100644 net/tests/Sails.ClientGenerator.Tests/Sails.ClientGenerator.Tests.csproj create mode 100644 net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs create mode 100644 net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs create mode 100644 net/tests/Sails.ClientGenerator.Tests/idl/demo.idl diff --git a/Sails.Net.sln b/Sails.Net.sln index 37f9ea4e..f3d70a2e 100644 --- a/Sails.Net.sln +++ b/Sails.Net.sln @@ -9,7 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Substrate.Gear.Api", "net\s EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sails.Remoting.Abstractions", "net\src\Sails.Remoting.Abstractions\Sails.Remoting.Abstractions.csproj", "{0442F9DE-9775-4787-866B-22869C681995}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sails.Remoting", "net\src\Sails.Remoting\Sails.Remoting.csproj", "{4C15C311-F328-480C-A102-3DCDC2C0AF11}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sails.Remoting", "net\src\Sails.Remoting\Sails.Remoting.csproj", "{4C15C311-F328-480C-A102-3DCDC2C0AF11}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{17A264B0-419F-46D2-8ACE-662FB478E570}" ProjectSection(SolutionItems) = preProject @@ -17,9 +17,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution net\Directory.Packages.props = net\Directory.Packages.props EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate.Gear.Client", "net\src\Substrate.Gear.Client\Substrate.Gear.Client.csproj", "{1589D5A4-0CC4-4855-89E0-2E61BBC5E0B0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Substrate.Gear.Client", "net\src\Substrate.Gear.Client\Substrate.Gear.Client.csproj", "{1589D5A4-0CC4-4855-89E0-2E61BBC5E0B0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sails.ClientGenerator", "net\src\Sails.ClientGenerator\Sails.ClientGenerator.csproj", "{F93FFE42-71C1-44BD-9DBA-3559B307370C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sails.ClientGenerator", "net\src\Sails.ClientGenerator\Sails.ClientGenerator.csproj", "{F93FFE42-71C1-44BD-9DBA-3559B307370C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sails.ClientGenerator.Tests", "net\tests\Sails.ClientGenerator.Tests\Sails.ClientGenerator.Tests.csproj", "{A6A2172B-8F8F-4BDC-B519-E7299FFCCA5F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{19594BCA-94DB-44AD-ACBC-2ACFED242E9F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -51,10 +55,17 @@ Global {F93FFE42-71C1-44BD-9DBA-3559B307370C}.Debug|Any CPU.Build.0 = Debug|Any CPU {F93FFE42-71C1-44BD-9DBA-3559B307370C}.Release|Any CPU.ActiveCfg = Release|Any CPU {F93FFE42-71C1-44BD-9DBA-3559B307370C}.Release|Any CPU.Build.0 = Release|Any CPU + {A6A2172B-8F8F-4BDC-B519-E7299FFCCA5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A6A2172B-8F8F-4BDC-B519-E7299FFCCA5F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A6A2172B-8F8F-4BDC-B519-E7299FFCCA5F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A6A2172B-8F8F-4BDC-B519-E7299FFCCA5F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {A6A2172B-8F8F-4BDC-B519-E7299FFCCA5F} = {19594BCA-94DB-44AD-ACBC-2ACFED242E9F} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0894C08B-8BB9-401D-8471-26F5EB5A4EA2} EndGlobalSection diff --git a/net/Directory.Build.props b/net/Directory.Build.props index 6c268046..4b9ebbe4 100644 --- a/net/Directory.Build.props +++ b/net/Directory.Build.props @@ -15,6 +15,13 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + all + diff --git a/net/Directory.Packages.props b/net/Directory.Packages.props index d41ef1ec..9ac74d12 100644 --- a/net/Directory.Packages.props +++ b/net/Directory.Packages.props @@ -5,17 +5,17 @@ - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - all - + + + + + + + diff --git a/net/src/Sails.ClientGenerator/NativeMethods.g.cs b/net/src/Sails.ClientGenerator/NativeMethods.g.cs new file mode 100644 index 00000000..68809021 --- /dev/null +++ b/net/src/Sails.ClientGenerator/NativeMethods.g.cs @@ -0,0 +1,40 @@ +// +// This code is generated by csbindgen. +// DON'T CHANGE THIS DIRECTLY. +// +#pragma warning disable CS8500 +#pragma warning disable CS8981 +using System; +using System.Runtime.InteropServices; + + +namespace Sails.ClientGenerator +{ + internal static unsafe partial class NativeMethods + { + const string __DllName = "sails_client_gen_dotnet"; + + + + /// + /// # Safety + /// + /// Function [`free_c_string`] should be called after this function + /// + [DllImport(__DllName, EntryPoint = "generate_dotnet_client", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + internal static extern byte* generate_dotnet_client(byte* program_utf8, int program_len, byte* service_name_utf8, int service_name_len); + + /// + /// # Safety + /// + /// This function should not be called before the [`generate_dotnet_client`] + /// + [DllImport(__DllName, EntryPoint = "free_c_string", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + internal static extern void free_c_string(byte* str); + + + } + + + +} diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 13d08f3e..4b4d9201 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -10,13 +10,38 @@ true $(NoWarn);NU5128 Code generator for Sails.Net. + True + true + + + + Always + + + + + + + Always + sails_client_gen_dotnet.dll + + + Always + sails_client_gen_dotnet.pdb + + + + + + + diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 0135e4b5..9396d5cd 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -1,38 +1,42 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; namespace Sails.ClientGenerator; [Generator(LanguageNames.CSharp)] public partial class SailsClientGenerator : IIncrementalGenerator { - public const string SailsClientAttributeFullName = "Sails.ClientGenerator.SailsClientAttribute"; - public void Initialize(IncrementalGeneratorInitializationContext context) { - context.RegisterPostInitializationOutput(ctx => - { - ctx.AddSource("SailsClientAttribute.g.cs", """ -namespace Sails.ClientGenerator -{ - [System.AttributeUsage(System.AttributeTargets.Class)] - public class SailsClientAttribute : System.Attribute - { - } -} -"""); - }); - - var source = context.SyntaxProvider.ForAttributeWithMetadataName( - SailsClientAttributeFullName, - predicate: static (node, token) => node is ClassDeclarationSyntax, - transform: static (context, token) => context); + var source = context.AdditionalTextsProvider.Where(static file => file.Path.EndsWith(".idl")); context.RegisterSourceOutput(source, Generate); } - private static void Generate(SourceProductionContext context, GeneratorAttributeSyntaxContext source) + private static unsafe void Generate(SourceProductionContext context, AdditionalText source) { + var idl = source.GetText()!.ToString(); + var idlBytes = Encoding.UTF8.GetBytes(idl); + var name = Path.GetFileNameWithoutExtension(source.Path); + var nameBytes = Encoding.UTF8.GetBytes(name); + + fixed (byte* pIdl = idlBytes) + { + fixed (byte* pName = nameBytes) + { + var cstr = NativeMethods.generate_dotnet_client(pIdl, idlBytes.Length, pName, nameBytes.Length); + try + { + var str = new string((sbyte*)cstr); + context.AddSource($"{name}.g.cs", SourceText.From(str, encoding: Encoding.UTF8)); + } + finally + { + NativeMethods.free_c_string(cstr); + } + } + } } } diff --git a/net/tests/Sails.ClientGenerator.Tests/InMemoryAdditionalText.cs b/net/tests/Sails.ClientGenerator.Tests/InMemoryAdditionalText.cs new file mode 100644 index 00000000..d64ebecf --- /dev/null +++ b/net/tests/Sails.ClientGenerator.Tests/InMemoryAdditionalText.cs @@ -0,0 +1,20 @@ +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; + +namespace Sails.ClientGenerator.Tests; + +internal sealed class InMemoryAdditionalText : AdditionalText +{ + private readonly SourceText content; + + public InMemoryAdditionalText(string path, string content) + { + this.Path = path; + this.content = SourceText.From(content, Encoding.UTF8); + } + + public override string Path { get; } + + public override SourceText GetText(CancellationToken cancellationToken = default) => this.content; +} diff --git a/net/tests/Sails.ClientGenerator.Tests/Sails.ClientGenerator.Tests.csproj b/net/tests/Sails.ClientGenerator.Tests/Sails.ClientGenerator.Tests.csproj new file mode 100644 index 00000000..d37e346c --- /dev/null +++ b/net/tests/Sails.ClientGenerator.Tests/Sails.ClientGenerator.Tests.csproj @@ -0,0 +1,39 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs b/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs new file mode 100644 index 00000000..14f8d812 --- /dev/null +++ b/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs @@ -0,0 +1,39 @@ +using System.Collections.Immutable; +using System.Runtime.CompilerServices; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace Sails.ClientGenerator.Tests; + +public class SailsClientGeneratorTests +{ + [ModuleInitializer] + internal static void Init() => VerifySourceGenerators.Initialize(); + + + [Fact] + public Task Generate_DemoIdl() => Verify("idl/demo.idl"); + + private static Task Verify(params string[] fileNames) + { + // Create a Roslyn compilation for the syntax tree. + var compilation = CSharpCompilation.Create(assemblyName: "Tests"); + + var additionalFiles = fileNames + .Select(x => (file: x, content: File.ReadAllText(@$"./{x}"))) + .Select(x => new InMemoryAdditionalText(x.file, x.content)) + .ToImmutableArray(); + + // Create an instance of our SailsClientGenerator incremental source generator + var generator = new SailsClientGenerator().AsSourceGenerator(); + + // The GeneratorDriver is used to run our generator against a compilation + GeneratorDriver driver = CSharpGeneratorDriver.Create([generator], additionalTexts: additionalFiles); + + // Run the source generator! + driver = driver.RunGenerators(compilation); + + // Use verify to snapshot test the source generator output! + return Verifier.Verify(driver).UseDirectory("Snapshots"); + } +} diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs new file mode 100644 index 00000000..7f58f4b9 --- /dev/null +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs @@ -0,0 +1,701 @@ +//HintName: demo.g.cs +using global::Sails.Remoting.Abstractions; +using global::System; +using global::System.Collections.Generic; + +#pragma warning disable RCS0056 // A line is too long + +public interface IDemoFactory +{ + /// + /// Program constructor (called once at the very beginning of the program lifetime) + /// + IActivation Default(); + /// + /// Another program constructor (called once at the very beginning of the program lifetime) + /// + IActivation New(global::Substrate.NetApi.Model.Types.Base.BaseOpt counter, global::Substrate.NetApi.Model.Types.Base.BaseOpt> dogPosition); +} + +public partial class DemoFactory : IDemoFactory +{ + private readonly IRemoting remoting; + + public DemoFactory(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public IActivation Default() + { + return new RemotingAction( + this.remoting, + [28, 68, 101, 102, 97, 117, 108, 116], + new global::Substrate.NetApi.Model.Types.Base.BaseVoid()); + } + + /// + public IActivation New(global::Substrate.NetApi.Model.Types.Base.BaseOpt counter, global::Substrate.NetApi.Model.Types.Base.BaseOpt> dogPosition) + { + return new RemotingAction, global::Substrate.NetApi.Model.Types.Base.BaseOpt>>>( + this.remoting, + [12, 78, 101, 119], + new global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Base.BaseOpt>>(counter, dogPosition)); + } +} + +public interface ICounter +{ + global::Sails.Remoting.Abstractions.ICall Add( + global::Substrate.NetApi.Model.Types.Primitive.U32 value); + global::Sails.Remoting.Abstractions.ICall Sub( + global::Substrate.NetApi.Model.Types.Primitive.U32 value); + global::Sails.Remoting.Abstractions.IQuery Value( + ); +} + +public partial class Counter : ICounter +{ + private readonly IRemoting remoting; + + public Counter(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public global::Sails.Remoting.Abstractions.ICall Add( + global::Substrate.NetApi.Model.Types.Primitive.U32 value) + { + return new RemotingAction( + this.remoting, + [28, 67, 111, 117, 110, 116, 101, 114, 12, 65, 100, 100], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(value) + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall Sub( + global::Substrate.NetApi.Model.Types.Primitive.U32 value) + { + return new RemotingAction( + this.remoting, + [28, 67, 111, 117, 110, 116, 101, 114, 12, 83, 117, 98], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(value) + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery Value( + ) + { + return new RemotingAction( + this.remoting, + [28, 67, 111, 117, 110, 116, 101, 114, 20, 86, 97, 108, 117, 101], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } +} + +public enum CounterEvents +{ + /// + /// Emitted when a new value is added to the counter + /// + Added, + /// + /// Emitted when a value is subtracted from the counter + /// + Subtracted, +} + +public sealed partial class EnumCounterEvents : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumCounterEvents() + { + this.AddTypeDecoder(CounterEvents.Added); + this.AddTypeDecoder(CounterEvents.Subtracted); + } +} + +public partial class CounterListener : IRemotingListener +{ + private static readonly byte[][] EventRoutes = + [ + [28, 67, 111, 117, 110, 116, 101, 114, 20, 65, 100, 100, 101, 100], + [28, 67, 111, 117, 110, 116, 101, 114, 40, 83, 117, 98, 116, 114, 97, 99, 116, 101, 100], + ]; + + private readonly IRemotingListener remoting; + + public CounterListener(IRemotingListener remoting) + { + this.remoting = remoting; + } + + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync( + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + { + await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) + { + byte idx = 0; + foreach (var route in EventRoutes) + { + if (route.Length > bytes.Length) + { + continue; + } + if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) + { + var bytesLength = bytes.Length - route.Length + 1; + var data = new byte[bytesLength]; + data[0] = idx; + Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); + + var p = 0; + EnumCounterEvents ev = new(); + ev.Decode(bytes, ref p); + yield return ev; + } + idx++; + } + } + } +} + +public interface IDog +{ + global::Sails.Remoting.Abstractions.ICall MakeSound( + ); + global::Sails.Remoting.Abstractions.ICall Walk( + global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy); + global::Sails.Remoting.Abstractions.IQuery AvgWeight( + ); + global::Sails.Remoting.Abstractions.IQuery> Position( + ); +} + +public partial class Dog : IDog +{ + private readonly IRemoting remoting; + + public Dog(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public global::Sails.Remoting.Abstractions.ICall MakeSound( + ) + { + return new RemotingAction( + this.remoting, + [12, 68, 111, 103, 36, 77, 97, 107, 101, 83, 111, 117, 110, 100], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall Walk( + global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy) + { + return new RemotingAction( + this.remoting, + [12, 68, 111, 103, 16, 87, 97, 108, 107], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(dx, dy) + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery AvgWeight( + ) + { + return new RemotingAction( + this.remoting, + [12, 68, 111, 103, 36, 65, 118, 103, 87, 101, 105, 103, 104, 116], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery> Position( + ) + { + return new RemotingAction>( + this.remoting, + [12, 68, 111, 103, 32, 80, 111, 115, 105, 116, 105, 111, 110], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } +} + +public enum DogEvents +{ + Barked, + Walked, +} + +public sealed partial class EnumDogEvents : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumDogEvents() + { + this.AddTypeDecoder(DogEvents.Barked); + this.AddTypeDecoder, global::Substrate.NetApi.Model.Types.Base.BaseTuple>>(DogEvents.Walked); + } +} + +public partial class DogListener : IRemotingListener +{ + private static readonly byte[][] EventRoutes = + [ + [12, 68, 111, 103, 24, 66, 97, 114, 107, 101, 100], + [12, 68, 111, 103, 24, 87, 97, 108, 107, 101, 100], + ]; + + private readonly IRemotingListener remoting; + + public DogListener(IRemotingListener remoting) + { + this.remoting = remoting; + } + + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync( + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + { + await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) + { + byte idx = 0; + foreach (var route in EventRoutes) + { + if (route.Length > bytes.Length) + { + continue; + } + if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) + { + var bytesLength = bytes.Length - route.Length + 1; + var data = new byte[bytesLength]; + data[0] = idx; + Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); + + var p = 0; + EnumDogEvents ev = new(); + ev.Decode(bytes, ref p); + yield return ev; + } + idx++; + } + } + } +} + +public interface IPingPong +{ + global::Sails.Remoting.Abstractions.ICall> Ping( + global::Substrate.NetApi.Model.Types.Primitive.Str input); +} + +public partial class PingPong : IPingPong +{ + private readonly IRemoting remoting; + + public PingPong(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public global::Sails.Remoting.Abstractions.ICall> Ping( + global::Substrate.NetApi.Model.Types.Primitive.Str input) + { + return new RemotingAction>( + this.remoting, + [32, 80, 105, 110, 103, 80, 111, 110, 103, 16, 80, 105, 110, 103], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(input) + ); + } +} + +public interface IReferences +{ + global::Sails.Remoting.Abstractions.ICall Add( + global::Substrate.NetApi.Model.Types.Primitive.U32 v); + global::Sails.Remoting.Abstractions.ICall> AddByte( + global::Substrate.NetApi.Model.Types.Primitive.U8 byte); + global::Sails.Remoting.Abstractions.ICall> GuessNum( + global::Substrate.NetApi.Model.Types.Primitive.U8 number); + global::Sails.Remoting.Abstractions.ICall Incr( + ); + global::Sails.Remoting.Abstractions.ICall> SetNum( + global::Substrate.NetApi.Model.Types.Primitive.U8 number); + global::Sails.Remoting.Abstractions.IQuery Baked( + ); + global::Sails.Remoting.Abstractions.IQuery> LastByte( + ); + global::Sails.Remoting.Abstractions.IQuery> Message( + ); +} + +public partial class References : IReferences +{ + private readonly IRemoting remoting; + + public References(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public global::Sails.Remoting.Abstractions.ICall Add( + global::Substrate.NetApi.Model.Types.Primitive.U32 v) + { + return new RemotingAction( + this.remoting, + [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 12, 65, 100, 100], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v) + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall> AddByte( + global::Substrate.NetApi.Model.Types.Primitive.U8 byte) + { + return new RemotingAction>( + this.remoting, + [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 28, 65, 100, 100, 66, 121, 116, 101], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(byte) + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall> GuessNum( + global::Substrate.NetApi.Model.Types.Primitive.U8 number) + { + return new RemotingAction>( + this.remoting, + [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 32, 71, 117, 101, 115, 115, 78, 117, 109], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number) + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall Incr( + ) + { + return new RemotingAction( + this.remoting, + [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 16, 73, 110, 99, 114], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall> SetNum( + global::Substrate.NetApi.Model.Types.Primitive.U8 number) + { + return new RemotingAction>( + this.remoting, + [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 24, 83, 101, 116, 78, 117, 109], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number) + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery Baked( + ) + { + return new RemotingAction( + this.remoting, + [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 20, 66, 97, 107, 101, 100], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery> LastByte( + ) + { + return new RemotingAction>( + this.remoting, + [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 32, 76, 97, 115, 116, 66, 121, 116, 101], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery> Message( + ) + { + return new RemotingAction>( + this.remoting, + [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 28, 77, 101, 115, 115, 97, 103, 101], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } +} + +public interface IThisThat +{ + global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( + DoThatParam param); + global::Sails.Remoting.Abstractions.ICall> DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, NonZeroU8> p3, TupleStruct p4); + global::Sails.Remoting.Abstractions.ICall Noop( + ); + global::Sails.Remoting.Abstractions.IQuery> That( + ); + global::Sails.Remoting.Abstractions.IQuery This( + ); +} + +public partial class ThisThat : IThisThat +{ + private readonly IRemoting remoting; + + public ThisThat(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( + DoThatParam param) + { + return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( + this.remoting, + [32, 84, 104, 105, 115, 84, 104, 97, 116, 24, 68, 111, 84, 104, 97, 116], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall> DoThis( + global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, NonZeroU8> p3, TupleStruct p4) + { + return new RemotingAction>( + this.remoting, + [32, 84, 104, 105, 115, 84, 104, 97, 116, 24, 68, 111, 84, 104, 105, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) + ); + } + /// + public global::Sails.Remoting.Abstractions.ICall Noop( + ) + { + return new RemotingAction( + this.remoting, + [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 78, 111, 111, 112], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery> That( + ) + { + return new RemotingAction>( + this.remoting, + [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 84, 104, 97, 116], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } + /// + public global::Sails.Remoting.Abstractions.IQuery This( + ) + { + return new RemotingAction( + this.remoting, + [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 84, 104, 105, 115], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } +} + +public interface IValueFee +{ + global::Sails.Remoting.Abstractions.ICall DoSomethingAndTakeFee( + ); +} + +public partial class ValueFee : IValueFee +{ + private readonly IRemoting remoting; + + public ValueFee(IRemoting remoting) + { + this.remoting = remoting; + } + + /// + public global::Sails.Remoting.Abstractions.ICall DoSomethingAndTakeFee( + ) + { + return new RemotingAction( + this.remoting, + [32, 86, 97, 108, 117, 101, 70, 101, 101, 84, 68, 111, 83, 111, 109, 101, 116, 104, 105, 110, 103, 65, 110, 100, 84, 97, 107, 101, 70, 101, 101], + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() + ); + } +} + +public enum ValueFeeEvents +{ + Withheld, +} + +public sealed partial class EnumValueFeeEvents : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumValueFeeEvents() + { + this.AddTypeDecoder(ValueFeeEvents.Withheld); + } +} + +public partial class ValueFeeListener : IRemotingListener +{ + private static readonly byte[][] EventRoutes = + [ + [32, 86, 97, 108, 117, 101, 70, 101, 101, 32, 87, 105, 116, 104, 104, 101, 108, 100], + ]; + + private readonly IRemotingListener remoting; + + public ValueFeeListener(IRemotingListener remoting) + { + this.remoting = remoting; + } + + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync( + [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + { + await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) + { + byte idx = 0; + foreach (var route in EventRoutes) + { + if (route.Length > bytes.Length) + { + continue; + } + if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) + { + var bytesLength = bytes.Length - route.Length + 1; + var data = new byte[bytesLength]; + data[0] = idx; + Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); + + var p = 0; + EnumValueFeeEvents ev = new(); + ev.Decode(bytes, ref p); + yield return ev; + } + idx++; + } + } + } +} + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class ReferenceCount : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public required global::Substrate.NetApi.Model.Types.Primitive.U32 Value { get; set; } + + /// + public override string TypeName() => "ReferenceCount"; + + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(this.Value.Encode()); + return result.ToArray(); + } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + this.Value = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + this.Value.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + } +} + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class DoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public required global::Substrate.Gear.Api.Generated.Types.Base.NonZeroU32 P1 { get; set; } + public required global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId P2 { get; set; } + public required EnumManyVariants P3 { get; set; } + + /// + public override string TypeName() => "DoThatParam"; + + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(this.P1.Encode()); + result.AddRange(this.P2.Encode()); + result.AddRange(this.P3.Encode()); + return result.ToArray(); + } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + this.P1 = new global::Substrate.Gear.Api.Generated.Types.Base.NonZeroU32(); + this.P1.Decode(byteArray, ref p); + this.P2 = new global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId(); + this.P2.Decode(byteArray, ref p); + this.P3 = new EnumManyVariants(); + this.P3.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + } +} + +public enum ManyVariants +{ + One, + Two, + Three, + Four, + Five, + Six, +} + +public sealed partial class EnumManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust +{ + public EnumManyVariants() + { + this.AddTypeDecoder(ManyVariants.One); + this.AddTypeDecoder(ManyVariants.Two); + this.AddTypeDecoder>(ManyVariants.Three); + this.AddTypeDecoder>>(ManyVariants.Four); + this.AddTypeDecoder>(ManyVariants.Five); + this.AddTypeDecoder(ManyVariants.Six); + } +} + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] +public sealed partial class TupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType +{ + public required global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } + + /// + public override string TypeName() => "TupleStruct"; + + /// + public override byte[] Encode() + { + var result = new List(); + result.AddRange(this.Value.Encode()); + return result.ToArray(); + } + + /// + public override void Decode(byte[] byteArray, ref int p) + { + var start = p; + this.Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); + this.Value.Decode(byteArray, ref p); + var bytesLength = p - start; + this.TypeSize = bytesLength; + this.Bytes = new byte[bytesLength]; + Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); + } +} diff --git a/net/tests/Sails.ClientGenerator.Tests/idl/demo.idl b/net/tests/Sails.ClientGenerator.Tests/idl/demo.idl new file mode 100644 index 00000000..d7cc6728 --- /dev/null +++ b/net/tests/Sails.ClientGenerator.Tests/idl/demo.idl @@ -0,0 +1,91 @@ +type ReferenceCount = struct { + u32, +}; + +type DoThatParam = struct { + p1: nat32, + p2: actor_id, + p3: ManyVariants, +}; + +type ManyVariants = enum { + One, + Two: u32, + Three: opt u256, + Four: struct { a: u32, b: opt u16 }, + Five: struct { str, h256 }, + Six: struct { u32 }, +}; + +type TupleStruct = struct { + bool, +}; + +constructor { + /// Program constructor (called once at the very beginning of the program lifetime) + Default : (); + /// Another program constructor (called once at the very beginning of the program lifetime) + New : (counter: opt u32, dog_position: opt struct { i32, i32 }); +}; + +service Counter { + /// Add a value to the counter + Add : (value: u32) -> u32; + /// Substract a value from the counter + Sub : (value: u32) -> u32; + /// Get the current value + query Value : () -> u32; + + events { + /// Emitted when a new value is added to the counter + Added: u32; + /// Emitted when a value is subtracted from the counter + Subtracted: u32; + } +}; + +service Dog { + MakeSound : () -> str; + Walk : (dx: i32, dy: i32) -> null; + query AvgWeight : () -> u32; + query Position : () -> struct { i32, i32 }; + + events { + Barked; + Walked: struct { from: struct { i32, i32 }, to: struct { i32, i32 } }; + } +}; + +service PingPong { + Ping : (input: str) -> result (str, str); +}; + +service References { + Add : (v: u32) -> u32; + AddByte : (byte: u8) -> vec u8; + GuessNum : (number: u8) -> result (str, str); + Incr : () -> ReferenceCount; + SetNum : (number: u8) -> result (null, str); + query Baked : () -> str; + query LastByte : () -> opt u8; + query Message : () -> opt str; +}; + +service ThisThat { + DoThat : (param: DoThatParam) -> result (struct { actor_id, nat32 }, struct { str }); + DoThis : (p1: u32, p2: str, p3: struct { opt h160, nat8 }, p4: TupleStruct) -> struct { str, u32 }; + Noop : () -> null; + query That : () -> result (str, str); + query This : () -> u32; +}; + +service ValueFee { + /// Return flag if fee taken and remain value, + /// using special type `CommandReply` + DoSomethingAndTakeFee : () -> bool; + + events { + Withheld: u128; + } +}; + From 62acda4fd0c5609b53eb3a1b43daedadead88ceb Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 5 Nov 2024 11:35:56 +0100 Subject: [PATCH 13/54] wip: add BaseDictionary. map types --- Cargo.lock | 4 +- .../Model/Types/Base/BaseDictionary.cs | 151 ++++++++++++++++++ rs/client-gen-dotnet/src/type_generators.rs | 37 +++-- 3 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 net/src/Substrate.Gear.Client/Model/Types/Base/BaseDictionary.cs diff --git a/Cargo.lock b/Cargo.lock index 08a4a966..35faf406 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1338,7 +1338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c26b9831049b947d154bba920e4124053def72447be6fb106a96f483874b482a" dependencies = [ "regex", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -6228,7 +6228,7 @@ dependencies = [ [[package]] name = "sails-client-gen-dotnet" -version = "0.6.1" +version = "0.6.2" dependencies = [ "anyhow", "convert_case 0.6.0", diff --git a/net/src/Substrate.Gear.Client/Model/Types/Base/BaseDictionary.cs b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseDictionary.cs new file mode 100644 index 00000000..40147b32 --- /dev/null +++ b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseDictionary.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Substrate.NetApi; +using Substrate.NetApi.Model.Types; + +namespace Substrate.Gear.Client.Model.Types.Base; + +/// +/// Base Dictionary Type +/// +public class BaseDictionary : IType + where TKey : IType, new() + where TValue : IType, new() +{ + /// + /// Explicit conversion from Dictionary to BaseDictionary + /// + /// + public static explicit operator BaseDictionary(Dictionary p) + => new BaseDictionary(p); + + /// + /// Implicit conversion from BaseDictionary to Dictionary + /// + /// + public static implicit operator Dictionary(BaseDictionary p) => p.Value; + + /// + /// BaseDictionary Constructor + /// + public BaseDictionary() + { } + + /// + /// BaseDictionary Constructor + /// + /// + public BaseDictionary(Dictionary value) + { + this.Create(value); + } + + /// + /// BaseDictionary Type Name + /// + /// + public virtual string TypeName() => $"Dictionary<{new TKey().TypeName()}, {new TValue().TypeName()}>"; + + /// + /// BaseDictionary Type Size + /// + public int TypeSize { get; set; } + + /// + /// BaseDictionary Bytes + /// + [JsonIgnore] + public byte[] Bytes { get; internal set; } = []; + + /// + /// BaseDictionary Encode + /// + /// + public byte[] Encode() + { + var result = new List(); + result.AddRange(new CompactInteger(this.Value.Count).Encode()); + foreach (var kv in this.Value) + { + result.AddRange(kv.Key.Encode()); + result.AddRange(kv.Value.Encode()); + } + return result.ToArray(); + } + + /// + /// BaseDictionary Decode + /// + /// + /// + public void Decode(byte[] byteArray, ref int p) + { + var start = p; + + var length = CompactInteger.Decode(byteArray, ref p); + + var dict = new Dictionary(length); + for (var i = 0; i < length; i++) + { + var key = new TKey(); + key.Decode(byteArray, ref p); + var val = new TValue(); + val.Decode(byteArray, ref p); + dict[key] = val; + } + + this.TypeSize = p - start; + + this.Bytes = new byte[this.TypeSize]; + Array.Copy(byteArray, start, this.Bytes, 0, this.TypeSize); + this.Value = dict; + } + + /// + /// BaseDictionary Value + /// + public virtual Dictionary Value { get; internal set; } = []; + + /// + /// BaseDictionary Create + /// + /// + public void Create(Dictionary value) + { + this.Value = value; + this.Bytes = this.Encode(); + this.TypeSize = this.Bytes.Length; + } + + /// + /// BaseDictionary Create + /// + /// + public void Create(string str) => this.Create(Utils.HexToByteArray(str)); + + /// + /// BaseDictionary Create From Json + /// + /// + public void CreateFromJson(string str) => this.Create(Utils.HexToByteArray(str)); + + /// + /// BaseDictionary Create + /// + /// + public void Create(byte[] byteArray) + { + var p = 0; + this.Decode(byteArray, ref p); + } + + /// + /// BaseDictionary New + /// + /// + public IType New() => this; + + /// + public override string ToString() => JsonConvert.SerializeObject(this); +} diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index 669c015c..f1dd7784 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -25,6 +25,18 @@ macro_rules! gprimitives { }; } +macro_rules! client_base { + ($t: expr) => { + concat!("global::Substrate.Gear.Client.Model.Types.Base.", $t) + }; +} + +macro_rules! client_primitive { + ($t: expr) => { + concat!("global::Substrate.Gear.Client.Model.Types.Primitive.", $t) + }; +} + pub(crate) struct TopLevelTypeGenerator<'a> { type_name: &'a str, type_generator: TypeDeclGenerator<'a>, @@ -92,7 +104,7 @@ impl<'a> StructDefGenerator<'a> { pub(crate) fn finalize(self) -> Tokens { let system_array = &csharp::import("global::System", "Array"); - let generic_list = csharp::import("global::System.Collections.Generic", "List"); + let generic_list = &csharp::import("global::System.Collections.Generic", "List"); quote! { [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] @@ -299,7 +311,7 @@ impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { } fn visit_result_type_decl(&mut self, ok_type_decl: &'a TypeDecl, err_type_decl: &'a TypeDecl) { - self.code.push_str("Result<"); + self.code.push_str(client_base!("BaseResult<")); visitor::accept_type_decl(ok_type_decl, self); self.code.push_str(", "); visitor::accept_type_decl(err_type_decl, self); @@ -346,17 +358,16 @@ impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { } fn visit_map_type_decl(&mut self, key_type_decl: &'a TypeDecl, value_type_decl: &'a TypeDecl) { - self.code.push_str("BTreeMap<"); + self.code.push_str(client_base!("BaseDictionary<")); visitor::accept_type_decl(key_type_decl, self); self.code.push_str(", "); visitor::accept_type_decl(value_type_decl, self); self.code.push('>'); } - fn visit_array_type_decl(&mut self, item_type_decl: &'a TypeDecl, len: u32) { - self.code.push('['); + fn visit_array_type_decl(&mut self, item_type_decl: &'a TypeDecl, _len: u32) { visitor::accept_type_decl(item_type_decl, self); - self.code.push_str(&format!("; {len}]")); + self.code.push_str("[]"); } } @@ -379,14 +390,14 @@ pub(crate) fn primitive_type_to_dotnet(primitive_type: PrimitiveType) -> &'stati PrimitiveType::ActorId => gprimitives!("ActorId"), PrimitiveType::CodeId => gprimitives!("CodeId"), PrimitiveType::MessageId => gprimitives!("MessageId"), - PrimitiveType::H160 => "H160", + PrimitiveType::H160 => client_primitive!("H160"), PrimitiveType::H256 => "global::Substrate.Gear.Api.Generated.Model.primitive_types.H256", - PrimitiveType::U256 => "U256", - PrimitiveType::NonZeroU8 => "NonZeroU8", - PrimitiveType::NonZeroU16 => "NonZeroU16", + PrimitiveType::U256 => primitive!("U256"), + PrimitiveType::NonZeroU8 => client_primitive!("NonZeroU8"), + PrimitiveType::NonZeroU16 => client_primitive!("NonZeroU16"), PrimitiveType::NonZeroU32 => "global::Substrate.Gear.Api.Generated.Types.Base.NonZeroU32", - PrimitiveType::NonZeroU64 => "NonZeroU64", - PrimitiveType::NonZeroU128 => "NonZeroU128", - PrimitiveType::NonZeroU256 => "NonZeroU256", + PrimitiveType::NonZeroU64 => client_primitive!("NonZeroU64"), + PrimitiveType::NonZeroU128 => client_primitive!("NonZeroU128"), + PrimitiveType::NonZeroU256 => client_primitive!("NonZeroU256"), } } From 0208b7320f5d4befbdbca308a84b440c3980cbd9 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 5 Nov 2024 13:24:15 +0100 Subject: [PATCH 14/54] wip: fix types & dotnet generator --- .../Core/IRemotingListener.cs | 14 ++ .../Model/Types/Base/BaseDictionary.cs | 3 +- .../Model/Types/Base/BaseNonZero.cs | 5 +- .../Model/Types/Base/BaseResult.cs | 10 +- .../Model/Types/Primitive/H160.cs | 3 +- ...rTests.Generate_DemoIdl#demo.g.verified.cs | 184 +++++++----------- rs/client-gen-dotnet/src/ctor_generators.rs | 33 ++-- rs/client-gen-dotnet/src/events_generator.rs | 16 +- rs/client-gen-dotnet/src/helpers.rs | 104 +++++++++- rs/client-gen-dotnet/src/root_generator.rs | 5 + .../src/service_generators.rs | 24 +-- rs/client-gen-dotnet/src/type_generators.rs | 28 ++- .../snapshots/generator__basic_works.snap | 23 +-- .../snapshots/generator__events_works.snap | 32 +-- .../snapshots/generator__external_types.snap | 14 +- .../tests/snapshots/generator__full.snap | 49 +++-- .../generator__full_with_sails_path.snap | 42 ++-- .../generator__multiple_services.snap | 20 +- .../snapshots/generator__nonzero_works.snap | 25 +-- .../snapshots/generator__rmrk_works.snap | 79 ++++---- 20 files changed, 387 insertions(+), 326 deletions(-) create mode 100644 net/src/Sails.Remoting.Abstractions/Core/IRemotingListener.cs diff --git a/net/src/Sails.Remoting.Abstractions/Core/IRemotingListener.cs b/net/src/Sails.Remoting.Abstractions/Core/IRemotingListener.cs new file mode 100644 index 00000000..f5d72ebe --- /dev/null +++ b/net/src/Sails.Remoting.Abstractions/Core/IRemotingListener.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Threading; + +namespace Sails.Remoting.Abstractions.Core; + +public interface IRemotingListener +{ + /// + /// Listen to Gear events + /// + /// + /// + IAsyncEnumerable ListenAsync(CancellationToken cancellationToken); +} diff --git a/net/src/Substrate.Gear.Client/Model/Types/Base/BaseDictionary.cs b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseDictionary.cs index 40147b32..d2cb2d63 100644 --- a/net/src/Substrate.Gear.Client/Model/Types/Base/BaseDictionary.cs +++ b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseDictionary.cs @@ -17,8 +17,7 @@ public class BaseDictionary : IType /// Explicit conversion from Dictionary to BaseDictionary /// /// - public static explicit operator BaseDictionary(Dictionary p) - => new BaseDictionary(p); + public static explicit operator BaseDictionary(Dictionary p) => new(p); /// /// Implicit conversion from BaseDictionary to Dictionary diff --git a/net/src/Substrate.Gear.Client/Model/Types/Base/BaseNonZero.cs b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseNonZero.cs index 25761f57..ae4db676 100644 --- a/net/src/Substrate.Gear.Client/Model/Types/Base/BaseNonZero.cs +++ b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseNonZero.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics.CodeAnalysis; using Substrate.NetApi.Model.Types.Base; namespace Substrate.Gear.Client.Model.Types.Base; @@ -12,13 +11,13 @@ public class BaseNonZero : BaseType /// /// >> value /// - public required T Value { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public T Value { get; set; } public BaseNonZero() { } - [SetsRequiredMembers] public BaseNonZero(T value) { var span = value.Bytes.AsSpan(); diff --git a/net/src/Substrate.Gear.Client/Model/Types/Base/BaseResult.cs b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseResult.cs index ab94434d..f2af65ea 100644 --- a/net/src/Substrate.Gear.Client/Model/Types/Base/BaseResult.cs +++ b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseResult.cs @@ -6,7 +6,7 @@ namespace Substrate.Gear.Client.Model.Types.Base; /// /// Result /// -public enum BaseResult +public enum BaseResultEnum { /// @@ -23,7 +23,7 @@ public enum BaseResult /// /// EnumResult /// -public sealed class EnumBaseResult : BaseEnumRust +public sealed class BaseResult : BaseEnumRust where T1 : IType, new() where T2 : IType, new() { @@ -31,9 +31,9 @@ public sealed class EnumBaseResult : BaseEnumRust /// /// Initializes a new instance of the class. /// - public EnumBaseResult() + public BaseResult() { - this.AddTypeDecoder(BaseResult.Ok); - this.AddTypeDecoder(BaseResult.Err); + this.AddTypeDecoder(BaseResultEnum.Ok); + this.AddTypeDecoder(BaseResultEnum.Err); } } diff --git a/net/src/Substrate.Gear.Client/Model/Types/Primitive/H160.cs b/net/src/Substrate.Gear.Client/Model/Types/Primitive/H160.cs index fa08e6bf..49555c71 100644 --- a/net/src/Substrate.Gear.Client/Model/Types/Primitive/H160.cs +++ b/net/src/Substrate.Gear.Client/Model/Types/Primitive/H160.cs @@ -15,7 +15,8 @@ public sealed class H160 : BaseType /// /// >> value /// - public required Arr20U8 Value { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public Arr20U8 Value { get; set; } /// public override string TypeName() => nameof(H160); diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs index 7f58f4b9..b37e9745 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs @@ -5,6 +5,8 @@ #pragma warning disable RCS0056 // A line is too long +namespace Demo.Client; + public interface IDemoFactory { /// @@ -47,12 +49,9 @@ public IActivation New(global::Substrate.NetApi.Model.Types.Base.BaseOpt Add( - global::Substrate.NetApi.Model.Types.Primitive.U32 value); - global::Sails.Remoting.Abstractions.ICall Sub( - global::Substrate.NetApi.Model.Types.Primitive.U32 value); - global::Sails.Remoting.Abstractions.IQuery Value( - ); + global::Sails.Remoting.Abstractions.ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 value); + global::Sails.Remoting.Abstractions.ICall Sub(global::Substrate.NetApi.Model.Types.Primitive.U32 value); + global::Sails.Remoting.Abstractions.IQuery Value(); } public partial class Counter : ICounter @@ -65,8 +64,7 @@ public Counter(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall Add( - global::Substrate.NetApi.Model.Types.Primitive.U32 value) + public global::Sails.Remoting.Abstractions.ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 value) { return new RemotingAction( this.remoting, @@ -75,8 +73,7 @@ public Counter(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.ICall Sub( - global::Substrate.NetApi.Model.Types.Primitive.U32 value) + public global::Sails.Remoting.Abstractions.ICall Sub(global::Substrate.NetApi.Model.Types.Primitive.U32 value) { return new RemotingAction( this.remoting, @@ -85,8 +82,7 @@ public Counter(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.IQuery Value( - ) + public global::Sails.Remoting.Abstractions.IQuery Value() { return new RemotingAction( this.remoting, @@ -125,15 +121,14 @@ public partial class CounterListener : IRemotingListener [28, 67, 111, 117, 110, 116, 101, 114, 40, 83, 117, 98, 116, 114, 97, 99, 116, 101, 100], ]; - private readonly IRemotingListener remoting; + private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; - public CounterListener(IRemotingListener remoting) + public CounterListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) { this.remoting = remoting; } - public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync( - [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) { @@ -164,14 +159,10 @@ public CounterListener(IRemotingListener remoting) public interface IDog { - global::Sails.Remoting.Abstractions.ICall MakeSound( - ); - global::Sails.Remoting.Abstractions.ICall Walk( - global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy); - global::Sails.Remoting.Abstractions.IQuery AvgWeight( - ); - global::Sails.Remoting.Abstractions.IQuery> Position( - ); + global::Sails.Remoting.Abstractions.ICall MakeSound(); + global::Sails.Remoting.Abstractions.ICall Walk(global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy); + global::Sails.Remoting.Abstractions.IQuery AvgWeight(); + global::Sails.Remoting.Abstractions.IQuery> Position(); } public partial class Dog : IDog @@ -184,8 +175,7 @@ public Dog(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall MakeSound( - ) + public global::Sails.Remoting.Abstractions.ICall MakeSound() { return new RemotingAction( this.remoting, @@ -194,8 +184,7 @@ public Dog(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.ICall Walk( - global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy) + public global::Sails.Remoting.Abstractions.ICall Walk(global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy) { return new RemotingAction( this.remoting, @@ -204,8 +193,7 @@ public Dog(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.IQuery AvgWeight( - ) + public global::Sails.Remoting.Abstractions.IQuery AvgWeight() { return new RemotingAction( this.remoting, @@ -214,8 +202,7 @@ public Dog(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> Position( - ) + public global::Sails.Remoting.Abstractions.IQuery> Position() { return new RemotingAction>( this.remoting, @@ -248,15 +235,14 @@ public partial class DogListener : IRemotingListener [12, 68, 111, 103, 24, 87, 97, 108, 107, 101, 100], ]; - private readonly IRemotingListener remoting; + private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; - public DogListener(IRemotingListener remoting) + public DogListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) { this.remoting = remoting; } - public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync( - [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) { @@ -287,8 +273,7 @@ public DogListener(IRemotingListener remoting) public interface IPingPong { - global::Sails.Remoting.Abstractions.ICall> Ping( - global::Substrate.NetApi.Model.Types.Primitive.Str input); + global::Sails.Remoting.Abstractions.ICall> Ping(global::Substrate.NetApi.Model.Types.Primitive.Str input); } public partial class PingPong : IPingPong @@ -301,10 +286,9 @@ public PingPong(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall> Ping( - global::Substrate.NetApi.Model.Types.Primitive.Str input) + public global::Sails.Remoting.Abstractions.ICall> Ping(global::Substrate.NetApi.Model.Types.Primitive.Str input) { - return new RemotingAction>( + return new RemotingAction>( this.remoting, [32, 80, 105, 110, 103, 80, 111, 110, 103, 16, 80, 105, 110, 103], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(input) @@ -314,22 +298,14 @@ public PingPong(IRemoting remoting) public interface IReferences { - global::Sails.Remoting.Abstractions.ICall Add( - global::Substrate.NetApi.Model.Types.Primitive.U32 v); - global::Sails.Remoting.Abstractions.ICall> AddByte( - global::Substrate.NetApi.Model.Types.Primitive.U8 byte); - global::Sails.Remoting.Abstractions.ICall> GuessNum( - global::Substrate.NetApi.Model.Types.Primitive.U8 number); - global::Sails.Remoting.Abstractions.ICall Incr( - ); - global::Sails.Remoting.Abstractions.ICall> SetNum( - global::Substrate.NetApi.Model.Types.Primitive.U8 number); - global::Sails.Remoting.Abstractions.IQuery Baked( - ); - global::Sails.Remoting.Abstractions.IQuery> LastByte( - ); - global::Sails.Remoting.Abstractions.IQuery> Message( - ); + global::Sails.Remoting.Abstractions.ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 v); + global::Sails.Remoting.Abstractions.ICall> AddByte(global::Substrate.NetApi.Model.Types.Primitive.U8 @byte); + global::Sails.Remoting.Abstractions.ICall> GuessNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number); + global::Sails.Remoting.Abstractions.ICall Incr(); + global::Sails.Remoting.Abstractions.ICall> SetNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number); + global::Sails.Remoting.Abstractions.IQuery Baked(); + global::Sails.Remoting.Abstractions.IQuery> LastByte(); + global::Sails.Remoting.Abstractions.IQuery> Message(); } public partial class References : IReferences @@ -342,8 +318,7 @@ public References(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall Add( - global::Substrate.NetApi.Model.Types.Primitive.U32 v) + public global::Sails.Remoting.Abstractions.ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 v) { return new RemotingAction( this.remoting, @@ -352,28 +327,25 @@ public References(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.ICall> AddByte( - global::Substrate.NetApi.Model.Types.Primitive.U8 byte) + public global::Sails.Remoting.Abstractions.ICall> AddByte(global::Substrate.NetApi.Model.Types.Primitive.U8 @byte) { return new RemotingAction>( this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 28, 65, 100, 100, 66, 121, 116, 101], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(byte) + new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(@byte) ); } /// - public global::Sails.Remoting.Abstractions.ICall> GuessNum( - global::Substrate.NetApi.Model.Types.Primitive.U8 number) + public global::Sails.Remoting.Abstractions.ICall> GuessNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number) { - return new RemotingAction>( + return new RemotingAction>( this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 32, 71, 117, 101, 115, 115, 78, 117, 109], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number) ); } /// - public global::Sails.Remoting.Abstractions.ICall Incr( - ) + public global::Sails.Remoting.Abstractions.ICall Incr() { return new RemotingAction( this.remoting, @@ -382,18 +354,16 @@ public References(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.ICall> SetNum( - global::Substrate.NetApi.Model.Types.Primitive.U8 number) + public global::Sails.Remoting.Abstractions.ICall> SetNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number) { - return new RemotingAction>( + return new RemotingAction>( this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 24, 83, 101, 116, 78, 117, 109], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number) ); } /// - public global::Sails.Remoting.Abstractions.IQuery Baked( - ) + public global::Sails.Remoting.Abstractions.IQuery Baked() { return new RemotingAction( this.remoting, @@ -402,8 +372,7 @@ public References(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> LastByte( - ) + public global::Sails.Remoting.Abstractions.IQuery> LastByte() { return new RemotingAction>( this.remoting, @@ -412,8 +381,7 @@ public References(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> Message( - ) + public global::Sails.Remoting.Abstractions.IQuery> Message() { return new RemotingAction>( this.remoting, @@ -425,16 +393,11 @@ public References(IRemoting remoting) public interface IThisThat { - global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( - DoThatParam param); - global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, NonZeroU8> p3, TupleStruct p4); - global::Sails.Remoting.Abstractions.ICall Noop( - ); - global::Sails.Remoting.Abstractions.IQuery> That( - ); - global::Sails.Remoting.Abstractions.IQuery This( - ); + global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(DoThatParam param); + global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU8> p3, TupleStruct p4); + global::Sails.Remoting.Abstractions.ICall Noop(); + global::Sails.Remoting.Abstractions.IQuery> That(); + global::Sails.Remoting.Abstractions.IQuery This(); } public partial class ThisThat : IThisThat @@ -447,18 +410,16 @@ public ThisThat(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( - DoThatParam param) + public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(DoThatParam param) { - return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( + return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } /// - public global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, NonZeroU8> p3, TupleStruct p4) + public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU8> p3, TupleStruct p4) { return new RemotingAction>( this.remoting, @@ -467,8 +428,7 @@ public ThisThat(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.ICall Noop( - ) + public global::Sails.Remoting.Abstractions.ICall Noop() { return new RemotingAction( this.remoting, @@ -477,18 +437,16 @@ public ThisThat(IRemoting remoting) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> That( - ) + public global::Sails.Remoting.Abstractions.IQuery> That() { - return new RemotingAction>( + return new RemotingAction>( this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() ); } /// - public global::Sails.Remoting.Abstractions.IQuery This( - ) + public global::Sails.Remoting.Abstractions.IQuery This() { return new RemotingAction( this.remoting, @@ -500,8 +458,7 @@ public ThisThat(IRemoting remoting) public interface IValueFee { - global::Sails.Remoting.Abstractions.ICall DoSomethingAndTakeFee( - ); + global::Sails.Remoting.Abstractions.ICall DoSomethingAndTakeFee(); } public partial class ValueFee : IValueFee @@ -514,8 +471,7 @@ public ValueFee(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall DoSomethingAndTakeFee( - ) + public global::Sails.Remoting.Abstractions.ICall DoSomethingAndTakeFee() { return new RemotingAction( this.remoting, @@ -545,15 +501,14 @@ public partial class ValueFeeListener : IRemotingListener [32, 86, 97, 108, 117, 101, 70, 101, 101, 32, 87, 105, 116, 104, 104, 101, 108, 100], ]; - private readonly IRemotingListener remoting; + private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; - public ValueFeeListener(IRemotingListener remoting) + public ValueFeeListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) { this.remoting = remoting; } - public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync( - [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) { @@ -585,7 +540,8 @@ public ValueFeeListener(IRemotingListener remoting) [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ReferenceCount : global::Substrate.NetApi.Model.Types.Base.BaseType { - public required global::Substrate.NetApi.Model.Types.Primitive.U32 Value { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.U32 Value { get; set; } /// public override string TypeName() => "ReferenceCount"; @@ -614,9 +570,12 @@ public override void Decode(byte[] byteArray, ref int p) [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class DoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType { - public required global::Substrate.Gear.Api.Generated.Types.Base.NonZeroU32 P1 { get; set; } - public required global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId P2 { get; set; } - public required EnumManyVariants P3 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.Gear.Api.Generated.Types.Base.NonZeroU32 P1 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId P2 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public EnumManyVariants P3 { get; set; } /// public override string TypeName() => "DoThatParam"; @@ -664,7 +623,7 @@ public EnumManyVariants() { this.AddTypeDecoder(ManyVariants.One); this.AddTypeDecoder(ManyVariants.Two); - this.AddTypeDecoder>(ManyVariants.Three); + this.AddTypeDecoder>(ManyVariants.Three); this.AddTypeDecoder>>(ManyVariants.Four); this.AddTypeDecoder>(ManyVariants.Five); this.AddTypeDecoder(ManyVariants.Six); @@ -674,7 +633,8 @@ public EnumManyVariants() [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class TupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { - public required global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } /// public override string TypeName() => "TupleStruct"; diff --git a/rs/client-gen-dotnet/src/ctor_generators.rs b/rs/client-gen-dotnet/src/ctor_generators.rs index 10b3d262..df0af12e 100644 --- a/rs/client-gen-dotnet/src/ctor_generators.rs +++ b/rs/client-gen-dotnet/src/ctor_generators.rs @@ -3,7 +3,7 @@ use crate::{ type_generators::{primitive_type_to_dotnet, TypeDeclGenerator}, }; use convert_case::{Case, Casing}; -use csharp::{block_comment, Tokens}; +use csharp::Tokens; use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; @@ -34,15 +34,15 @@ impl<'a> CtorFactoryGenerator<'a> { $(self.interface_tokens) } $['\n'] - public partial class $(&class_name) : I$(&class_name) + public partial class $(&class_name) : I$(&class_name)$['\r'] { private readonly $remoting remoting; - - public $(&class_name)($remoting remoting) + $['\n'] + public $(&class_name)($remoting remoting)$['\r'] { this.remoting = remoting; } - + $['\n'] $(self.class_tokens) } $['\n'] @@ -63,19 +63,8 @@ impl<'a> Visitor<'a> for CtorFactoryGenerator<'a> { self.interface_tokens.push(); let route_bytes = &path_bytes(func.name()).0; - let args = encoded_fn_args(func.params()); - let args_with_type = func - .params() - .iter() - .map(|p| { - format!( - "{} {}", - self.type_generator.generate_type_decl(p.type_decl()), - p.name().to_case(Case::Camel) - ) - }) - .collect::>() - .join(", "); + let args = &encoded_fn_args(func.params()); + let args_with_type = &self.type_generator.fn_params_with_types(func.params()); let type_decls = func .params() @@ -92,17 +81,17 @@ impl<'a> Visitor<'a> for CtorFactoryGenerator<'a> { let action = &csharp::import("global::Sails.Remoting.Abstractions", "RemotingAction"); quote_in! { self.interface_tokens => - $activation $func_name_pascal($(&args_with_type));$['\r'] + $activation $func_name_pascal($args_with_type);$['\r'] }; quote_in! { self.class_tokens => - $(block_comment(vec![""])) - public $activation $func_name_pascal($(&args_with_type)) + $(inheritdoc()) + public $activation $func_name_pascal($args_with_type) { return new $action<$(&tuple_arg_type)>( this.remoting, [$route_bytes], - new $(&tuple_arg_type)($(&args))); + new $(&tuple_arg_type)($args)); } $['\n'] }; diff --git a/rs/client-gen-dotnet/src/events_generator.rs b/rs/client-gen-dotnet/src/events_generator.rs index 05831808..58399302 100644 --- a/rs/client-gen-dotnet/src/events_generator.rs +++ b/rs/client-gen-dotnet/src/events_generator.rs @@ -31,7 +31,12 @@ impl<'a> EventsGenerator<'a> { let listener_name = &format!("{}Listener", name); let system_buffer = &csharp::import("global::System", "Buffer"); - let listener = &csharp::import("global::Sails.Remoting.Abstractions", "IRemotingListener"); + let core_listener = &csharp::import( + "global::Sails.Remoting.Abstractions.Core", + "IRemotingListener", + ); + let service_listener = + &csharp::import("global::Sails.Remoting.Abstractions", "IRemotingListener"); quote! { public enum $enum_name @@ -47,22 +52,21 @@ impl<'a> EventsGenerator<'a> { } } $['\n'] - public partial class $listener_name : $listener<$class_name> + public partial class $listener_name : $service_listener<$class_name> { private static readonly byte[][] EventRoutes = [ $(self.listener_tokens) ]; - private readonly $listener remoting; + private readonly $core_listener remoting; - public $listener_name($listener remoting) + public $listener_name($core_listener remoting) { this.remoting = remoting; } - public async global::System.Collections.Generic.IAsyncEnumerable<$class_name> ListenAsync( - [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + public async global::System.Collections.Generic.IAsyncEnumerable<$class_name> ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) { diff --git a/rs/client-gen-dotnet/src/helpers.rs b/rs/client-gen-dotnet/src/helpers.rs index e7d24390..3f5f0bcf 100644 --- a/rs/client-gen-dotnet/src/helpers.rs +++ b/rs/client-gen-dotnet/src/helpers.rs @@ -25,7 +25,7 @@ pub(crate) fn path_bytes(path: &str) -> (String, usize) { pub(crate) fn encoded_fn_args(params: &[FuncParam]) -> String { params .iter() - .map(|a| a.name().to_case(convert_case::Case::Camel)) + .map(|p| escape_keywords(p.name().to_case(convert_case::Case::Camel))) .collect::>() .join(", ") } @@ -63,3 +63,105 @@ where tokens.push(); } } + +pub fn inheritdoc() -> InheritDoc { + InheritDoc +} + +pub struct InheritDoc; + +impl FormatInto for InheritDoc { + fn format_into(self, tokens: &mut Tokens) { + tokens.push(); + tokens.append(ItemStr::Static("/// ")); + tokens.push(); + } +} + +pub fn escape_keywords(name: String) -> String { + if RESERVED_KEYWORDS.contains(&name.as_str()) { + format!("@{name}") + } else { + name + } +} + +const RESERVED_KEYWORDS: &[&str] = &[ + "abstract", + "as", + "base", + "bool", + "break", + "byte", + "case", + "catch", + "char", + "checked", + "class", + "const", + "continue", + "decimal", + "default", + "delegate", + "do", + "double", + "else", + "enum", + "event", + "explicit", + "extern", + "false", + "finally", + "fixed", + "float", + "for", + "foreach", + "goto", + "if", + "implicit", + "in", + "int", + "interface", + "internal", + "is", + "lock", + "long", + "namespace", + "new", + "null", + "object", + "operator", + "out", + "override", + "params", + "private", + "protected", + "public", + "readonly", + "ref", + "return", + "sbyte", + "sealed", + "short", + "sizeof", + "stackalloc", + "static", + "string", + "struct", + "switch", + "this", + "throw", + "true", + "try", + "typeof", + "uint", + "ulong", + "unchecked", + "unsafe", + "ushort", + "using", + "virtual", + "void", + "volatile", + "while", +]; diff --git a/rs/client-gen-dotnet/src/root_generator.rs b/rs/client-gen-dotnet/src/root_generator.rs index 5c2e1bfc..812a9591 100644 --- a/rs/client-gen-dotnet/src/root_generator.rs +++ b/rs/client-gen-dotnet/src/root_generator.rs @@ -22,6 +22,11 @@ impl<'a> RootGenerator<'a> { "#pragma warning disable RCS0056 // A line is too long", )); tokens.line(); + tokens.append(format!( + "namespace {}.Client;", + anonymous_service_name.to_case(Case::Pascal) + )); + tokens.line(); Self { tokens, anonymous_service_name, diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/rs/client-gen-dotnet/src/service_generators.rs index 3132a610..fe431b60 100644 --- a/rs/client-gen-dotnet/src/service_generators.rs +++ b/rs/client-gen-dotnet/src/service_generators.rs @@ -1,6 +1,6 @@ use crate::{helpers::*, type_generators::TypeDeclGenerator}; use convert_case::{Case, Casing}; -use csharp::{block_comment, Tokens}; +use csharp::Tokens; use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; @@ -67,32 +67,18 @@ impl<'a> Visitor<'a> for ServiceClientGenerator<'a> { let route_bytes = [service_route_bytes, func_route_bytes].join(", "); let args = encoded_fn_args(func.params()); - let args_with_type = func - .params() - .iter() - .map(|p| { - format!( - "{} {}", - self.type_generator.generate_type_decl(p.type_decl()), - p.name().to_case(Case::Camel) - ) - }) - .collect::>() - .join(", "); - + let args_with_type = &self.type_generator.fn_params_with_types(func.params()); let func_return_type = &self.type_generator.generate_type_decl(func.output()); let action = &csharp::import("global::Sails.Remoting.Abstractions", "RemotingAction"); quote_in! { self.interface_tokens => - $return_type<$func_return_type> $func_name_pascal($['\r'] - $(&args_with_type));$['\r'] + $return_type<$func_return_type> $func_name_pascal($args_with_type);$['\r'] }; quote_in! { self.class_tokens => - $(block_comment(vec![""])) - public $return_type<$func_return_type> $func_name_pascal($['\r'] - $(&args_with_type)) + $(inheritdoc()) + public $return_type<$func_return_type> $func_name_pascal($args_with_type) { return new $action<$func_return_type>( this.remoting, diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/rs/client-gen-dotnet/src/type_generators.rs index f1dd7784..5962bdb5 100644 --- a/rs/client-gen-dotnet/src/type_generators.rs +++ b/rs/client-gen-dotnet/src/type_generators.rs @@ -1,6 +1,6 @@ use crate::helpers::*; use convert_case::{Case, Casing}; -use csharp::{block_comment, Tokens}; +use csharp::Tokens; use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; @@ -112,10 +112,10 @@ impl<'a> StructDefGenerator<'a> { { $(self.props_tokens) - $(block_comment(vec![""])) + $(inheritdoc()) public override string TypeName() => $(quoted(self.type_name)); - $(block_comment(vec![""])) + $(inheritdoc()) public override byte[] Encode() { var result = new $generic_list(); @@ -123,7 +123,7 @@ impl<'a> StructDefGenerator<'a> { return result.ToArray(); } - $(block_comment(vec![""])) + $(inheritdoc()) public override void Decode(byte[] byteArray, ref int p) { var start = p; @@ -143,7 +143,8 @@ impl<'a> StructDefGenerator<'a> { } let value_type = self.type_generator.generate_struct_def(struct_def); quote_in! { self.props_tokens => - public required $(&value_type) Value { get; set; }$['\r'] + [System.Diagnostics.CodeAnalysis.AllowNull]$['\r'] + public $(&value_type) Value { get; set; }$['\r'] }; quote_in! { self.encode_tokens => result.AddRange(this.Value.Encode());$['\r'] @@ -183,7 +184,8 @@ impl<'a> Visitor<'a> for StructDefGenerator<'a> { if let Some(field_name) = struct_field.name() { let field_name_pascal = field_name.to_case(Case::Pascal); quote_in! { self.props_tokens => - public required $(&type_decl_code) $(&field_name_pascal) { get; set; }$['\r'] + [System.Diagnostics.CodeAnalysis.AllowNull]$['\r'] + public $(&type_decl_code) $(&field_name_pascal) { get; set; }$['\r'] }; quote_in! { self.encode_tokens => result.AddRange(this.$(&field_name_pascal).Encode());$['\r'] @@ -301,6 +303,20 @@ impl<'a> TypeDeclGenerator<'a> { _ = std::mem::replace(&mut self.code, prev_code); self.code.push_str(type_decls_str.join(separator).as_str()); } + + pub(crate) fn fn_params_with_types(&mut self, params: &'a [FuncParam]) -> String { + params + .iter() + .map(|p| { + format!( + "{} {}", + self.generate_type_decl(p.type_decl()), + escape_keywords(p.name().to_case(convert_case::Case::Camel)) + ) + }) + .collect::>() + .join(", ") + } } impl<'a> Visitor<'a> for TypeDeclGenerator<'a> { diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap index 6d9a7755..1d7464fb 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap @@ -8,12 +8,12 @@ using global::System.Collections.Generic; #pragma warning disable RCS0056 // A line is too long +namespace Basic.Client; + public interface IBasic { - global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); - global::Sails.Remoting.Abstractions.ICall DoThat( - global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); + global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); + global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } public partial class Basic : IBasic @@ -26,8 +26,7 @@ public partial class Basic : IBasic } /// - public global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, @@ -36,8 +35,7 @@ public partial class Basic : IBasic ); } /// - public global::Sails.Remoting.Abstractions.ICall DoThat( - global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) + public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, @@ -50,9 +48,12 @@ public partial class Basic : IBasic [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType { - public required global::Substrate.NetApi.Model.Types.Primitive.U32 F1 { get; set; } - public required global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } - public required global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.U32 F1 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } /// public override string TypeName() => "MyParam"; diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap index df278a23..c622f52f 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap @@ -8,10 +8,11 @@ using global::System.Collections.Generic; #pragma warning disable RCS0056 // A line is too long +namespace ServiceWithEvents.Client; + public interface IServiceWithEvents { - global::Sails.Remoting.Abstractions.ICall DoThis( - NonZeroU256 p1, MyParam p2); + global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); } public partial class ServiceWithEvents : IServiceWithEvents @@ -24,10 +25,9 @@ public partial class ServiceWithEvents : IServiceWithEvents } /// - public global::Sails.Remoting.Abstractions.ICall DoThis( - NonZeroU256 p1, MyParam p2) + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) { - return new RemotingAction( + return new RemotingAction( this.remoting, [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) @@ -64,15 +64,14 @@ public partial class ServiceWithEventsListener : IRemotingListener ListenAsync( - [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) { @@ -104,9 +103,12 @@ public partial class ServiceWithEventsListener : IRemotingListener F2 { get; set; } - public required global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 F1 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } /// public override string TypeName() => "MyParam"; @@ -125,11 +127,11 @@ public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base. public override void Decode(byte[] byteArray, ref int p) { var start = p; - this.F1 = new NonZeroU256(); + this.F1 = new global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256(); this.F1.Decode(byteArray, ref p); - this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); this.F2.Decode(byteArray, ref p); - this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); + this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); this.F3.Decode(byteArray, ref p); var bytesLength = p - start; this.TypeSize = bytesLength; diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap index 5f95629e..12192430 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap @@ -6,12 +6,12 @@ using global::Sails.Remoting.Abstractions; #pragma warning disable RCS0056 // A line is too long +namespace Service.Client; + public interface IService { - global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); - global::Sails.Remoting.Abstractions.ICall DoThat( - global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); + global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); + global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } public partial class Service : IService @@ -24,8 +24,7 @@ public partial class Service : IService } /// - public global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, @@ -34,8 +33,7 @@ public partial class Service : IService ); } /// - public global::Sails.Remoting.Abstractions.ICall DoThat( - global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) + public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap index 20d4a6c6..b9113fc4 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -8,6 +8,8 @@ using global::System.Collections.Generic; #pragma warning disable RCS0056 // A line is too long +namespace Service.Client; + public interface IServiceFactory { /// @@ -37,14 +39,10 @@ public partial class ServiceFactory : IServiceFactory public interface IService { - global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); - global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( - ThisThatSvcAppDoThatParam param); - global::Sails.Remoting.Abstractions.IQuery This( - global::Substrate.NetApi.Model.Types.Base.BaseVec v1); - global::Sails.Remoting.Abstractions.IQuery> That( - global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); + global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); + global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); + global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); + global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); } public partial class Service : IService @@ -57,8 +55,7 @@ public partial class Service : IService } /// - public global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) + public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, @@ -67,18 +64,16 @@ public partial class Service : IService ); } /// - public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( - ThisThatSvcAppDoThatParam param) + public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) { - return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( + return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } /// - public global::Sails.Remoting.Abstractions.IQuery This( - global::Substrate.NetApi.Model.Types.Base.BaseVec v1) + public global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) { return new RemotingAction( this.remoting, @@ -87,10 +82,9 @@ public partial class Service : IService ); } /// - public global::Sails.Remoting.Abstractions.IQuery> That( - global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) + public global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) { - return new RemotingAction>( + return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) @@ -127,15 +121,14 @@ public partial class ServiceListener : IRemotingListener [28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 97, 116, 68, 111, 110, 101], ]; - private readonly IRemotingListener remoting; + private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; - public ServiceListener(IRemotingListener remoting) + public ServiceListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) { this.remoting = remoting; } - public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync( - [global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) { @@ -170,7 +163,8 @@ public partial class ServiceListener : IRemotingListener [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { - public required global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } /// public override string TypeName() => "ThisThatSvcAppTupleStruct"; @@ -205,15 +199,18 @@ public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi /// /// field `query` /// - public required global::Substrate.NetApi.Model.Types.Primitive.U32 Query { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.U32 Query { get; set; } /// /// field `result` /// - public required global::Substrate.NetApi.Model.Types.Primitive.Str Result { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Str Result { get; set; } /// /// field `p3` /// - public required EnumThisThatSvcAppManyVariants P3 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public EnumThisThatSvcAppManyVariants P3 { get; set; } /// public override string TypeName() => "ThisThatSvcAppDoThatParam"; diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap index 8f48ace9..403fb6b4 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -8,6 +8,8 @@ using global::System.Collections.Generic; #pragma warning disable RCS0056 // A line is too long +namespace Service.Client; + public interface IServiceFactory { IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); @@ -34,14 +36,10 @@ public partial class ServiceFactory : IServiceFactory public interface IService { - global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); - global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( - ThisThatSvcAppDoThatParam param); - global::Sails.Remoting.Abstractions.IQuery This( - global::Substrate.NetApi.Model.Types.Base.BaseVec v1); - global::Sails.Remoting.Abstractions.IQuery> That( - global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); + global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); + global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); + global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); + global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); } public partial class Service : IService @@ -54,8 +52,7 @@ public partial class Service : IService } /// - public global::Sails.Remoting.Abstractions.ICall> DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) + public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, @@ -64,18 +61,16 @@ public partial class Service : IService ); } /// - public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat( - ThisThatSvcAppDoThatParam param) + public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) { - return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( + return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } /// - public global::Sails.Remoting.Abstractions.IQuery This( - global::Substrate.NetApi.Model.Types.Base.BaseVec v1) + public global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) { return new RemotingAction( this.remoting, @@ -84,10 +79,9 @@ public partial class Service : IService ); } /// - public global::Sails.Remoting.Abstractions.IQuery> That( - global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) + public global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) { - return new RemotingAction>( + return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) @@ -98,7 +92,8 @@ public partial class Service : IService [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { - public required global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } /// public override string TypeName() => "ThisThatSvcAppTupleStruct"; @@ -127,9 +122,12 @@ public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType { - public required global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } - public required global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } - public required EnumThisThatSvcAppManyVariants P3 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public EnumThisThatSvcAppManyVariants P3 { get; set; } /// public override string TypeName() => "ThisThatSvcAppDoThatParam"; diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap index e3b4a5ef..a3517909 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap @@ -6,12 +6,12 @@ using global::Sails.Remoting.Abstractions; #pragma warning disable RCS0056 // A line is too long +namespace Multiple.Client; + public interface IMultiple { - global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); - global::Sails.Remoting.Abstractions.ICall DoThat( - global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); + global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); + global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } public partial class Multiple : IMultiple @@ -24,8 +24,7 @@ public partial class Multiple : IMultiple } /// - public global::Sails.Remoting.Abstractions.ICall DoThis( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, @@ -34,8 +33,7 @@ public partial class Multiple : IMultiple ); } /// - public global::Sails.Remoting.Abstractions.ICall DoThat( - global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) + public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, @@ -47,8 +45,7 @@ public partial class Multiple : IMultiple public interface INamed { - global::Sails.Remoting.Abstractions.IQuery That( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1); + global::Sails.Remoting.Abstractions.IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1); } public partial class Named : INamed @@ -61,8 +58,7 @@ public partial class Named : INamed } /// - public global::Sails.Remoting.Abstractions.IQuery That( - global::Substrate.NetApi.Model.Types.Primitive.U32 p1) + public global::Sails.Remoting.Abstractions.IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1) { return new RemotingAction( this.remoting, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap index 228dfef6..db3fdcd5 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap @@ -8,10 +8,11 @@ using global::System.Collections.Generic; #pragma warning disable RCS0056 // A line is too long +namespace NonZeroParams.Client; + public interface INonZeroParams { - global::Sails.Remoting.Abstractions.ICall DoThis( - NonZeroU256 p1, MyParam p2); + global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); } public partial class NonZeroParams : INonZeroParams @@ -24,10 +25,9 @@ public partial class NonZeroParams : INonZeroParams } /// - public global::Sails.Remoting.Abstractions.ICall DoThis( - NonZeroU256 p1, MyParam p2) + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) { - return new RemotingAction( + return new RemotingAction( this.remoting, [52, 78, 111, 110, 90, 101, 114, 111, 80, 97, 114, 97, 109, 115, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) @@ -38,9 +38,12 @@ public partial class NonZeroParams : INonZeroParams [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType { - public required NonZeroU256 F1 { get; set; } - public required global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } - public required global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 F1 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } /// public override string TypeName() => "MyParam"; @@ -59,11 +62,11 @@ public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base. public override void Decode(byte[] byteArray, ref int p) { var start = p; - this.F1 = new NonZeroU256(); + this.F1 = new global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256(); this.F1.Decode(byteArray, ref p); - this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); this.F2.Decode(byteArray, ref p); - this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); + this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); this.F3.Decode(byteArray, ref p); var bytesLength = p - start; this.TypeSize = bytesLength; diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap index b35fc5cd..bddc8331 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap @@ -8,6 +8,8 @@ using global::System.Collections.Generic; #pragma warning disable RCS0056 // A line is too long +namespace RmrkCatalog.Client; + public interface IRmrkCatalogFactory { IActivation New(); @@ -34,22 +36,14 @@ public partial class RmrkCatalogFactory : IRmrkCatalogFactory public interface IRmrkCatalog { - global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds); - global::Sails.Remoting.Abstractions.ICall, Error>> AddParts( - BTreeMap parts); - global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); - global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts( - global::Substrate.NetApi.Model.Types.Base.BaseVec partIds); - global::Sails.Remoting.Abstractions.ICall> ResetEquippables( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId); - global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId); - global::Sails.Remoting.Abstractions.IQuery> Equippable( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); - global::Sails.Remoting.Abstractions.IQuery> Part( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId); + global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds); + global::Sails.Remoting.Abstractions.ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts); + global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); + global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds); + global::Sails.Remoting.Abstractions.ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); + global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); + global::Sails.Remoting.Abstractions.IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); + global::Sails.Remoting.Abstractions.IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); } public partial class RmrkCatalog : IRmrkCatalog @@ -62,78 +56,70 @@ public partial class RmrkCatalog : IRmrkCatalog } /// - public global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds) + public global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds) { - return new RemotingAction>, Error>>( + return new RemotingAction>, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 56, 65, 100, 100, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionIds) ); } /// - public global::Sails.Remoting.Abstractions.ICall, Error>> AddParts( - BTreeMap parts) + public global::Sails.Remoting.Abstractions.ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts) { - return new RemotingAction, Error>>( + return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 32, 65, 100, 100, 80, 97, 114, 116, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(parts) ); } /// - public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) + public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { - return new RemotingAction, Error>>( + return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 109, 111, 118, 101, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) ); } /// - public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts( - global::Substrate.NetApi.Model.Types.Base.BaseVec partIds) + public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds) { - return new RemotingAction, Error>>( + return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 44, 82, 101, 109, 111, 118, 101, 80, 97, 114, 116, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partIds) ); } /// - public global::Sails.Remoting.Abstractions.ICall> ResetEquippables( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId) + public global::Sails.Remoting.Abstractions.ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { - return new RemotingAction>( + return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 115, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } /// - public global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId) + public global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { - return new RemotingAction>( + return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 76, 83, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115, 84, 111, 65, 108, 108], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> Equippable( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) + public global::Sails.Remoting.Abstractions.IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { - return new RemotingAction>( + return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 40, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> Part( - global::Substrate.NetApi.Model.Types.Primitive.U32 partId) + public global::Sails.Remoting.Abstractions.IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, @@ -191,11 +177,13 @@ public sealed partial class FixedPart : global::Substrate.NetApi.Model.Types.Bas /// specifies the stack order of an element. /// An element with greater stack order is always in front of an element with a lower stack order. /// - public required global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } /// /// The metadata URI of the part. /// - public required global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } /// public override string TypeName() => "FixedPart"; @@ -230,17 +218,20 @@ public sealed partial class SlotPart : global::Substrate.NetApi.Model.Types.Base /// /// Array of whitelisted collections that can be equipped in the given slot. Used with slot parts only. /// - public required global::Substrate.NetApi.Model.Types.Base.BaseVec Equippable { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseVec Equippable { get; set; } /// /// An optional zIndex of base part layer. /// specifies the stack order of an element. /// An element with greater stack order is always in front of an element with a lower stack order. /// - public required global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } /// /// The metadata URI of the part. /// - public required global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } /// public override string TypeName() => "SlotPart"; From 8e76c2467c870e3dfd856817df734db9641c8f26 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 5 Nov 2024 14:43:25 +0100 Subject: [PATCH 15/54] remove nigtly build, add code format --- .../Sails.ClientGenerator.csproj | 2 +- .../SailsClientGenerator.cs | 12 +- ...rTests.Generate_DemoIdl#demo.g.verified.cs | 203 +++------- rs/client-gen-dotnet/src/ctor_generators.rs | 4 +- rs/client-gen-dotnet/src/events_generator.rs | 8 +- .../src/service_generators.rs | 4 +- .../snapshots/generator__basic_works.snap | 142 +++---- .../snapshots/generator__events_works.snap | 181 +++------ .../snapshots/generator__external_types.snap | 79 ++-- .../tests/snapshots/generator__full.snap | 370 ++++++------------ .../generator__full_with_sails_path.snap | 269 +++++-------- .../generator__multiple_services.snap | 67 +--- .../snapshots/generator__nonzero_works.snap | 96 ++--- .../snapshots/generator__rmrk_works.snap | 370 ++++++------------ 14 files changed, 578 insertions(+), 1229 deletions(-) diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 4b4d9201..a5757602 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -39,7 +39,7 @@ - + diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 9396d5cd..8cbd213d 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -1,5 +1,6 @@ using System.Text; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; namespace Sails.ClientGenerator; @@ -30,7 +31,8 @@ private static unsafe void Generate(SourceProductionContext context, AdditionalT try { var str = new string((sbyte*)cstr); - context.AddSource($"{name}.g.cs", SourceText.From(str, encoding: Encoding.UTF8)); + var formatted = FormatCode(str); + context.AddSource($"{name}.g.cs", SourceText.From(formatted, encoding: Encoding.UTF8)); } finally { @@ -39,4 +41,12 @@ private static unsafe void Generate(SourceProductionContext context, AdditionalT } } } + + public static string FormatCode(string code, CancellationToken cancelToken = default) + => CSharpSyntaxTree.ParseText(code, cancellationToken: cancelToken) + .GetRoot(cancelToken) + .NormalizeWhitespace() + .SyntaxTree + .GetText(cancelToken) + .ToString(); } diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs index b37e9745..4427fd3f 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs @@ -6,7 +6,6 @@ #pragma warning disable RCS0056 // A line is too long namespace Demo.Client; - public interface IDemoFactory { /// @@ -22,7 +21,6 @@ public interface IDemoFactory public partial class DemoFactory : IDemoFactory { private readonly IRemoting remoting; - public DemoFactory(IRemoting remoting) { this.remoting = remoting; @@ -31,19 +29,13 @@ public DemoFactory(IRemoting remoting) /// public IActivation Default() { - return new RemotingAction( - this.remoting, - [28, 68, 101, 102, 97, 117, 108, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseVoid()); + return new RemotingAction(this.remoting, [28, 68, 101, 102, 97, 117, 108, 116], new global::Substrate.NetApi.Model.Types.Base.BaseVoid()); } /// public IActivation New(global::Substrate.NetApi.Model.Types.Base.BaseOpt counter, global::Substrate.NetApi.Model.Types.Base.BaseOpt> dogPosition) { - return new RemotingAction, global::Substrate.NetApi.Model.Types.Base.BaseOpt>>>( - this.remoting, - [12, 78, 101, 119], - new global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Base.BaseOpt>>(counter, dogPosition)); + return new RemotingAction, global::Substrate.NetApi.Model.Types.Base.BaseOpt>>>(this.remoting, [12, 78, 101, 119], new global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Base.BaseOpt>>(counter, dogPosition)); } } @@ -57,7 +49,6 @@ public interface ICounter public partial class Counter : ICounter { private readonly IRemoting remoting; - public Counter(IRemoting remoting) { this.remoting = remoting; @@ -66,29 +57,19 @@ public Counter(IRemoting remoting) /// public global::Sails.Remoting.Abstractions.ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 value) { - return new RemotingAction( - this.remoting, - [28, 67, 111, 117, 110, 116, 101, 114, 12, 65, 100, 100], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(value) - ); + return new RemotingAction(this.remoting, [28, 67, 111, 117, 110, 116, 101, 114, 12, 65, 100, 100], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(value)); } + /// public global::Sails.Remoting.Abstractions.ICall Sub(global::Substrate.NetApi.Model.Types.Primitive.U32 value) { - return new RemotingAction( - this.remoting, - [28, 67, 111, 117, 110, 116, 101, 114, 12, 83, 117, 98], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(value) - ); + return new RemotingAction(this.remoting, [28, 67, 111, 117, 110, 116, 101, 114, 12, 83, 117, 98], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(value)); } + /// public global::Sails.Remoting.Abstractions.IQuery Value() { - return new RemotingAction( - this.remoting, - [28, 67, 111, 117, 110, 116, 101, 114, 20, 86, 97, 108, 117, 101], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction(this.remoting, [28, 67, 111, 117, 110, 116, 101, 114, 20, 86, 97, 108, 117, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } } @@ -115,14 +96,8 @@ public EnumCounterEvents() public partial class CounterListener : IRemotingListener { - private static readonly byte[][] EventRoutes = - [ - [28, 67, 111, 117, 110, 116, 101, 114, 20, 65, 100, 100, 101, 100], - [28, 67, 111, 117, 110, 116, 101, 114, 40, 83, 117, 98, 116, 114, 97, 99, 116, 101, 100], - ]; - + private static readonly byte[][] EventRoutes = [[28, 67, 111, 117, 110, 116, 101, 114, 20, 65, 100, 100, 101, 100], [28, 67, 111, 117, 110, 116, 101, 114, 40, 83, 117, 98, 116, 114, 97, 99, 116, 101, 100], ]; private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; - public CounterListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) { this.remoting = remoting; @@ -139,18 +114,19 @@ public CounterListener(global::Sails.Remoting.Abstractions.Core.IRemotingListene { continue; } + if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) { var bytesLength = bytes.Length - route.Length + 1; var data = new byte[bytesLength]; data[0] = idx; Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); - var p = 0; EnumCounterEvents ev = new(); ev.Decode(bytes, ref p); yield return ev; } + idx++; } } @@ -168,7 +144,6 @@ public interface IDog public partial class Dog : IDog { private readonly IRemoting remoting; - public Dog(IRemoting remoting) { this.remoting = remoting; @@ -177,38 +152,25 @@ public Dog(IRemoting remoting) /// public global::Sails.Remoting.Abstractions.ICall MakeSound() { - return new RemotingAction( - this.remoting, - [12, 68, 111, 103, 36, 77, 97, 107, 101, 83, 111, 117, 110, 100], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction(this.remoting, [12, 68, 111, 103, 36, 77, 97, 107, 101, 83, 111, 117, 110, 100], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } + /// public global::Sails.Remoting.Abstractions.ICall Walk(global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy) { - return new RemotingAction( - this.remoting, - [12, 68, 111, 103, 16, 87, 97, 108, 107], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(dx, dy) - ); + return new RemotingAction(this.remoting, [12, 68, 111, 103, 16, 87, 97, 108, 107], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(dx, dy)); } + /// public global::Sails.Remoting.Abstractions.IQuery AvgWeight() { - return new RemotingAction( - this.remoting, - [12, 68, 111, 103, 36, 65, 118, 103, 87, 101, 105, 103, 104, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction(this.remoting, [12, 68, 111, 103, 36, 65, 118, 103, 87, 101, 105, 103, 104, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } + /// public global::Sails.Remoting.Abstractions.IQuery> Position() { - return new RemotingAction>( - this.remoting, - [12, 68, 111, 103, 32, 80, 111, 115, 105, 116, 105, 111, 110], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction>(this.remoting, [12, 68, 111, 103, 32, 80, 111, 115, 105, 116, 105, 111, 110], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } } @@ -229,14 +191,8 @@ public EnumDogEvents() public partial class DogListener : IRemotingListener { - private static readonly byte[][] EventRoutes = - [ - [12, 68, 111, 103, 24, 66, 97, 114, 107, 101, 100], - [12, 68, 111, 103, 24, 87, 97, 108, 107, 101, 100], - ]; - + private static readonly byte[][] EventRoutes = [[12, 68, 111, 103, 24, 66, 97, 114, 107, 101, 100], [12, 68, 111, 103, 24, 87, 97, 108, 107, 101, 100], ]; private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; - public DogListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) { this.remoting = remoting; @@ -253,18 +209,19 @@ public DogListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener re { continue; } + if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) { var bytesLength = bytes.Length - route.Length + 1; var data = new byte[bytesLength]; data[0] = idx; Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); - var p = 0; EnumDogEvents ev = new(); ev.Decode(bytes, ref p); yield return ev; } + idx++; } } @@ -279,7 +236,6 @@ public interface IPingPong public partial class PingPong : IPingPong { private readonly IRemoting remoting; - public PingPong(IRemoting remoting) { this.remoting = remoting; @@ -288,11 +244,7 @@ public PingPong(IRemoting remoting) /// public global::Sails.Remoting.Abstractions.ICall> Ping(global::Substrate.NetApi.Model.Types.Primitive.Str input) { - return new RemotingAction>( - this.remoting, - [32, 80, 105, 110, 103, 80, 111, 110, 103, 16, 80, 105, 110, 103], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(input) - ); + return new RemotingAction>(this.remoting, [32, 80, 105, 110, 103, 80, 111, 110, 103, 16, 80, 105, 110, 103], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(input)); } } @@ -311,7 +263,6 @@ public interface IReferences public partial class References : IReferences { private readonly IRemoting remoting; - public References(IRemoting remoting) { this.remoting = remoting; @@ -320,74 +271,49 @@ public References(IRemoting remoting) /// public global::Sails.Remoting.Abstractions.ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 v) { - return new RemotingAction( - this.remoting, - [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 12, 65, 100, 100], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v) - ); + return new RemotingAction(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 12, 65, 100, 100], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v)); } + /// public global::Sails.Remoting.Abstractions.ICall> AddByte(global::Substrate.NetApi.Model.Types.Primitive.U8 @byte) { - return new RemotingAction>( - this.remoting, - [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 28, 65, 100, 100, 66, 121, 116, 101], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(@byte) - ); + return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 28, 65, 100, 100, 66, 121, 116, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(@byte)); } + /// public global::Sails.Remoting.Abstractions.ICall> GuessNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number) { - return new RemotingAction>( - this.remoting, - [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 32, 71, 117, 101, 115, 115, 78, 117, 109], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number) - ); + return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 32, 71, 117, 101, 115, 115, 78, 117, 109], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number)); } + /// public global::Sails.Remoting.Abstractions.ICall Incr() { - return new RemotingAction( - this.remoting, - [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 16, 73, 110, 99, 114], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 16, 73, 110, 99, 114], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } + /// public global::Sails.Remoting.Abstractions.ICall> SetNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number) { - return new RemotingAction>( - this.remoting, - [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 24, 83, 101, 116, 78, 117, 109], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number) - ); + return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 24, 83, 101, 116, 78, 117, 109], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number)); } + /// public global::Sails.Remoting.Abstractions.IQuery Baked() { - return new RemotingAction( - this.remoting, - [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 20, 66, 97, 107, 101, 100], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 20, 66, 97, 107, 101, 100], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } + /// public global::Sails.Remoting.Abstractions.IQuery> LastByte() { - return new RemotingAction>( - this.remoting, - [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 32, 76, 97, 115, 116, 66, 121, 116, 101], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 32, 76, 97, 115, 116, 66, 121, 116, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } + /// public global::Sails.Remoting.Abstractions.IQuery> Message() { - return new RemotingAction>( - this.remoting, - [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 28, 77, 101, 115, 115, 97, 103, 101], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 28, 77, 101, 115, 115, 97, 103, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } } @@ -403,7 +329,6 @@ public interface IThisThat public partial class ThisThat : IThisThat { private readonly IRemoting remoting; - public ThisThat(IRemoting remoting) { this.remoting = remoting; @@ -412,47 +337,31 @@ public ThisThat(IRemoting remoting) /// public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(DoThatParam param) { - return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( - this.remoting, - [32, 84, 104, 105, 115, 84, 104, 97, 116, 24, 68, 111, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) - ); + return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param)); } + /// public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU8> p3, TupleStruct p4) { - return new RemotingAction>( - this.remoting, - [32, 84, 104, 105, 115, 84, 104, 97, 116, 24, 68, 111, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) - ); + return new RemotingAction>(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4)); } + /// public global::Sails.Remoting.Abstractions.ICall Noop() { - return new RemotingAction( - this.remoting, - [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 78, 111, 111, 112], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 78, 111, 111, 112], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } + /// public global::Sails.Remoting.Abstractions.IQuery> That() { - return new RemotingAction>( - this.remoting, - [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction>(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } + /// public global::Sails.Remoting.Abstractions.IQuery This() { - return new RemotingAction( - this.remoting, - [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } } @@ -464,7 +373,6 @@ public interface IValueFee public partial class ValueFee : IValueFee { private readonly IRemoting remoting; - public ValueFee(IRemoting remoting) { this.remoting = remoting; @@ -473,11 +381,7 @@ public ValueFee(IRemoting remoting) /// public global::Sails.Remoting.Abstractions.ICall DoSomethingAndTakeFee() { - return new RemotingAction( - this.remoting, - [32, 86, 97, 108, 117, 101, 70, 101, 101, 84, 68, 111, 83, 111, 109, 101, 116, 104, 105, 110, 103, 65, 110, 100, 84, 97, 107, 101, 70, 101, 101], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust() - ); + return new RemotingAction(this.remoting, [32, 86, 97, 108, 117, 101, 70, 101, 101, 84, 68, 111, 83, 111, 109, 101, 116, 104, 105, 110, 103, 65, 110, 100, 84, 97, 107, 101, 70, 101, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } } @@ -496,13 +400,8 @@ public EnumValueFeeEvents() public partial class ValueFeeListener : IRemotingListener { - private static readonly byte[][] EventRoutes = - [ - [32, 86, 97, 108, 117, 101, 70, 101, 101, 32, 87, 105, 116, 104, 104, 101, 108, 100], - ]; - + private static readonly byte[][] EventRoutes = [[32, 86, 97, 108, 117, 101, 70, 101, 101, 32, 87, 105, 116, 104, 104, 101, 108, 100], ]; private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; - public ValueFeeListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) { this.remoting = remoting; @@ -519,18 +418,19 @@ public ValueFeeListener(global::Sails.Remoting.Abstractions.Core.IRemotingListen { continue; } + if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) { var bytesLength = bytes.Length - route.Length + 1; var data = new byte[bytesLength]; data[0] = idx; Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); - var p = 0; EnumValueFeeEvents ev = new(); ev.Decode(bytes, ref p); yield return ev; } + idx++; } } @@ -545,7 +445,6 @@ public sealed partial class ReferenceCount : global::Substrate.NetApi.Model.Type /// public override string TypeName() => "ReferenceCount"; - /// public override byte[] Encode() { @@ -572,14 +471,15 @@ public sealed partial class DoThatParam : global::Substrate.NetApi.Model.Types.B { [System.Diagnostics.CodeAnalysis.AllowNull] public global::Substrate.Gear.Api.Generated.Types.Base.NonZeroU32 P1 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] public global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId P2 { get; set; } + [System.Diagnostics.CodeAnalysis.AllowNull] public EnumManyVariants P3 { get; set; } /// public override string TypeName() => "DoThatParam"; - /// public override byte[] Encode() { @@ -638,7 +538,6 @@ public sealed partial class TupleStruct : global::Substrate.NetApi.Model.Types.B /// public override string TypeName() => "TupleStruct"; - /// public override byte[] Encode() { diff --git a/rs/client-gen-dotnet/src/ctor_generators.rs b/rs/client-gen-dotnet/src/ctor_generators.rs index df0af12e..6f5110a4 100644 --- a/rs/client-gen-dotnet/src/ctor_generators.rs +++ b/rs/client-gen-dotnet/src/ctor_generators.rs @@ -29,13 +29,13 @@ impl<'a> CtorFactoryGenerator<'a> { let remoting = &csharp::import("global::Sails.Remoting.Abstractions", "IRemoting"); quote! { - public interface I$(&class_name) + public interface I$(&class_name)$['\r'] { $(self.interface_tokens) } $['\n'] public partial class $(&class_name) : I$(&class_name)$['\r'] - { + {$['\n'] private readonly $remoting remoting; $['\n'] public $(&class_name)($remoting remoting)$['\r'] diff --git a/rs/client-gen-dotnet/src/events_generator.rs b/rs/client-gen-dotnet/src/events_generator.rs index 58399302..2d169813 100644 --- a/rs/client-gen-dotnet/src/events_generator.rs +++ b/rs/client-gen-dotnet/src/events_generator.rs @@ -58,14 +58,14 @@ impl<'a> EventsGenerator<'a> { [ $(self.listener_tokens) ]; - + $['\n'] private readonly $core_listener remoting; - + $['\n'] public $listener_name($core_listener remoting) { this.remoting = remoting; } - + $['\n'] public async global::System.Collections.Generic.IAsyncEnumerable<$class_name> ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) @@ -111,7 +111,7 @@ impl<'a> Visitor<'a> for EventsGenerator<'a> { let route_bytes = [service_route_bytes, event_route_bytes].join(", "); quote_in! { self.listener_tokens => - [$(&route_bytes)],$['\r'] + [$(&route_bytes)], }; quote_in! { self.enum_tokens => diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/rs/client-gen-dotnet/src/service_generators.rs index fe431b60..5ccd2aea 100644 --- a/rs/client-gen-dotnet/src/service_generators.rs +++ b/rs/client-gen-dotnet/src/service_generators.rs @@ -39,12 +39,12 @@ impl<'a> ServiceClientGenerator<'a> { public partial class $name : I$name$['\r'] { private readonly $remoting remoting; - + $['\n'] public $name($remoting remoting) { this.remoting = remoting; } - + $['\n'] $(self.class_tokens) } $['\n'] diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap index 1d7464fb..c5ed5982 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap @@ -11,97 +11,51 @@ using global::System.Collections.Generic; namespace Basic.Client; public interface IBasic -{ - global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); - global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); -} - -public partial class Basic : IBasic -{ - private readonly IRemoting remoting; - - public Basic(IRemoting remoting) - { - this.remoting = remoting; - } - - /// - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) - { - return new RemotingAction( - this.remoting, - [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) - { - return new RemotingAction( - this.remoting, - [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) - ); - } -} - -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.U32 F1 { get; set; } - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } - - /// - public override string TypeName() => "MyParam"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(this.F1.Encode()); - result.AddRange(this.F2.Encode()); - result.AddRange(this.F3.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - this.F1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); - this.F1.Decode(byteArray, ref p); - this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); - this.F2.Decode(byteArray, ref p); - this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); - this.F3.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); - } -} - -public enum MyParam2 -{ - Variant1, - Variant2, - Variant3, - Variant4, - Variant5, -} - -public sealed partial class EnumMyParam2 : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumMyParam2() - { - this.AddTypeDecoder(MyParam2.Variant1); - this.AddTypeDecoder(MyParam2.Variant2); - this.AddTypeDecoder(MyParam2.Variant3); - this.AddTypeDecoder>(MyParam2.Variant4); - this.AddTypeDecoder>>(MyParam2.Variant5); - } -} + { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); +global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); + } + + public partial class Basic : IBasic + { private readonly IRemoting remoting; + + public Basic(IRemoting remoting) { this.remoting = remoting; } + +/// + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } +/// + public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType { +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.U32 F1 { get; set; } +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } +/// + public override string TypeName() => "MyParam"; +/// + public override byte[] Encode() { var result = new List(); result.AddRange(this.F1.Encode()); +result.AddRange(this.F2.Encode()); +result.AddRange(this.F3.Encode()); + return result.ToArray(); } +/// + public override void Decode(byte[] byteArray, ref int p) { var start = p; this.F1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + this.F1.Decode(byteArray, ref p); +this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.F2.Decode(byteArray, ref p); +this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); + this.F3.Decode(byteArray, ref p); + var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } + +public enum MyParam2 { Variant1, + Variant2, + Variant3, + Variant4, + Variant5, + } public sealed partial class EnumMyParam2 : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumMyParam2() { this.AddTypeDecoder(MyParam2.Variant1); +this.AddTypeDecoder(MyParam2.Variant2); +this.AddTypeDecoder(MyParam2.Variant3); +this.AddTypeDecoder>(MyParam2.Variant4); +this.AddTypeDecoder>>(MyParam2.Variant5); + } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap index c622f52f..35c39780 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap @@ -11,131 +11,56 @@ using global::System.Collections.Generic; namespace ServiceWithEvents.Client; public interface IServiceWithEvents -{ - global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); -} - -public partial class ServiceWithEvents : IServiceWithEvents -{ - private readonly IRemoting remoting; - - public ServiceWithEvents(IRemoting remoting) - { - this.remoting = remoting; - } - - /// - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) - { - return new RemotingAction( - this.remoting, - [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 24, 68, 111, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) - ); - } -} - -public enum ServiceWithEventsEvents -{ - One, - Two, - Three, - Reset, -} - -public sealed partial class EnumServiceWithEventsEvents : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumServiceWithEventsEvents() - { - this.AddTypeDecoder(ServiceWithEventsEvents.One); - this.AddTypeDecoder>(ServiceWithEventsEvents.Two); - this.AddTypeDecoder(ServiceWithEventsEvents.Three); - this.AddTypeDecoder(ServiceWithEventsEvents.Reset); - } -} - -public partial class ServiceWithEventsListener : IRemotingListener -{ - private static readonly byte[][] EventRoutes = - [ - [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 79, 110, 101], - [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 84, 119, 111], - [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 84, 104, 114, 101, 101], - [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 82, 101, 115, 101, 116], - ]; - - private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; - - public ServiceWithEventsListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) - { - this.remoting = remoting; - } - - public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) - { - await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) - { - byte idx = 0; - foreach (var route in EventRoutes) - { - if (route.Length > bytes.Length) - { - continue; - } - if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) - { - var bytesLength = bytes.Length - route.Length + 1; - var data = new byte[bytesLength]; - data[0] = idx; - Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); - - var p = 0; - EnumServiceWithEventsEvents ev = new(); - ev.Decode(bytes, ref p); - yield return ev; - } - idx++; - } - } - } -} - -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 F1 { get; set; } - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } - - /// - public override string TypeName() => "MyParam"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(this.F1.Encode()); - result.AddRange(this.F2.Encode()); - result.AddRange(this.F3.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - this.F1 = new global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256(); - this.F1.Decode(byteArray, ref p); - this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); - this.F2.Decode(byteArray, ref p); - this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); - this.F3.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); - } -} + { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); + } + + public partial class ServiceWithEvents : IServiceWithEvents + { private readonly IRemoting remoting; + + public ServiceWithEvents(IRemoting remoting) { this.remoting = remoting; } + +/// + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) { return new RemotingAction( this.remoting, [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } } + +public enum ServiceWithEventsEvents { One, + Two, + Three, + Reset, + } + + public sealed partial class EnumServiceWithEventsEvents : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumServiceWithEventsEvents() { this.AddTypeDecoder(ServiceWithEventsEvents.One); +this.AddTypeDecoder>(ServiceWithEventsEvents.Two); +this.AddTypeDecoder(ServiceWithEventsEvents.Three); +this.AddTypeDecoder(ServiceWithEventsEvents.Reset); + } } + + public partial class ServiceWithEventsListener : IRemotingListener { private static readonly byte[][] EventRoutes = [ [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 79, 110, 101],[68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 84, 119, 111],[68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 84, 104, 114, 101, 101],[68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 82, 101, 115, 101, 116], ]; + + private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; + + public ServiceWithEventsListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) { this.remoting = remoting; } + + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) { byte idx = 0; foreach (var route in EventRoutes) { if (route.Length > bytes.Length) { continue; } if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) { var bytesLength = bytes.Length - route.Length + 1; var data = new byte[bytesLength]; data[0] = idx; Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); var p = 0; EnumServiceWithEventsEvents ev = new(); ev.Decode(bytes, ref p); yield return ev; } idx++; } } } } + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType { +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 F1 { get; set; } +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } +/// + public override string TypeName() => "MyParam"; +/// + public override byte[] Encode() { var result = new List(); result.AddRange(this.F1.Encode()); +result.AddRange(this.F2.Encode()); +result.AddRange(this.F3.Encode()); + return result.ToArray(); } +/// + public override void Decode(byte[] byteArray, ref int p) { var start = p; this.F1 = new global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256(); + this.F1.Decode(byteArray, ref p); +this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.F2.Decode(byteArray, ref p); +this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); + this.F3.Decode(byteArray, ref p); + var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap index 12192430..97d876c9 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap @@ -9,57 +9,28 @@ using global::Sails.Remoting.Abstractions; namespace Service.Client; public interface IService -{ - global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); - global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); -} - -public partial class Service : IService -{ - private readonly IRemoting remoting; - - public Service(IRemoting remoting) - { - this.remoting = remoting; - } - - /// - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) - { - return new RemotingAction( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) - { - return new RemotingAction( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) - ); - } -} - -public enum MyParam2 -{ - Variant1, - Variant2, - Variant3, - Variant4, - Variant5, -} - -public sealed partial class EnumMyParam2 : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumMyParam2() - { - this.AddTypeDecoder(MyParam2.Variant1); - this.AddTypeDecoder(MyParam2.Variant2); - this.AddTypeDecoder(MyParam2.Variant3); - this.AddTypeDecoder>(MyParam2.Variant4); - this.AddTypeDecoder>>(MyParam2.Variant5); - } -} + { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); +global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); + } + + public partial class Service : IService + { private readonly IRemoting remoting; + + public Service(IRemoting remoting) { this.remoting = remoting; } + +/// + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } +/// + public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } + +public enum MyParam2 { Variant1, + Variant2, + Variant3, + Variant4, + Variant5, + } public sealed partial class EnumMyParam2 : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumMyParam2() { this.AddTypeDecoder(MyParam2.Variant1); +this.AddTypeDecoder(MyParam2.Variant2); +this.AddTypeDecoder(MyParam2.Variant3); +this.AddTypeDecoder>(MyParam2.Variant4); +this.AddTypeDecoder>>(MyParam2.Variant5); + } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap index b9113fc4..1741152f 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -11,278 +11,144 @@ using global::System.Collections.Generic; namespace Service.Client; public interface IServiceFactory -{ - /// - /// New constructor - /// - IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); -} - -public partial class ServiceFactory : IServiceFactory -{ - private readonly IRemoting remoting; - - public ServiceFactory(IRemoting remoting) - { - this.remoting = remoting; - } - - /// - public IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a) - { - return new RemotingAction( - this.remoting, - [12, 78, 101, 119], - new global::Substrate.NetApi.Model.Types.Primitive.U32(a)); - } -} + { +/// +/// New constructor +/// +IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); + } -public interface IService -{ - global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); - global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); - global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); - global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); -} + public partial class ServiceFactory : IServiceFactory + { -public partial class Service : IService -{ - private readonly IRemoting remoting; + private readonly IRemoting remoting; - public Service(IRemoting remoting) - { - this.remoting = remoting; - } + public ServiceFactory(IRemoting remoting) + { this.remoting = remoting; } - /// - public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) - { - return new RemotingAction>( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) - { - return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) - ); - } - /// - public global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) - { - return new RemotingAction( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) - ); - } - /// - public global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) - { - return new RemotingAction>( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) - ); - } -} +/// + public IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a) { return new RemotingAction( this.remoting, [12, 78, 101, 119], new global::Substrate.NetApi.Model.Types.Primitive.U32(a)); } -public enum ServiceEvents -{ - /// - /// `This` Done - /// - ThisDone, - /// - /// `That` Done too - /// - ThatDone, -} + } -public sealed partial class EnumServiceEvents : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumServiceEvents() - { - this.AddTypeDecoder(ServiceEvents.ThisDone); - this.AddTypeDecoder(ServiceEvents.ThatDone); - } -} +public interface IService + { global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); +global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); +global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); +global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); + } + + public partial class Service : IService + { private readonly IRemoting remoting; + + public Service(IRemoting remoting) { this.remoting = remoting; } + +/// + public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) ); } +/// + public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } +/// + public global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } +/// + public global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } } + +public enum ServiceEvents { +/// +/// `This` Done +/// + ThisDone, +/// +/// `That` Done too +/// + ThatDone, + } -public partial class ServiceListener : IRemotingListener -{ - private static readonly byte[][] EventRoutes = - [ - [28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 105, 115, 68, 111, 110, 101], - [28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 97, 116, 68, 111, 110, 101], - ]; + public sealed partial class EnumServiceEvents : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumServiceEvents() { this.AddTypeDecoder(ServiceEvents.ThisDone); +this.AddTypeDecoder(ServiceEvents.ThatDone); + } } - private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; + public partial class ServiceListener : IRemotingListener { private static readonly byte[][] EventRoutes = [ [28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 105, 115, 68, 111, 110, 101],[28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 97, 116, 68, 111, 110, 101], ]; - public ServiceListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) - { - this.remoting = remoting; - } + private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; - public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) - { - await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) - { - byte idx = 0; - foreach (var route in EventRoutes) - { - if (route.Length > bytes.Length) - { - continue; - } - if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) - { - var bytesLength = bytes.Length - route.Length + 1; - var data = new byte[bytesLength]; - data[0] = idx; - Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); + public ServiceListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting) { this.remoting = remoting; } - var p = 0; - EnumServiceEvents ev = new(); - ev.Decode(bytes, ref p); - yield return ev; - } - idx++; - } - } - } -} + public async global::System.Collections.Generic.IAsyncEnumerable ListenAsync([global::System.Runtime.CompilerServices.EnumeratorCancellation] global::System.Threading.CancellationToken cancellationToken = default) { await foreach (var bytes in this.remoting.ListenAsync(cancellationToken)) { byte idx = 0; foreach (var route in EventRoutes) { if (route.Length > bytes.Length) { continue; } if (route.AsSpan().SequenceEqual(bytes.AsSpan()[..route.Length])) { var bytesLength = bytes.Length - route.Length + 1; var data = new byte[bytesLength]; data[0] = idx; Buffer.BlockCopy(bytes, route.Length, data, 1, bytes.Length - route.Length); var p = 0; EnumServiceEvents ev = new(); ev.Decode(bytes, ref p); yield return ev; } idx++; } } } } /// /// ThisThatSvcAppTupleStruct docs /// -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } - - /// - public override string TypeName() => "ThisThatSvcAppTupleStruct"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(this.Value.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - this.Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); - this.Value.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); - } -} +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } +/// + public override string TypeName() => "ThisThatSvcAppTupleStruct"; +/// + public override byte[] Encode() { var result = new List(); result.AddRange(this.Value.Encode()); + return result.ToArray(); } +/// + public override void Decode(byte[] byteArray, ref int p) { var start = p; this.Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); + this.Value.Decode(byteArray, ref p); + var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } /// /// ThisThatSvcAppDoThatParam docs /// -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - /// - /// field `query` - /// - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.U32 Query { get; set; } - /// - /// field `result` - /// - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.Str Result { get; set; } - /// - /// field `p3` - /// - [System.Diagnostics.CodeAnalysis.AllowNull] - public EnumThisThatSvcAppManyVariants P3 { get; set; } - - /// - public override string TypeName() => "ThisThatSvcAppDoThatParam"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(this.Query.Encode()); - result.AddRange(this.Result.Encode()); - result.AddRange(this.P3.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - this.Query = new global::Substrate.NetApi.Model.Types.Primitive.U32(); - this.Query.Decode(byteArray, ref p); - this.Result = new global::Substrate.NetApi.Model.Types.Primitive.Str(); - this.Result.Decode(byteArray, ref p); - this.P3 = new EnumThisThatSvcAppManyVariants(); - this.P3.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); - } -} +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType { +/// +/// field `query` +/// +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.U32 Query { get; set; } +/// +/// field `result` +/// +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Str Result { get; set; } +/// +/// field `p3` +/// +[System.Diagnostics.CodeAnalysis.AllowNull] + public EnumThisThatSvcAppManyVariants P3 { get; set; } +/// + public override string TypeName() => "ThisThatSvcAppDoThatParam"; +/// + public override byte[] Encode() { var result = new List(); result.AddRange(this.Query.Encode()); +result.AddRange(this.Result.Encode()); +result.AddRange(this.P3.Encode()); + return result.ToArray(); } +/// + public override void Decode(byte[] byteArray, ref int p) { var start = p; this.Query = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + this.Query.Decode(byteArray, ref p); +this.Result = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + this.Result.Decode(byteArray, ref p); +this.P3 = new EnumThisThatSvcAppManyVariants(); + this.P3.Decode(byteArray, ref p); + var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } /// /// ThisThatSvcAppManyVariants docs /// -public enum ThisThatSvcAppManyVariants -{ - /// - /// variant `One` - /// - One, - /// - /// variant `Two` - /// - Two, - Three, - Four, - Five, - Six, -} - -public sealed partial class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumThisThatSvcAppManyVariants() - { - this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); - this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); - this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); - this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); - this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); - this.AddTypeDecoder(ThisThatSvcAppManyVariants.Six); - } -} - -public enum T -{ - One, -} - -public sealed partial class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumT() - { - this.AddTypeDecoder(T.One); - } -} +public enum ThisThatSvcAppManyVariants { +/// +/// variant `One` +/// + One, +/// +/// variant `Two` +/// + Two, + Three, + Four, + Five, + Six, + } public sealed partial class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumThisThatSvcAppManyVariants() { this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); +this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); +this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); +this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); +this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); +this.AddTypeDecoder(ThisThatSvcAppManyVariants.Six); + } } + +public enum T { One, + } public sealed partial class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumT() { this.AddTypeDecoder(T.One); + } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap index 403fb6b4..4c549040 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -11,186 +11,93 @@ using global::System.Collections.Generic; namespace Service.Client; public interface IServiceFactory -{ - IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); -} - -public partial class ServiceFactory : IServiceFactory -{ - private readonly IRemoting remoting; - - public ServiceFactory(IRemoting remoting) - { - this.remoting = remoting; - } - - /// - public IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a) - { - return new RemotingAction( - this.remoting, - [12, 78, 101, 119], - new global::Substrate.NetApi.Model.Types.Primitive.U32(a)); - } -} + { +IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); + } + + public partial class ServiceFactory : IServiceFactory + { + + private readonly IRemoting remoting; + + public ServiceFactory(IRemoting remoting) + { this.remoting = remoting; } + +/// + public IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a) { return new RemotingAction( this.remoting, [12, 78, 101, 119], new global::Substrate.NetApi.Model.Types.Primitive.U32(a)); } + + } public interface IService -{ - global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); - global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); - global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); - global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); -} - -public partial class Service : IService -{ - private readonly IRemoting remoting; - - public Service(IRemoting remoting) - { - this.remoting = remoting; - } - - /// - public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) - { - return new RemotingAction>( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) - { - return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) - ); - } - /// - public global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) - { - return new RemotingAction( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) - ); - } - /// - public global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) - { - return new RemotingAction>( - this.remoting, - [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) - ); - } -} - -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } - - /// - public override string TypeName() => "ThisThatSvcAppTupleStruct"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(this.Value.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - this.Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); - this.Value.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); - } -} - -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } - [System.Diagnostics.CodeAnalysis.AllowNull] - public EnumThisThatSvcAppManyVariants P3 { get; set; } - - /// - public override string TypeName() => "ThisThatSvcAppDoThatParam"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(this.P1.Encode()); - result.AddRange(this.P2.Encode()); - result.AddRange(this.P3.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - this.P1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); - this.P1.Decode(byteArray, ref p); - this.P2 = new global::Substrate.NetApi.Model.Types.Primitive.Str(); - this.P2.Decode(byteArray, ref p); - this.P3 = new EnumThisThatSvcAppManyVariants(); - this.P3.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); - } -} - -public enum ThisThatSvcAppManyVariants -{ - One, - Two, - Three, - Four, - Five, - Six, -} - -public sealed partial class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumThisThatSvcAppManyVariants() - { - this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); - this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); - this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); - this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); - this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); - this.AddTypeDecoder(ThisThatSvcAppManyVariants.Six); - } -} - -public enum T -{ - One, -} - -public sealed partial class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumT() - { - this.AddTypeDecoder(T.One); - } -} + { global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); +global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); +global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); +global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); + } + + public partial class Service : IService + { private readonly IRemoting remoting; + + public Service(IRemoting remoting) { this.remoting = remoting; } + +/// + public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) ); } +/// + public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } +/// + public global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } +/// + public global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } } + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { [System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } +/// + public override string TypeName() => "ThisThatSvcAppTupleStruct"; +/// + public override byte[] Encode() { var result = new List(); result.AddRange(this.Value.Encode()); + return result.ToArray(); } +/// + public override void Decode(byte[] byteArray, ref int p) { var start = p; this.Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); + this.Value.Decode(byteArray, ref p); + var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType { +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } +[System.Diagnostics.CodeAnalysis.AllowNull] + public EnumThisThatSvcAppManyVariants P3 { get; set; } +/// + public override string TypeName() => "ThisThatSvcAppDoThatParam"; +/// + public override byte[] Encode() { var result = new List(); result.AddRange(this.P1.Encode()); +result.AddRange(this.P2.Encode()); +result.AddRange(this.P3.Encode()); + return result.ToArray(); } +/// + public override void Decode(byte[] byteArray, ref int p) { var start = p; this.P1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); + this.P1.Decode(byteArray, ref p); +this.P2 = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + this.P2.Decode(byteArray, ref p); +this.P3 = new EnumThisThatSvcAppManyVariants(); + this.P3.Decode(byteArray, ref p); + var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } + +public enum ThisThatSvcAppManyVariants { One, + Two, + Three, + Four, + Five, + Six, + } public sealed partial class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumThisThatSvcAppManyVariants() { this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); +this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); +this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); +this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); +this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); +this.AddTypeDecoder(ThisThatSvcAppManyVariants.Six); + } } + +public enum T { One, + } public sealed partial class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumT() { this.AddTypeDecoder(T.One); + } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap index a3517909..5a924157 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap @@ -9,61 +9,28 @@ using global::Sails.Remoting.Abstractions; namespace Multiple.Client; public interface IMultiple -{ - global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); - global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); -} + { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); +global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); + } -public partial class Multiple : IMultiple -{ - private readonly IRemoting remoting; + public partial class Multiple : IMultiple + { private readonly IRemoting remoting; - public Multiple(IRemoting remoting) - { - this.remoting = remoting; - } + public Multiple(IRemoting remoting) { this.remoting = remoting; } - /// - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) - { - return new RemotingAction( - this.remoting, - [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) - { - return new RemotingAction( - this.remoting, - [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) - ); - } -} +/// + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } +/// + public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } public interface INamed -{ - global::Sails.Remoting.Abstractions.IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1); -} + { global::Sails.Remoting.Abstractions.IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1); + } -public partial class Named : INamed -{ - private readonly IRemoting remoting; + public partial class Named : INamed + { private readonly IRemoting remoting; - public Named(IRemoting remoting) - { - this.remoting = remoting; - } + public Named(IRemoting remoting) { this.remoting = remoting; } - /// - public global::Sails.Remoting.Abstractions.IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1) - { - return new RemotingAction( - this.remoting, - [20, 78, 97, 109, 101, 100, 16, 84, 104, 97, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) - ); - } -} +/// + public global::Sails.Remoting.Abstractions.IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1) { return new RemotingAction( this.remoting, [20, 78, 97, 109, 101, 100, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap index db3fdcd5..389ffc28 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap @@ -11,66 +11,36 @@ using global::System.Collections.Generic; namespace NonZeroParams.Client; public interface INonZeroParams -{ - global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); -} - -public partial class NonZeroParams : INonZeroParams -{ - private readonly IRemoting remoting; - - public NonZeroParams(IRemoting remoting) - { - this.remoting = remoting; - } - - /// - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) - { - return new RemotingAction( - this.remoting, - [52, 78, 111, 110, 90, 101, 114, 111, 80, 97, 114, 97, 109, 115, 24, 68, 111, 84, 104, 105, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) - ); - } -} - -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 F1 { get; set; } - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } - - /// - public override string TypeName() => "MyParam"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(this.F1.Encode()); - result.AddRange(this.F2.Encode()); - result.AddRange(this.F3.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - this.F1 = new global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256(); - this.F1.Decode(byteArray, ref p); - this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); - this.F2.Decode(byteArray, ref p); - this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); - this.F3.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); - } -} + { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); + } + + public partial class NonZeroParams : INonZeroParams + { private readonly IRemoting remoting; + + public NonZeroParams(IRemoting remoting) { this.remoting = remoting; } + +/// + public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) { return new RemotingAction( this.remoting, [52, 78, 111, 110, 90, 101, 114, 111, 80, 97, 114, 97, 109, 115, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } } + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType { +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 F1 { get; set; } +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseVec F2 { get; set; } +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt> F3 { get; set; } +/// + public override string TypeName() => "MyParam"; +/// + public override byte[] Encode() { var result = new List(); result.AddRange(this.F1.Encode()); +result.AddRange(this.F2.Encode()); +result.AddRange(this.F3.Encode()); + return result.ToArray(); } +/// + public override void Decode(byte[] byteArray, ref int p) { var start = p; this.F1 = new global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256(); + this.F1.Decode(byteArray, ref p); +this.F2 = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.F2.Decode(byteArray, ref p); +this.F3 = new global::Substrate.NetApi.Model.Types.Base.BaseOpt>(); + this.F3.Decode(byteArray, ref p); + var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap index bddc8331..5fe5e382 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap @@ -11,254 +11,134 @@ using global::System.Collections.Generic; namespace RmrkCatalog.Client; public interface IRmrkCatalogFactory -{ - IActivation New(); -} + { +IActivation New(); + } -public partial class RmrkCatalogFactory : IRmrkCatalogFactory -{ - private readonly IRemoting remoting; + public partial class RmrkCatalogFactory : IRmrkCatalogFactory + { - public RmrkCatalogFactory(IRemoting remoting) - { - this.remoting = remoting; - } + private readonly IRemoting remoting; - /// - public IActivation New() - { - return new RemotingAction( - this.remoting, - [12, 78, 101, 119], - new global::Substrate.NetApi.Model.Types.Base.BaseVoid()); - } -} + public RmrkCatalogFactory(IRemoting remoting) + { this.remoting = remoting; } -public interface IRmrkCatalog -{ - global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds); - global::Sails.Remoting.Abstractions.ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts); - global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); - global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds); - global::Sails.Remoting.Abstractions.ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); - global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); - global::Sails.Remoting.Abstractions.IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); - global::Sails.Remoting.Abstractions.IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); -} - -public partial class RmrkCatalog : IRmrkCatalog -{ - private readonly IRemoting remoting; - - public RmrkCatalog(IRemoting remoting) - { - this.remoting = remoting; - } - - /// - public global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds) - { - return new RemotingAction>, Error>>( - this.remoting, - [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 56, 65, 100, 100, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionIds) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts) - { - return new RemotingAction, Error>>( - this.remoting, - [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 32, 65, 100, 100, 80, 97, 114, 116, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(parts) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) - { - return new RemotingAction, Error>>( - this.remoting, - [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 109, 111, 118, 101, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds) - { - return new RemotingAction, Error>>( - this.remoting, - [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 44, 82, 101, 109, 111, 118, 101, 80, 97, 114, 116, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partIds) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) - { - return new RemotingAction>( - this.remoting, - [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 115, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) - ); - } - /// - public global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) - { - return new RemotingAction>( - this.remoting, - [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 76, 83, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115, 84, 111, 65, 108, 108], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) - ); - } - /// - public global::Sails.Remoting.Abstractions.IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) - { - return new RemotingAction>( - this.remoting, - [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 40, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) - ); - } - /// - public global::Sails.Remoting.Abstractions.IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) - { - return new RemotingAction>( - this.remoting, - [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 16, 80, 97, 114, 116], - new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) - ); - } -} - -public enum Error -{ - PartIdCantBeZero, - BadConfig, - PartAlreadyExists, - ZeroLengthPassed, - PartDoesNotExist, - WrongPartFormat, - NotAllowedToCall, -} - -public sealed partial class EnumError : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumError() - { - this.AddTypeDecoder(Error.PartIdCantBeZero); - this.AddTypeDecoder(Error.BadConfig); - this.AddTypeDecoder(Error.PartAlreadyExists); - this.AddTypeDecoder(Error.ZeroLengthPassed); - this.AddTypeDecoder(Error.PartDoesNotExist); - this.AddTypeDecoder(Error.WrongPartFormat); - this.AddTypeDecoder(Error.NotAllowedToCall); - } -} - -public enum Part -{ - Fixed, - Slot, -} - -public sealed partial class EnumPart : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust -{ - public EnumPart() - { - this.AddTypeDecoder(Part.Fixed); - this.AddTypeDecoder(Part.Slot); - } -} +/// + public IActivation New() { return new RemotingAction( this.remoting, [12, 78, 101, 119], new global::Substrate.NetApi.Model.Types.Base.BaseVoid()); } -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class FixedPart : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - /// - /// An optional zIndex of base part layer. - /// specifies the stack order of an element. - /// An element with greater stack order is always in front of an element with a lower stack order. - /// - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } - /// - /// The metadata URI of the part. - /// - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } + } - /// - public override string TypeName() => "FixedPart"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(this.Z.Encode()); - result.AddRange(this.MetadataUri.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - this.Z = new global::Substrate.NetApi.Model.Types.Base.BaseOpt(); - this.Z.Decode(byteArray, ref p); - this.MetadataUri = new global::Substrate.NetApi.Model.Types.Primitive.Str(); - this.MetadataUri.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); - } -} - -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] -public sealed partial class SlotPart : global::Substrate.NetApi.Model.Types.Base.BaseType -{ - /// - /// Array of whitelisted collections that can be equipped in the given slot. Used with slot parts only. - /// - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Base.BaseVec Equippable { get; set; } - /// - /// An optional zIndex of base part layer. - /// specifies the stack order of an element. - /// An element with greater stack order is always in front of an element with a lower stack order. - /// - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } - /// - /// The metadata URI of the part. - /// - [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } - - /// - public override string TypeName() => "SlotPart"; - - /// - public override byte[] Encode() - { - var result = new List(); - result.AddRange(this.Equippable.Encode()); - result.AddRange(this.Z.Encode()); - result.AddRange(this.MetadataUri.Encode()); - return result.ToArray(); - } - - /// - public override void Decode(byte[] byteArray, ref int p) - { - var start = p; - this.Equippable = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); - this.Equippable.Decode(byteArray, ref p); - this.Z = new global::Substrate.NetApi.Model.Types.Base.BaseOpt(); - this.Z.Decode(byteArray, ref p); - this.MetadataUri = new global::Substrate.NetApi.Model.Types.Primitive.Str(); - this.MetadataUri.Decode(byteArray, ref p); - var bytesLength = p - start; - this.TypeSize = bytesLength; - this.Bytes = new byte[bytesLength]; - Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); - } -} +public interface IRmrkCatalog + { global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds); +global::Sails.Remoting.Abstractions.ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts); +global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); +global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds); +global::Sails.Remoting.Abstractions.ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); +global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); +global::Sails.Remoting.Abstractions.IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); +global::Sails.Remoting.Abstractions.IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); + } + + public partial class RmrkCatalog : IRmrkCatalog + { private readonly IRemoting remoting; + + public RmrkCatalog(IRemoting remoting) { this.remoting = remoting; } + +/// + public global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds) { return new RemotingAction>, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 56, 65, 100, 100, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionIds) ); } +/// + public global::Sails.Remoting.Abstractions.ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts) { return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 32, 65, 100, 100, 80, 97, 114, 116, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(parts) ); } +/// + public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 109, 111, 118, 101, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) ); } +/// + public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds) { return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 44, 82, 101, 109, 111, 118, 101, 80, 97, 114, 116, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partIds) ); } +/// + public global::Sails.Remoting.Abstractions.ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 115, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } +/// + public global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 76, 83, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115, 84, 111, 65, 108, 108], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } +/// + public global::Sails.Remoting.Abstractions.IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 40, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) ); } +/// + public global::Sails.Remoting.Abstractions.IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 16, 80, 97, 114, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } } + +public enum Error { PartIdCantBeZero, + BadConfig, + PartAlreadyExists, + ZeroLengthPassed, + PartDoesNotExist, + WrongPartFormat, + NotAllowedToCall, + } public sealed partial class EnumError : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumError() { this.AddTypeDecoder(Error.PartIdCantBeZero); +this.AddTypeDecoder(Error.BadConfig); +this.AddTypeDecoder(Error.PartAlreadyExists); +this.AddTypeDecoder(Error.ZeroLengthPassed); +this.AddTypeDecoder(Error.PartDoesNotExist); +this.AddTypeDecoder(Error.WrongPartFormat); +this.AddTypeDecoder(Error.NotAllowedToCall); + } } + +public enum Part { Fixed, + Slot, + } public sealed partial class EnumPart : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumPart() { this.AddTypeDecoder(Part.Fixed); +this.AddTypeDecoder(Part.Slot); + } } + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class FixedPart : global::Substrate.NetApi.Model.Types.Base.BaseType { +/// +/// An optional zIndex of base part layer. +/// specifies the stack order of an element. +/// An element with greater stack order is always in front of an element with a lower stack order. +/// +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } +/// +/// The metadata URI of the part. +/// +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } +/// + public override string TypeName() => "FixedPart"; +/// + public override byte[] Encode() { var result = new List(); result.AddRange(this.Z.Encode()); +result.AddRange(this.MetadataUri.Encode()); + return result.ToArray(); } +/// + public override void Decode(byte[] byteArray, ref int p) { var start = p; this.Z = new global::Substrate.NetApi.Model.Types.Base.BaseOpt(); + this.Z.Decode(byteArray, ref p); +this.MetadataUri = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + this.MetadataUri.Decode(byteArray, ref p); + var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } + +[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class SlotPart : global::Substrate.NetApi.Model.Types.Base.BaseType { +/// +/// Array of whitelisted collections that can be equipped in the given slot. Used with slot parts only. +/// +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseVec Equippable { get; set; } +/// +/// An optional zIndex of base part layer. +/// specifies the stack order of an element. +/// An element with greater stack order is always in front of an element with a lower stack order. +/// +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Base.BaseOpt Z { get; set; } +/// +/// The metadata URI of the part. +/// +[System.Diagnostics.CodeAnalysis.AllowNull] + public global::Substrate.NetApi.Model.Types.Primitive.Str MetadataUri { get; set; } +/// + public override string TypeName() => "SlotPart"; +/// + public override byte[] Encode() { var result = new List(); result.AddRange(this.Equippable.Encode()); +result.AddRange(this.Z.Encode()); +result.AddRange(this.MetadataUri.Encode()); + return result.ToArray(); } +/// + public override void Decode(byte[] byteArray, ref int p) { var start = p; this.Equippable = new global::Substrate.NetApi.Model.Types.Base.BaseVec(); + this.Equippable.Decode(byteArray, ref p); +this.Z = new global::Substrate.NetApi.Model.Types.Base.BaseOpt(); + this.Z.Decode(byteArray, ref p); +this.MetadataUri = new global::Substrate.NetApi.Model.Types.Primitive.Str(); + this.MetadataUri.Decode(byteArray, ref p); + var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } From 45f8d13e398b9405b2a2a64c728a82eadda4fdca Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 6 Nov 2024 11:35:08 +0100 Subject: [PATCH 16/54] wip: ci --- .github/workflows/net-build-client-gen.yml | 38 +++++++++++++++++++ .../Sails.ClientGenerator.csproj | 4 +- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/net-build-client-gen.yml diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml new file mode 100644 index 00000000..111712f9 --- /dev/null +++ b/.github/workflows/net-build-client-gen.yml @@ -0,0 +1,38 @@ +name: '[net] Build client-gen-dotnet' + +on: + push: + branches: + - master + paths: + - '.github/workflows/net-build-client-gen.yml' + - 'rs/**' + + pull_request: + paths: + - '.github/workflows/net-build-client-gen.yml' + - 'rs/**' + +jobs: + win-x64: + runs-on: windows-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - run: cargo build -p sails-client-gen-dotnet --target x86_64-pc-windows-msvc --release + - uses: actions/upload-artifact@v4 + with: + name: win-x64 + path: ./target/x86_64-pc-windows-msvc/release/sails-client-gen-dotnet.dll + retention-days: 1 + + linux-x64: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: cargo build -p sails-client-gen-dotnet --target x86_64-unknown-linux-gnu --release + - uses: actions/upload-artifact@v4 + with: + name: linux-x64 + path: ./target/x86_64-unknown-linux-gnu/release/sails-client-gen-dotnet.so + retention-days: 1 diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index a5757602..7e8e5fea 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -38,9 +38,9 @@ - + From 9fe76e690eb49b96ed407c96cadcc65965f95bc2 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 6 Nov 2024 11:42:43 +0100 Subject: [PATCH 17/54] wip: ci2 --- .github/workflows/net-build-client-gen.yml | 8 ++++---- .../Sails.ClientGenerator/Sails.ClientGenerator.csproj | 10 ---------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index 111712f9..4f441f32 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -19,20 +19,20 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v4 - - run: cargo build -p sails-client-gen-dotnet --target x86_64-pc-windows-msvc --release + - run: cargo build -p sails-client-gen-dotnet --release - uses: actions/upload-artifact@v4 with: name: win-x64 - path: ./target/x86_64-pc-windows-msvc/release/sails-client-gen-dotnet.dll + path: ./target/release/sails_client_gen_dotnet.dll retention-days: 1 linux-x64: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: cargo build -p sails-client-gen-dotnet --target x86_64-unknown-linux-gnu --release + - run: cargo build -p sails-client-gen-dotnet --release - uses: actions/upload-artifact@v4 with: name: linux-x64 - path: ./target/x86_64-unknown-linux-gnu/release/sails-client-gen-dotnet.so + path: ./target/release/sails_client_gen_dotnet.so retention-days: 1 diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 7e8e5fea..555e7b0f 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -20,12 +20,6 @@ - - - Always - - - @@ -38,10 +32,6 @@ - - From b0b675d9c6c4201e87b493c6a3eb3b90b02ab08b Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 6 Nov 2024 12:39:08 +0100 Subject: [PATCH 18/54] wip: ci3 --- .github/workflows/net-build-client-gen.yml | 13 ++++++++++++- .../Sails.ClientGenerator.csproj | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index 4f441f32..4ab07cc1 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -34,5 +34,16 @@ jobs: - uses: actions/upload-artifact@v4 with: name: linux-x64 - path: ./target/release/sails_client_gen_dotnet.so + path: ./target/release/libsails_client_gen_dotnet.so + retention-days: 1 + + osx-arm64: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - run: cargo build -p sails-client-gen-dotnet --release + - uses: actions/upload-artifact@v4 + with: + name: linux-x64 + path: ./target/release/libsails_client_gen_dotnet.dylib retention-days: 1 diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 555e7b0f..f4da178a 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -32,6 +32,10 @@ + + + + From cf0064b0282f9ac79dd7e40cbf9f5d7f0df93720 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 6 Nov 2024 15:29:42 +0100 Subject: [PATCH 19/54] wip: ci4 --- .github/workflows/net-build-client-gen.yml | 39 +++++++++++++++++-- .../Sails.ClientGenerator.csproj | 13 ++++++- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index 4ab07cc1..89736dd9 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -6,11 +6,13 @@ on: - master paths: - '.github/workflows/net-build-client-gen.yml' - - 'rs/**' + - 'rs/client-gen-dotnet/**' + - 'rs/idl-parser/**' pull_request: paths: - '.github/workflows/net-build-client-gen.yml' + - 'rs/client-gen-dotnet/**' - 'rs/**' jobs: @@ -25,6 +27,7 @@ jobs: name: win-x64 path: ./target/release/sails_client_gen_dotnet.dll retention-days: 1 + overwrite: true linux-x64: runs-on: ubuntu-latest @@ -36,14 +39,42 @@ jobs: name: linux-x64 path: ./target/release/libsails_client_gen_dotnet.so retention-days: 1 + overwrite: true + linux-arm64: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: rustup target add x86_64-apple-darwin + - run: cargo build -p sails-client-gen-dotnet --release --target aarch64-unknown-linux-gnu + - uses: actions/upload-artifact@v4 + with: + name: linux-arm64 + path: ./target/aarch64-unknown-linux-gnu/release/libsails_client_gen_dotnet.so + retention-days: 1 + overwrite: true + + osx-x64: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - run: rustup target add x86_64-apple-darwin + - run: cargo build -p sails-client-gen-dotnet --release --target x86_64-apple-darwin + - uses: actions/upload-artifact@v4 + with: + name: osx-x64 + path: ./target/x86_64-apple-darwin/release/libsails_client_gen_dotnet.dylib + retention-days: 1 + overwrite: true + osx-arm64: runs-on: macos-latest steps: - uses: actions/checkout@v4 - - run: cargo build -p sails-client-gen-dotnet --release + - run: cargo build -p sails-client-gen-dotnet --release --target aarch64-apple-darwin - uses: actions/upload-artifact@v4 with: - name: linux-x64 - path: ./target/release/libsails_client_gen_dotnet.dylib + name: osx-arm64 + path: ./target/aarch64-apple-darwin/release/libsails_client_gen_dotnet.dylib retention-days: 1 + overwrite: true diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index f4da178a..a68ea6b7 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -16,7 +16,6 @@ - @@ -36,6 +35,18 @@ + + + Always + + + Always + + + Always + + + From a5858cdc45a0ef0a743b0f383044f8db7792cad3 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 6 Nov 2024 15:45:47 +0100 Subject: [PATCH 20/54] wip: ci --- .github/workflows/net-build-client-gen.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index 89736dd9..9e9a3efa 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -13,7 +13,7 @@ on: paths: - '.github/workflows/net-build-client-gen.yml' - 'rs/client-gen-dotnet/**' - - 'rs/**' + - 'rs/idl-parser/**' jobs: win-x64: @@ -33,11 +33,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: cargo build -p sails-client-gen-dotnet --release + - run: rustup target add x86_64-unknown-linux-gnu + - run: cargo build -p sails-client-gen-dotnet --release --target x86_64-unknown-linux-gnu - uses: actions/upload-artifact@v4 with: name: linux-x64 - path: ./target/release/libsails_client_gen_dotnet.so + path: ./target/x86_64-unknown-linux-gnu/release/libsails_client_gen_dotnet.so retention-days: 1 overwrite: true @@ -45,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: rustup target add x86_64-apple-darwin + - run: rustup target add aarch64-unknown-linux-gnu - run: cargo build -p sails-client-gen-dotnet --release --target aarch64-unknown-linux-gnu - uses: actions/upload-artifact@v4 with: @@ -71,6 +72,7 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v4 + - run: rustup target add aarch64-apple-darwin - run: cargo build -p sails-client-gen-dotnet --release --target aarch64-apple-darwin - uses: actions/upload-artifact@v4 with: From 42c033de7f14409959e386cb37ccafec0749a909 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 6 Nov 2024 15:58:25 +0100 Subject: [PATCH 21/54] fix build --- Cargo.lock | 2 +- rs/idl-parser/src/ffi/ast/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7bd70073..889fb449 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1338,7 +1338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c26b9831049b947d154bba920e4124053def72447be6fb106a96f483874b482a" dependencies = [ "regex", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] diff --git a/rs/idl-parser/src/ffi/ast/mod.rs b/rs/idl-parser/src/ffi/ast/mod.rs index 127ef2d5..29010bbd 100644 --- a/rs/idl-parser/src/ffi/ast/mod.rs +++ b/rs/idl-parser/src/ffi/ast/mod.rs @@ -81,7 +81,7 @@ pub unsafe extern "C" fn free_parse_result(result: *mut ParseResult) { unsafe { let result = Box::from_raw(result); if result.error.code != ErrorCode::Ok { - let details = CString::from_raw(result.error.details as *mut i8); + let details = CString::from_raw(result.error.details as *mut std::ffi::c_char); drop(details); } } From aa1aa71822a8cae1a4e7e204d71b05888bfe8b22 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 6 Nov 2024 16:09:43 +0100 Subject: [PATCH 22/54] wip: ci --- .github/workflows/net-build-client-gen.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index 9e9a3efa..779084ee 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -33,25 +33,23 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: rustup target add x86_64-unknown-linux-gnu - - run: cargo build -p sails-client-gen-dotnet --release --target x86_64-unknown-linux-gnu + - run: cargo build -p sails-client-gen-dotnet --release - uses: actions/upload-artifact@v4 with: name: linux-x64 - path: ./target/x86_64-unknown-linux-gnu/release/libsails_client_gen_dotnet.so + path: ./target/release/libsails_client_gen_dotnet.so retention-days: 1 overwrite: true linux-arm64: - runs-on: ubuntu-latest + runs-on: ubuntu-arm steps: - uses: actions/checkout@v4 - - run: rustup target add aarch64-unknown-linux-gnu - - run: cargo build -p sails-client-gen-dotnet --release --target aarch64-unknown-linux-gnu + - run: cargo build -p sails-client-gen-dotnet --release - uses: actions/upload-artifact@v4 with: name: linux-arm64 - path: ./target/aarch64-unknown-linux-gnu/release/libsails_client_gen_dotnet.so + path: ./target/release/libsails_client_gen_dotnet.so retention-days: 1 overwrite: true From bdf2ce0ef062b1655d915212966325c2805168e4 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Thu, 7 Nov 2024 11:11:14 +0100 Subject: [PATCH 23/54] try i8 --- net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj | 4 ++-- rs/idl-parser/src/ffi/ast/mod.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index a68ea6b7..4252d305 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -10,7 +10,7 @@ true $(NoWarn);NU5128 Code generator for Sails.Net. - True + true true @@ -42,7 +42,7 @@ Always - + Always diff --git a/rs/idl-parser/src/ffi/ast/mod.rs b/rs/idl-parser/src/ffi/ast/mod.rs index 29010bbd..127ef2d5 100644 --- a/rs/idl-parser/src/ffi/ast/mod.rs +++ b/rs/idl-parser/src/ffi/ast/mod.rs @@ -81,7 +81,7 @@ pub unsafe extern "C" fn free_parse_result(result: *mut ParseResult) { unsafe { let result = Box::from_raw(result); if result.error.code != ErrorCode::Ok { - let details = CString::from_raw(result.error.details as *mut std::ffi::c_char); + let details = CString::from_raw(result.error.details as *mut i8); drop(details); } } From 1588abec70a2adf262d09341a4f7df18a1e42133 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Thu, 7 Nov 2024 11:14:12 +0100 Subject: [PATCH 24/54] try 2 --- .github/workflows/net-build-client-gen.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index 779084ee..20738321 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -42,14 +42,14 @@ jobs: overwrite: true linux-arm64: - runs-on: ubuntu-arm + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: cargo build -p sails-client-gen-dotnet --release + - run: cargo build -p sails-client-gen-dotnet --release --target aarch64-unknown-linux-gnu - uses: actions/upload-artifact@v4 with: name: linux-arm64 - path: ./target/release/libsails_client_gen_dotnet.so + path: ./target/aarch64-unknown-linux-gnu/release/libsails_client_gen_dotnet.so retention-days: 1 overwrite: true From d3776591f767b5c38dc24c6d8e346ef3a0578849 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Thu, 7 Nov 2024 11:15:40 +0100 Subject: [PATCH 25/54] try 3 --- .github/workflows/net-build-client-gen.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index 20738321..8f38d717 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -45,6 +45,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - run: rustup target add aarch64-unknown-linux-gnu - run: cargo build -p sails-client-gen-dotnet --release --target aarch64-unknown-linux-gnu - uses: actions/upload-artifact@v4 with: From e4fb5fa9daaf58a7ab0311f86cad7d565f54f9d7 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Thu, 7 Nov 2024 12:38:36 +0100 Subject: [PATCH 26/54] try pack --- .github/workflows/net-build-client-gen.yml | 41 +++++++++++++------ .../Sails.ClientGenerator.csproj | 39 ++++++++++++++---- rs/idl-parser/src/ffi/ast/mod.rs | 2 +- 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index 8f38d717..2f36b713 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -41,19 +41,6 @@ jobs: retention-days: 1 overwrite: true - linux-arm64: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: rustup target add aarch64-unknown-linux-gnu - - run: cargo build -p sails-client-gen-dotnet --release --target aarch64-unknown-linux-gnu - - uses: actions/upload-artifact@v4 - with: - name: linux-arm64 - path: ./target/aarch64-unknown-linux-gnu/release/libsails_client_gen_dotnet.so - retention-days: 1 - overwrite: true - osx-x64: runs-on: macos-latest steps: @@ -79,3 +66,31 @@ jobs: path: ./target/aarch64-apple-darwin/release/libsails_client_gen_dotnet.dylib retention-days: 1 overwrite: true + + build-nuget-package: + needs: + - win-x64 + - linux-x64 + - osx-x64 + - osx-arm64 + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download native libraries + uses: actions/download-artifact@v4 + with: + path: native-libraries + + - name: Build package + run: dotnet pack ./net/src/Sails.ClientGenerator/ -c Release /p:LibraryRoot=${{ github.workspace }}/native-libraries -p:Version=0.6.3 -o ./publish + + - name: Upload NuGet artifact + uses: actions/upload-artifact@v4 + with: + name: nuget-package + path: ./publish/*.nupkg + retention-days: 1 + overwrite: true + diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 4252d305..e3537c19 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -31,22 +31,43 @@ + + - - Always - - - Always - - - Always - + + PreserveNewest + runtimes/win-x64/native/sails_client_gen_dotnet.dll + + + PreserveNewest + + + PreserveNewest + + + + + + runtimes/win-x64/native/sails_client_gen_dotnet.dll + + + runtimes/linux-x64/native/libsails_client_gen_dotnet.so + + + runtimes/osx-x64/native/libsails_client_gen_dotnet.dylib + + + runtimes/osx-arm64/native/libsails_client_gen_dotnet.dylib + + + + diff --git a/rs/idl-parser/src/ffi/ast/mod.rs b/rs/idl-parser/src/ffi/ast/mod.rs index 127ef2d5..29010bbd 100644 --- a/rs/idl-parser/src/ffi/ast/mod.rs +++ b/rs/idl-parser/src/ffi/ast/mod.rs @@ -81,7 +81,7 @@ pub unsafe extern "C" fn free_parse_result(result: *mut ParseResult) { unsafe { let result = Box::from_raw(result); if result.error.code != ErrorCode::Ok { - let details = CString::from_raw(result.error.details as *mut i8); + let details = CString::from_raw(result.error.details as *mut std::ffi::c_char); drop(details); } } From 780c705714bf8dc826056bc895c6d8a61f76daa2 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Thu, 7 Nov 2024 14:55:58 +0100 Subject: [PATCH 27/54] wip: ci --- .../Sails.ClientGenerator.csproj | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index e3537c19..dada2751 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -32,41 +32,38 @@ - + - + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + runtimes/win-x64/native/sails_client_gen_dotnet.dll - - PreserveNewest + + runtimes/linux-x64/native/libsails_client_gen_dotnet.so - - PreserveNewest + + runtimes/osx-x64/native/libsails_client_gen_dotnet.dylib + + + runtimes/osx-arm64/native/libsails_client_gen_dotnet.dylib - - - - - - runtimes/win-x64/native/sails_client_gen_dotnet.dll - - - runtimes/linux-x64/native/libsails_client_gen_dotnet.so - - - runtimes/osx-x64/native/libsails_client_gen_dotnet.dylib - - - runtimes/osx-arm64/native/libsails_client_gen_dotnet.dylib - - - From 06e7f0b3ee96ed7703ad1e2cd5cf4c3d0f11c618 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 8 Nov 2024 12:37:17 +0100 Subject: [PATCH 28/54] wip: native loader --- .github/workflows/net-build-client-gen.yml | 7 +- net/src/Sails.ClientGenerator/Kernel32.cs | 15 ++ net/src/Sails.ClientGenerator/Libdl.cs | 66 ++++++ .../Sails.ClientGenerator/LibraryLoader.cs | 221 ++++++++++++++++++ .../NativeMethods.Loader.cs | 86 +++++++ net/src/Sails.ClientGenerator/PathResolver.cs | 65 ++++++ .../Sails.ClientGenerator.csproj | 56 +++-- .../SailsClientGenerator.cs | 4 +- .../SailsClientGeneratorTests.cs | 3 +- ...rTests.Generate_DemoIdl#demo.g.verified.cs | 4 +- rs/client-gen-dotnet/src/ctor_generators.rs | 4 +- .../src/service_generators.rs | 4 +- 12 files changed, 500 insertions(+), 35 deletions(-) create mode 100644 net/src/Sails.ClientGenerator/Kernel32.cs create mode 100644 net/src/Sails.ClientGenerator/Libdl.cs create mode 100644 net/src/Sails.ClientGenerator/LibraryLoader.cs create mode 100644 net/src/Sails.ClientGenerator/NativeMethods.Loader.cs create mode 100644 net/src/Sails.ClientGenerator/PathResolver.cs diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index 2f36b713..a8bc41a5 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -83,8 +83,11 @@ jobs: with: path: native-libraries - - name: Build package - run: dotnet pack ./net/src/Sails.ClientGenerator/ -c Release /p:LibraryRoot=${{ github.workspace }}/native-libraries -p:Version=0.6.3 -o ./publish + - name: Build + run: dotnet build ./net/src/Sails.ClientGenerator/ -c Release -p:Version=0.6.3-rc + + - name: Pack + run: dotnet pack ./net/src/Sails.ClientGenerator/ -c Release --no-build -p:LibraryRoot=${{ github.workspace }}/native-libraries -p:Version=0.6.3-rc -o ./publish - name: Upload NuGet artifact uses: actions/upload-artifact@v4 diff --git a/net/src/Sails.ClientGenerator/Kernel32.cs b/net/src/Sails.ClientGenerator/Kernel32.cs new file mode 100644 index 00000000..381d0c7b --- /dev/null +++ b/net/src/Sails.ClientGenerator/Kernel32.cs @@ -0,0 +1,15 @@ +using System.Runtime.InteropServices; + +namespace Sails.ClientGenerator; + +internal static class Kernel32 +{ + [DllImport("kernel32")] + public static extern IntPtr LoadLibrary(string fileName); + + [DllImport("kernel32")] + public static extern IntPtr GetProcAddress(IntPtr module, string procName); + + [DllImport("kernel32")] + public static extern int FreeLibrary(IntPtr module); +} diff --git a/net/src/Sails.ClientGenerator/Libdl.cs b/net/src/Sails.ClientGenerator/Libdl.cs new file mode 100644 index 00000000..8670683a --- /dev/null +++ b/net/src/Sails.ClientGenerator/Libdl.cs @@ -0,0 +1,66 @@ +#pragma warning disable RCS0056 // A line is too long + +using System.Runtime.InteropServices; + +namespace Sails.ClientGenerator; + +internal static class Libdl +{ + private static class Libdl1 + { + private const string LibName = "libdl"; + + [DllImport(LibName)] + public static extern IntPtr dlopen(string fileName, int flags); + + [DllImport(LibName)] + public static extern IntPtr dlsym(IntPtr handle, string name); + + [DllImport(LibName)] + public static extern int dlclose(IntPtr handle); + + [DllImport(LibName)] + public static extern string dlerror(); + } + + private static class Libdl2 + { + private const string LibName = "libdl.so.2"; + + [DllImport(LibName)] + public static extern IntPtr dlopen(string fileName, int flags); + + [DllImport(LibName)] + public static extern IntPtr dlsym(IntPtr handle, string name); + + [DllImport(LibName)] + public static extern int dlclose(IntPtr handle); + + [DllImport(LibName)] + public static extern string dlerror(); + } + + static Libdl() + { + try + { + Libdl1.dlerror(); + UseLibdl1 = true; + } + catch + { + } + } + + private static readonly bool UseLibdl1; + + public const int RTLD_NOW = 0x002; + + public static IntPtr dlopen(string fileName, int flags) => UseLibdl1 ? Libdl1.dlopen(fileName, flags) : Libdl2.dlopen(fileName, flags); + + public static IntPtr dlsym(IntPtr handle, string name) => UseLibdl1 ? Libdl1.dlsym(handle, name) : Libdl2.dlsym(handle, name); + + public static int dlclose(IntPtr handle) => UseLibdl1 ? Libdl1.dlclose(handle) : Libdl2.dlclose(handle); + + public static string dlerror() => UseLibdl1 ? Libdl1.dlerror() : Libdl2.dlerror(); +} diff --git a/net/src/Sails.ClientGenerator/LibraryLoader.cs b/net/src/Sails.ClientGenerator/LibraryLoader.cs new file mode 100644 index 00000000..fab2cb89 --- /dev/null +++ b/net/src/Sails.ClientGenerator/LibraryLoader.cs @@ -0,0 +1,221 @@ +#pragma warning disable RCS0056 // A line is too long +#pragma warning disable RS1035 // Do not use APIs banned for analyzers + +using System.Reflection; +using System.Runtime.InteropServices; + +namespace Sails.ClientGenerator; + +/// +/// Exposes functionality for loading native libraries and function pointers. +/// +public abstract class LibraryLoader +{ + /// + /// Loads a native library by name and returns an operating system handle to it. + /// + /// The name of the library to open. + /// The operating system handle for the shared library. + public IntPtr LoadNativeLibrary(string name) + { + return this.LoadNativeLibrary(name, PathResolver.Default); + } + + /// + /// Loads a native library by name and returns an operating system handle to it. + /// + /// An ordered list of names. Each name is tried in turn, until the library is successfully loaded. + /// + /// The operating system handle for the shared library. + public IntPtr LoadNativeLibrary(string[] names) + { + return this.LoadNativeLibrary(names, PathResolver.Default); + } + + /// + /// Loads a native library by name and returns an operating system handle to it. + /// + /// The name of the library to open. + /// The path resolver to use. + /// The operating system handle for the shared library. + public IntPtr LoadNativeLibrary(string name, PathResolver pathResolver) + { + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentException("Parameter must not be null or empty.", nameof(name)); + } + + var ret = this.LoadWithResolver(name, pathResolver); + + if (ret == IntPtr.Zero) + { + throw new FileNotFoundException("Could not find or load the native library: " + name + ", Location: " + Assembly.GetExecutingAssembly().Location); + } + + return ret; + } + + /// + /// Loads a native library by name and returns an operating system handle to it. + /// + /// An ordered list of names. Each name is tried in turn, until the library is successfully loaded. + /// + /// The path resolver to use. + /// The operating system handle for the shared library. + /// + /// + public IntPtr LoadNativeLibrary(string[] names, PathResolver pathResolver) + { + if (names == null || names.Length == 0) + { + throw new ArgumentException("Parameter must not be null or empty.", nameof(names)); + } + + var ret = IntPtr.Zero; + foreach (var name in names) + { + ret = this.LoadWithResolver(name, pathResolver); + if (ret != IntPtr.Zero) + { + break; + } + } + + if (ret == IntPtr.Zero) + { + throw new FileNotFoundException($"Could not find or load the native library from any name: [ {string.Join(", ", names)} ]"); + } + + return ret; + } + + private IntPtr LoadWithResolver(string name, PathResolver pathResolver) + { + if (Path.IsPathRooted(name)) + { + return this.CoreLoadNativeLibrary(name); + } + else + { + foreach (var loadTarget in pathResolver.EnumeratePossibleLibraryLoadTargets(name)) + { + if (!Path.IsPathRooted(loadTarget) || File.Exists(loadTarget)) + { + var ret = this.CoreLoadNativeLibrary(loadTarget); + if (ret != IntPtr.Zero) + { + return ret; + } + } + } + + return IntPtr.Zero; + } + } + + /// + /// Loads a function pointer out of the given library by name. + /// + /// The operating system handle of the opened shared library. + /// The name of the exported function to load. + /// A pointer to the loaded function. + public IntPtr LoadFunctionPointer(IntPtr handle, string functionName) + { + if (string.IsNullOrEmpty(functionName)) + { + throw new ArgumentException("Parameter must not be null or empty.", nameof(functionName)); + } + + return this.CoreLoadFunctionPointer(handle, functionName); + } + + /// + /// Frees the library represented by the given operating system handle. + /// + /// The handle of the open shared library. + public void FreeNativeLibrary(IntPtr handle) + { + if (handle == IntPtr.Zero) + { + throw new ArgumentException("Parameter must not be zero.", nameof(handle)); + } + + this.CoreFreeNativeLibrary(handle); + } + + /// + /// Loads a native library by name and returns an operating system handle to it. + /// + /// The name of the library to open. This parameter must not be null or empty. + /// The operating system handle for the shared library. + /// If the library cannot be loaded, IntPtr.Zero should be returned. + protected abstract IntPtr CoreLoadNativeLibrary(string name); + + /// + /// Frees the library represented by the given operating system handle. + /// + /// The handle of the open shared library. This must not be zero. + protected abstract void CoreFreeNativeLibrary(IntPtr handle); + + /// + /// Loads a function pointer out of the given library by name. + /// + /// The operating system handle of the opened shared library. This must not be zero. + /// The name of the exported function to load. This must not be null or empty. + /// A pointer to the loaded function. + protected abstract IntPtr CoreLoadFunctionPointer(IntPtr handle, string functionName); + + /// + /// Returns a default library loader for the running operating system. + /// + /// A LibraryLoader suitable for loading libraries. + public static LibraryLoader GetPlatformDefaultLoader() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return new Win32LibraryLoader(); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return new UnixLibraryLoader(); + } + + throw new PlatformNotSupportedException("This platform cannot load native libraries."); + } + + private class Win32LibraryLoader : LibraryLoader + { + protected override void CoreFreeNativeLibrary(IntPtr handle) + { + Kernel32.FreeLibrary(handle); + } + + protected override IntPtr CoreLoadFunctionPointer(IntPtr handle, string functionName) + { + return Kernel32.GetProcAddress(handle, functionName); + } + + protected override IntPtr CoreLoadNativeLibrary(string name) + { + return Kernel32.LoadLibrary(name); + } + } + + private class UnixLibraryLoader : LibraryLoader + { + protected override void CoreFreeNativeLibrary(IntPtr handle) + { + Libdl.dlclose(handle); + } + + protected override IntPtr CoreLoadFunctionPointer(IntPtr handle, string functionName) + { + return Libdl.dlsym(handle, functionName); + } + + protected override IntPtr CoreLoadNativeLibrary(string name) + { + return Libdl.dlopen(name, Libdl.RTLD_NOW); + } + } +} diff --git a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs new file mode 100644 index 00000000..94404ec3 --- /dev/null +++ b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs @@ -0,0 +1,86 @@ +#pragma warning disable RS1035 +using System.Reflection; + +namespace Sails.ClientGenerator; + +internal static unsafe partial class NativeMethods +{ + internal static IntPtr LoadNativeLibrary() + { + // Determine where to extract the DLL + var tempDirectory = Path.Combine(Path.GetTempPath(), __DllName); + Directory.CreateDirectory(tempDirectory); + + var nativeLibraryPath = Path.Combine(tempDirectory, __DllName + ".dll"); + // Extract the DLL only if it doesn't already exist + if (!File.Exists(nativeLibraryPath)) + { + ExtractResourceToFile(__DllName + ".dll", nativeLibraryPath); + } + + //#if DEBUG + // var combinedPath = Path.Combine(AppContext.BaseDirectory, __DllName); + // if (File.Exists(combinedPath) || File.Exists(combinedPath + ".dll")) + // { + // return LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibrary(__DllName); + // } + //#endif + + // var path = "runtimes/"; + // var extension = ""; + + // if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + // { + // path += "win-"; + // extension = ".dll"; + // } + // else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + // { + // path += "osx-"; + // extension = ".dylib"; + // } + // else + // { + // path += "linux-"; + // extension = ".so"; + // } + + // if (RuntimeInformation.OSArchitecture == Architecture.X86) + // { + // path += "x86"; + // } + // else if (RuntimeInformation.OSArchitecture == Architecture.X64) + // { + // path += "x64"; + // } + // else if (RuntimeInformation.OSArchitecture == Architecture.Arm64) + // { + // path += "arm64"; + // } + + // path += "/native/" + __DllName + extension; + + // return LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibrary(__DllName); + //} + return LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibrary(__DllName, new TempPathResolver(nativeLibraryPath)); + //return IntPtr.Zero; + } + + private static void ExtractResourceToFile(string resourceName, string filePath) + { + var assembly = Assembly.GetExecutingAssembly(); + var resourceFullName = $"{assembly.GetName().Name}.{resourceName}"; + + using (var resourceStream = assembly.GetManifestResourceStream(resourceFullName)) + { + if (resourceStream == null) + { + throw new Exception($"Resource '{resourceFullName}' not found in assembly."); + } + using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) + { + resourceStream.CopyTo(fileStream); + } + } + } +} diff --git a/net/src/Sails.ClientGenerator/PathResolver.cs b/net/src/Sails.ClientGenerator/PathResolver.cs new file mode 100644 index 00000000..d5df9723 --- /dev/null +++ b/net/src/Sails.ClientGenerator/PathResolver.cs @@ -0,0 +1,65 @@ +#pragma warning disable RS1035 + +using System.Reflection; + +namespace Sails.ClientGenerator; + +/// +/// Enumerates possible library load targets. +/// +public abstract class PathResolver +{ + /// + /// Returns an enumerator which yields possible library load targets, in priority order. + /// + /// The name of the library to load. + /// An enumerator yielding load targets. + public abstract IEnumerable EnumeratePossibleLibraryLoadTargets(string name); + + /// + /// Gets a default path resolver. + /// + public static PathResolver Default { get; } = new DefaultPathResolver(); +} + +/// +/// Enumerates possible library load targets. This default implementation returns the following load targets: +/// First: The library contained in the applications base folder. +/// Second: The simple name, unchanged. +/// Third: The library as resolved via the default DependencyContext, in the default nuget package cache folder. +/// +public class DefaultPathResolver : PathResolver +{ + /// + /// Returns an enumerator which yields possible library load targets, in priority order. + /// + /// The name of the library to load. + /// An enumerator yielding load targets. + public override IEnumerable EnumeratePossibleLibraryLoadTargets(string name) + { + if (!string.IsNullOrEmpty(AppContext.BaseDirectory)) + { + yield return Path.Combine(AppContext.BaseDirectory, name); + } + if (!string.IsNullOrEmpty(Assembly.GetExecutingAssembly().Location)) + { + yield return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), name); + } + yield return name; + } +} + +public class TempPathResolver : PathResolver +{ + private readonly string path; + + public TempPathResolver(string path) + { + this.path = path; + } + + public override IEnumerable EnumeratePossibleLibraryLoadTargets(string name) + { + yield return this.path; + } +} diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index dada2751..828f3010 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -15,6 +15,7 @@ + @@ -37,40 +38,45 @@ - - + + PreserveNewest - + sails_client_gen_dotnet.dll + PreserveNewest + runtimes/linux-x64/native/libsails_client_gen_dotnet.so PreserveNewest - - - - runtimes/win-x64/native/sails_client_gen_dotnet.dll - - - runtimes/linux-x64/native/libsails_client_gen_dotnet.so - - - runtimes/osx-x64/native/libsails_client_gen_dotnet.dylib - - - runtimes/osx-arm64/native/libsails_client_gen_dotnet.dylib - - - - - - - - - + + + + + runtimes/win-x64/native/sails_client_gen_dotnet.dll + + + runtimes/linux-x64/native/libsails_client_gen_dotnet.so + + + runtimes/osx-x64/native/libsails_client_gen_dotnet.dylib + + + runtimes/osx-arm64/native/libsails_client_gen_dotnet.dylib + + + + $(TargetsForTfmSpecificContentInPackage);PackBuildOutputs + + + + + + + diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 8cbd213d..8382b887 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -17,6 +17,8 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private static unsafe void Generate(SourceProductionContext context, AdditionalText source) { + NativeMethods.LoadNativeLibrary(); + var idl = source.GetText()!.ToString(); var idlBytes = Encoding.UTF8.GetBytes(idl); @@ -32,7 +34,7 @@ private static unsafe void Generate(SourceProductionContext context, AdditionalT { var str = new string((sbyte*)cstr); var formatted = FormatCode(str); - context.AddSource($"{name}.g.cs", SourceText.From(formatted, encoding: Encoding.UTF8)); + context.AddSource($"idl/{name}.g.cs", SourceText.From(formatted, encoding: Encoding.UTF8)); } finally { diff --git a/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs b/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs index 14f8d812..7f467287 100644 --- a/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs +++ b/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs @@ -10,7 +10,6 @@ public class SailsClientGeneratorTests [ModuleInitializer] internal static void Init() => VerifySourceGenerators.Initialize(); - [Fact] public Task Generate_DemoIdl() => Verify("idl/demo.idl"); @@ -20,7 +19,7 @@ private static Task Verify(params string[] fileNames) var compilation = CSharpCompilation.Create(assemblyName: "Tests"); var additionalFiles = fileNames - .Select(x => (file: x, content: File.ReadAllText(@$"./{x}"))) + .Select(x => (file: x, content: File.ReadAllText($"./{x}"))) .Select(x => new InMemoryAdditionalText(x.file, x.content)) .ToImmutableArray(); diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs index 4427fd3f..2a87582f 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs @@ -1,5 +1,7 @@ -//HintName: demo.g.cs +//HintName: idl/demo.g.cs +using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; +using global::Sails.Remoting.Abstractions.Core; using global::System; using global::System.Collections.Generic; diff --git a/rs/client-gen-dotnet/src/ctor_generators.rs b/rs/client-gen-dotnet/src/ctor_generators.rs index 6f5110a4..f3f25cd5 100644 --- a/rs/client-gen-dotnet/src/ctor_generators.rs +++ b/rs/client-gen-dotnet/src/ctor_generators.rs @@ -26,7 +26,7 @@ impl<'a> CtorFactoryGenerator<'a> { pub(crate) fn finalize(self) -> Tokens { let class_name = format!("{}Factory", self.service_name); - let remoting = &csharp::import("global::Sails.Remoting.Abstractions", "IRemoting"); + let remoting = &csharp::import("global::Sails.Remoting.Abstractions.Core", "IRemoting"); quote! { public interface I$(&class_name)$['\r'] @@ -78,7 +78,7 @@ impl<'a> Visitor<'a> for CtorFactoryGenerator<'a> { }; let activation = &csharp::import("global::Sails.Remoting.Abstractions", "IActivation"); - let action = &csharp::import("global::Sails.Remoting.Abstractions", "RemotingAction"); + let action = &csharp::import("global::Sails.Remoting", "RemotingAction"); quote_in! { self.interface_tokens => $activation $func_name_pascal($args_with_type);$['\r'] diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/rs/client-gen-dotnet/src/service_generators.rs index 5ccd2aea..8309c913 100644 --- a/rs/client-gen-dotnet/src/service_generators.rs +++ b/rs/client-gen-dotnet/src/service_generators.rs @@ -28,7 +28,7 @@ impl<'a> ServiceClientGenerator<'a> { pub(crate) fn finalize(self) -> Tokens { let name = &self.service_name.to_case(Case::Pascal); - let remoting = &csharp::import("global::Sails.Remoting.Abstractions", "IRemoting"); + let remoting = &csharp::import("global::Sails.Remoting.Abstractions.Core", "IRemoting"); quote! { public interface I$name$['\r'] @@ -70,7 +70,7 @@ impl<'a> Visitor<'a> for ServiceClientGenerator<'a> { let args_with_type = &self.type_generator.fn_params_with_types(func.params()); let func_return_type = &self.type_generator.generate_type_decl(func.output()); - let action = &csharp::import("global::Sails.Remoting.Abstractions", "RemotingAction"); + let action = &csharp::import("global::Sails.Remoting", "RemotingAction"); quote_in! { self.interface_tokens => $return_type<$func_return_type> $func_name_pascal($args_with_type);$['\r'] From 7788dfaf5476e14aab0658eba2148435fca9d757 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Sun, 10 Nov 2024 14:14:55 +0100 Subject: [PATCH 29/54] wip: resource library loader --- .../{ => Loader}/Kernel32.cs | 2 +- .../{ => Loader}/Libdl.cs | 2 +- .../{ => Loader}/LibraryLoader.cs | 101 ++-------------- .../NativeMethods.Loader.cs | 111 +++++++++--------- net/src/Sails.ClientGenerator/PathResolver.cs | 65 ---------- .../Sails.ClientGenerator.csproj | 54 +++------ .../SailsClientGenerator.cs | 42 ++++--- ...rTests.Generate_DemoIdl#demo.g.verified.cs | 90 +++++++------- .../src/service_generators.rs | 6 +- 9 files changed, 151 insertions(+), 322 deletions(-) rename net/src/Sails.ClientGenerator/{ => Loader}/Kernel32.cs (90%) rename net/src/Sails.ClientGenerator/{ => Loader}/Libdl.cs (97%) rename net/src/Sails.ClientGenerator/{ => Loader}/LibraryLoader.cs (58%) delete mode 100644 net/src/Sails.ClientGenerator/PathResolver.cs diff --git a/net/src/Sails.ClientGenerator/Kernel32.cs b/net/src/Sails.ClientGenerator/Loader/Kernel32.cs similarity index 90% rename from net/src/Sails.ClientGenerator/Kernel32.cs rename to net/src/Sails.ClientGenerator/Loader/Kernel32.cs index 381d0c7b..632bf383 100644 --- a/net/src/Sails.ClientGenerator/Kernel32.cs +++ b/net/src/Sails.ClientGenerator/Loader/Kernel32.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace Sails.ClientGenerator; +namespace Sails.ClientGenerator.Loader; internal static class Kernel32 { diff --git a/net/src/Sails.ClientGenerator/Libdl.cs b/net/src/Sails.ClientGenerator/Loader/Libdl.cs similarity index 97% rename from net/src/Sails.ClientGenerator/Libdl.cs rename to net/src/Sails.ClientGenerator/Loader/Libdl.cs index 8670683a..6ae3bb60 100644 --- a/net/src/Sails.ClientGenerator/Libdl.cs +++ b/net/src/Sails.ClientGenerator/Loader/Libdl.cs @@ -2,7 +2,7 @@ using System.Runtime.InteropServices; -namespace Sails.ClientGenerator; +namespace Sails.ClientGenerator.Loader; internal static class Libdl { diff --git a/net/src/Sails.ClientGenerator/LibraryLoader.cs b/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs similarity index 58% rename from net/src/Sails.ClientGenerator/LibraryLoader.cs rename to net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs index fab2cb89..9925dd39 100644 --- a/net/src/Sails.ClientGenerator/LibraryLoader.cs +++ b/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs @@ -1,10 +1,8 @@ -#pragma warning disable RCS0056 // A line is too long -#pragma warning disable RS1035 // Do not use APIs banned for analyzers +#pragma warning disable RS1035 // Do not use APIs banned for analyzers -using System.Reflection; using System.Runtime.InteropServices; -namespace Sails.ClientGenerator; +namespace Sails.ClientGenerator.Loader; /// /// Exposes functionality for loading native libraries and function pointers. @@ -14,103 +12,24 @@ public abstract class LibraryLoader /// /// Loads a native library by name and returns an operating system handle to it. /// - /// The name of the library to open. - /// The operating system handle for the shared library. - public IntPtr LoadNativeLibrary(string name) - { - return this.LoadNativeLibrary(name, PathResolver.Default); - } - - /// - /// Loads a native library by name and returns an operating system handle to it. - /// - /// An ordered list of names. Each name is tried in turn, until the library is successfully loaded. - /// - /// The operating system handle for the shared library. - public IntPtr LoadNativeLibrary(string[] names) - { - return this.LoadNativeLibrary(names, PathResolver.Default); - } - - /// - /// Loads a native library by name and returns an operating system handle to it. - /// - /// The name of the library to open. - /// The path resolver to use. - /// The operating system handle for the shared library. - public IntPtr LoadNativeLibrary(string name, PathResolver pathResolver) - { - if (string.IsNullOrEmpty(name)) - { - throw new ArgumentException("Parameter must not be null or empty.", nameof(name)); - } - - var ret = this.LoadWithResolver(name, pathResolver); - - if (ret == IntPtr.Zero) - { - throw new FileNotFoundException("Could not find or load the native library: " + name + ", Location: " + Assembly.GetExecutingAssembly().Location); - } - - return ret; - } - - /// - /// Loads a native library by name and returns an operating system handle to it. - /// - /// An ordered list of names. Each name is tried in turn, until the library is successfully loaded. - /// - /// The path resolver to use. + /// An ordered list of names. Each name is tried in turn, until the library is successfully loaded. /// The operating system handle for the shared library. /// /// - public IntPtr LoadNativeLibrary(string[] names, PathResolver pathResolver) - { - if (names == null || names.Length == 0) - { - throw new ArgumentException("Parameter must not be null or empty.", nameof(names)); - } - - var ret = IntPtr.Zero; - foreach (var name in names) - { - ret = this.LoadWithResolver(name, pathResolver); - if (ret != IntPtr.Zero) - { - break; - } - } - - if (ret == IntPtr.Zero) - { - throw new FileNotFoundException($"Could not find or load the native library from any name: [ {string.Join(", ", names)} ]"); - } - - return ret; - } - - private IntPtr LoadWithResolver(string name, PathResolver pathResolver) + public IntPtr LoadNativeLibraryByPath(params string[] names) { - if (Path.IsPathRooted(name)) + foreach (var loadTarget in names!) { - return this.CoreLoadNativeLibrary(name); - } - else - { - foreach (var loadTarget in pathResolver.EnumeratePossibleLibraryLoadTargets(name)) + if (File.Exists(loadTarget)) { - if (!Path.IsPathRooted(loadTarget) || File.Exists(loadTarget)) + var ret = this.CoreLoadNativeLibrary(loadTarget); + if (ret != IntPtr.Zero) { - var ret = this.CoreLoadNativeLibrary(loadTarget); - if (ret != IntPtr.Zero) - { - return ret; - } + return ret; } } - - return IntPtr.Zero; } + return IntPtr.Zero; } /// diff --git a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs index 94404ec3..64dc340c 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs @@ -1,5 +1,8 @@ -#pragma warning disable RS1035 +#pragma warning disable RS1035 // Do not use APIs banned for analyzers + using System.Reflection; +using System.Runtime.InteropServices; +using Sails.ClientGenerator.Loader; namespace Sails.ClientGenerator; @@ -11,76 +14,68 @@ internal static IntPtr LoadNativeLibrary() var tempDirectory = Path.Combine(Path.GetTempPath(), __DllName); Directory.CreateDirectory(tempDirectory); - var nativeLibraryPath = Path.Combine(tempDirectory, __DllName + ".dll"); + var resource = GetResourceName(__DllName); + var nativeLibraryPath = Path.Combine(tempDirectory, __DllName); // Extract the DLL only if it doesn't already exist if (!File.Exists(nativeLibraryPath)) { - ExtractResourceToFile(__DllName + ".dll", nativeLibraryPath); + ExtractResourceToFile(resource, nativeLibraryPath); } + var ret = LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibraryByPath(nativeLibraryPath); + if (ret == IntPtr.Zero) + { + throw new FileNotFoundException($"Could not find or load the native library: {nativeLibraryPath}"); + } + return ret; + } - //#if DEBUG - // var combinedPath = Path.Combine(AppContext.BaseDirectory, __DllName); - // if (File.Exists(combinedPath) || File.Exists(combinedPath + ".dll")) - // { - // return LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibrary(__DllName); - // } - //#endif - - // var path = "runtimes/"; - // var extension = ""; - - // if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - // { - // path += "win-"; - // extension = ".dll"; - // } - // else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - // { - // path += "osx-"; - // extension = ".dylib"; - // } - // else - // { - // path += "linux-"; - // extension = ".so"; - // } - - // if (RuntimeInformation.OSArchitecture == Architecture.X86) - // { - // path += "x86"; - // } - // else if (RuntimeInformation.OSArchitecture == Architecture.X64) - // { - // path += "x64"; - // } - // else if (RuntimeInformation.OSArchitecture == Architecture.Arm64) - // { - // path += "arm64"; - // } + private static string GetResourceName(string dllName) + { + string platform; + string extension; - // path += "/native/" + __DllName + extension; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + platform = "win-"; + extension = ".dll"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + platform = "osx-"; + extension = ".dylib"; + } + else + { + platform = "linux-"; + extension = ".so"; + } - // return LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibrary(__DllName); - //} - return LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibrary(__DllName, new TempPathResolver(nativeLibraryPath)); - //return IntPtr.Zero; + if (RuntimeInformation.OSArchitecture == Architecture.X86) + { + platform += "x86"; + } + else if (RuntimeInformation.OSArchitecture == Architecture.X64) + { + platform += "x64"; + } + else if (RuntimeInformation.OSArchitecture == Architecture.Arm64) + { + platform += "arm64"; + } + return $"{platform}.{dllName}{extension}"; } + internal static void FreeNativeLibrary(IntPtr handle) => LibraryLoader.GetPlatformDefaultLoader().FreeNativeLibrary(handle); + private static void ExtractResourceToFile(string resourceName, string filePath) { var assembly = Assembly.GetExecutingAssembly(); - var resourceFullName = $"{assembly.GetName().Name}.{resourceName}"; - - using (var resourceStream = assembly.GetManifestResourceStream(resourceFullName)) + using var resourceStream = assembly.GetManifestResourceStream(resourceName); + if (resourceStream == null) { - if (resourceStream == null) - { - throw new Exception($"Resource '{resourceFullName}' not found in assembly."); - } - using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) - { - resourceStream.CopyTo(fileStream); - } + throw new Exception($"Resource '{resourceName}' not found in assembly."); } + using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write); + resourceStream.CopyTo(fileStream); } } diff --git a/net/src/Sails.ClientGenerator/PathResolver.cs b/net/src/Sails.ClientGenerator/PathResolver.cs deleted file mode 100644 index d5df9723..00000000 --- a/net/src/Sails.ClientGenerator/PathResolver.cs +++ /dev/null @@ -1,65 +0,0 @@ -#pragma warning disable RS1035 - -using System.Reflection; - -namespace Sails.ClientGenerator; - -/// -/// Enumerates possible library load targets. -/// -public abstract class PathResolver -{ - /// - /// Returns an enumerator which yields possible library load targets, in priority order. - /// - /// The name of the library to load. - /// An enumerator yielding load targets. - public abstract IEnumerable EnumeratePossibleLibraryLoadTargets(string name); - - /// - /// Gets a default path resolver. - /// - public static PathResolver Default { get; } = new DefaultPathResolver(); -} - -/// -/// Enumerates possible library load targets. This default implementation returns the following load targets: -/// First: The library contained in the applications base folder. -/// Second: The simple name, unchanged. -/// Third: The library as resolved via the default DependencyContext, in the default nuget package cache folder. -/// -public class DefaultPathResolver : PathResolver -{ - /// - /// Returns an enumerator which yields possible library load targets, in priority order. - /// - /// The name of the library to load. - /// An enumerator yielding load targets. - public override IEnumerable EnumeratePossibleLibraryLoadTargets(string name) - { - if (!string.IsNullOrEmpty(AppContext.BaseDirectory)) - { - yield return Path.Combine(AppContext.BaseDirectory, name); - } - if (!string.IsNullOrEmpty(Assembly.GetExecutingAssembly().Location)) - { - yield return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), name); - } - yield return name; - } -} - -public class TempPathResolver : PathResolver -{ - private readonly string path; - - public TempPathResolver(string path) - { - this.path = path; - } - - public override IEnumerable EnumeratePossibleLibraryLoadTargets(string name) - { - yield return this.path; - } -} diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 828f3010..0cf4496f 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -20,18 +20,6 @@ - - - - Always - sails_client_gen_dotnet.dll - - - Always - sails_client_gen_dotnet.pdb - - - @@ -39,40 +27,26 @@ - - PreserveNewest - sails_client_gen_dotnet.dll - - - PreserveNewest - runtimes/linux-x64/native/libsails_client_gen_dotnet.so - - - PreserveNewest - + + + + - - + + $(TargetsForTfmSpecificContentInPackage);EmbedLibraries + + + + - - runtimes/win-x64/native/sails_client_gen_dotnet.dll - - - runtimes/linux-x64/native/libsails_client_gen_dotnet.so - - - runtimes/osx-x64/native/libsails_client_gen_dotnet.dylib - - - runtimes/osx-arm64/native/libsails_client_gen_dotnet.dylib - + + + + - - $(TargetsForTfmSpecificContentInPackage);PackBuildOutputs - diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 8382b887..3942a57f 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -17,31 +17,37 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private static unsafe void Generate(SourceProductionContext context, AdditionalText source) { - NativeMethods.LoadNativeLibrary(); - - var idl = source.GetText()!.ToString(); - var idlBytes = Encoding.UTF8.GetBytes(idl); + var handle = NativeMethods.LoadNativeLibrary(); + try + { + var idl = source.GetText()!.ToString(); + var idlBytes = Encoding.UTF8.GetBytes(idl); - var name = Path.GetFileNameWithoutExtension(source.Path); - var nameBytes = Encoding.UTF8.GetBytes(name); + var name = Path.GetFileNameWithoutExtension(source.Path); + var nameBytes = Encoding.UTF8.GetBytes(name); - fixed (byte* pIdl = idlBytes) - { - fixed (byte* pName = nameBytes) + fixed (byte* pIdl = idlBytes) { - var cstr = NativeMethods.generate_dotnet_client(pIdl, idlBytes.Length, pName, nameBytes.Length); - try + fixed (byte* pName = nameBytes) { - var str = new string((sbyte*)cstr); - var formatted = FormatCode(str); - context.AddSource($"idl/{name}.g.cs", SourceText.From(formatted, encoding: Encoding.UTF8)); - } - finally - { - NativeMethods.free_c_string(cstr); + var cstr = NativeMethods.generate_dotnet_client(pIdl, idlBytes.Length, pName, nameBytes.Length); + try + { + var str = new string((sbyte*)cstr); + var formatted = FormatCode(str); + context.AddSource($"{name}.g.cs", SourceText.From(formatted, encoding: Encoding.UTF8)); + } + finally + { + NativeMethods.free_c_string(cstr); + } } } } + finally + { + NativeMethods.FreeNativeLibrary(handle); + } } public static string FormatCode(string code, CancellationToken cancelToken = default) diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs index 2a87582f..31032eb9 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs @@ -1,4 +1,4 @@ -//HintName: idl/demo.g.cs +//HintName: demo.g.cs using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; using global::Sails.Remoting.Abstractions.Core; @@ -43,9 +43,9 @@ public IActivation New(global::Substrate.NetApi.Model.Types.Base.BaseOpt Add(global::Substrate.NetApi.Model.Types.Primitive.U32 value); - global::Sails.Remoting.Abstractions.ICall Sub(global::Substrate.NetApi.Model.Types.Primitive.U32 value); - global::Sails.Remoting.Abstractions.IQuery Value(); + ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 value); + ICall Sub(global::Substrate.NetApi.Model.Types.Primitive.U32 value); + IQuery Value(); } public partial class Counter : ICounter @@ -57,19 +57,19 @@ public Counter(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 value) + public ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 value) { return new RemotingAction(this.remoting, [28, 67, 111, 117, 110, 116, 101, 114, 12, 65, 100, 100], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(value)); } /// - public global::Sails.Remoting.Abstractions.ICall Sub(global::Substrate.NetApi.Model.Types.Primitive.U32 value) + public ICall Sub(global::Substrate.NetApi.Model.Types.Primitive.U32 value) { return new RemotingAction(this.remoting, [28, 67, 111, 117, 110, 116, 101, 114, 12, 83, 117, 98], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(value)); } /// - public global::Sails.Remoting.Abstractions.IQuery Value() + public IQuery Value() { return new RemotingAction(this.remoting, [28, 67, 111, 117, 110, 116, 101, 114, 20, 86, 97, 108, 117, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } @@ -137,10 +137,10 @@ public CounterListener(global::Sails.Remoting.Abstractions.Core.IRemotingListene public interface IDog { - global::Sails.Remoting.Abstractions.ICall MakeSound(); - global::Sails.Remoting.Abstractions.ICall Walk(global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy); - global::Sails.Remoting.Abstractions.IQuery AvgWeight(); - global::Sails.Remoting.Abstractions.IQuery> Position(); + ICall MakeSound(); + ICall Walk(global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy); + IQuery AvgWeight(); + IQuery> Position(); } public partial class Dog : IDog @@ -152,25 +152,25 @@ public Dog(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall MakeSound() + public ICall MakeSound() { return new RemotingAction(this.remoting, [12, 68, 111, 103, 36, 77, 97, 107, 101, 83, 111, 117, 110, 100], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } /// - public global::Sails.Remoting.Abstractions.ICall Walk(global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy) + public ICall Walk(global::Substrate.NetApi.Model.Types.Primitive.I32 dx, global::Substrate.NetApi.Model.Types.Primitive.I32 dy) { return new RemotingAction(this.remoting, [12, 68, 111, 103, 16, 87, 97, 108, 107], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(dx, dy)); } /// - public global::Sails.Remoting.Abstractions.IQuery AvgWeight() + public IQuery AvgWeight() { return new RemotingAction(this.remoting, [12, 68, 111, 103, 36, 65, 118, 103, 87, 101, 105, 103, 104, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } /// - public global::Sails.Remoting.Abstractions.IQuery> Position() + public IQuery> Position() { return new RemotingAction>(this.remoting, [12, 68, 111, 103, 32, 80, 111, 115, 105, 116, 105, 111, 110], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } @@ -232,7 +232,7 @@ public DogListener(global::Sails.Remoting.Abstractions.Core.IRemotingListener re public interface IPingPong { - global::Sails.Remoting.Abstractions.ICall> Ping(global::Substrate.NetApi.Model.Types.Primitive.Str input); + ICall> Ping(global::Substrate.NetApi.Model.Types.Primitive.Str input); } public partial class PingPong : IPingPong @@ -244,7 +244,7 @@ public PingPong(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall> Ping(global::Substrate.NetApi.Model.Types.Primitive.Str input) + public ICall> Ping(global::Substrate.NetApi.Model.Types.Primitive.Str input) { return new RemotingAction>(this.remoting, [32, 80, 105, 110, 103, 80, 111, 110, 103, 16, 80, 105, 110, 103], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(input)); } @@ -252,14 +252,14 @@ public PingPong(IRemoting remoting) public interface IReferences { - global::Sails.Remoting.Abstractions.ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 v); - global::Sails.Remoting.Abstractions.ICall> AddByte(global::Substrate.NetApi.Model.Types.Primitive.U8 @byte); - global::Sails.Remoting.Abstractions.ICall> GuessNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number); - global::Sails.Remoting.Abstractions.ICall Incr(); - global::Sails.Remoting.Abstractions.ICall> SetNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number); - global::Sails.Remoting.Abstractions.IQuery Baked(); - global::Sails.Remoting.Abstractions.IQuery> LastByte(); - global::Sails.Remoting.Abstractions.IQuery> Message(); + ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 v); + ICall> AddByte(global::Substrate.NetApi.Model.Types.Primitive.U8 @byte); + ICall> GuessNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number); + ICall Incr(); + ICall> SetNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number); + IQuery Baked(); + IQuery> LastByte(); + IQuery> Message(); } public partial class References : IReferences @@ -271,49 +271,49 @@ public References(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 v) + public ICall Add(global::Substrate.NetApi.Model.Types.Primitive.U32 v) { return new RemotingAction(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 12, 65, 100, 100], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v)); } /// - public global::Sails.Remoting.Abstractions.ICall> AddByte(global::Substrate.NetApi.Model.Types.Primitive.U8 @byte) + public ICall> AddByte(global::Substrate.NetApi.Model.Types.Primitive.U8 @byte) { return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 28, 65, 100, 100, 66, 121, 116, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(@byte)); } /// - public global::Sails.Remoting.Abstractions.ICall> GuessNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number) + public ICall> GuessNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number) { return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 32, 71, 117, 101, 115, 115, 78, 117, 109], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number)); } /// - public global::Sails.Remoting.Abstractions.ICall Incr() + public ICall Incr() { return new RemotingAction(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 16, 73, 110, 99, 114], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } /// - public global::Sails.Remoting.Abstractions.ICall> SetNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number) + public ICall> SetNum(global::Substrate.NetApi.Model.Types.Primitive.U8 number) { return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 24, 83, 101, 116, 78, 117, 109], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(number)); } /// - public global::Sails.Remoting.Abstractions.IQuery Baked() + public IQuery Baked() { return new RemotingAction(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 20, 66, 97, 107, 101, 100], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } /// - public global::Sails.Remoting.Abstractions.IQuery> LastByte() + public IQuery> LastByte() { return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 32, 76, 97, 115, 116, 66, 121, 116, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } /// - public global::Sails.Remoting.Abstractions.IQuery> Message() + public IQuery> Message() { return new RemotingAction>(this.remoting, [40, 82, 101, 102, 101, 114, 101, 110, 99, 101, 115, 28, 77, 101, 115, 115, 97, 103, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } @@ -321,11 +321,11 @@ public References(IRemoting remoting) public interface IThisThat { - global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(DoThatParam param); - global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU8> p3, TupleStruct p4); - global::Sails.Remoting.Abstractions.ICall Noop(); - global::Sails.Remoting.Abstractions.IQuery> That(); - global::Sails.Remoting.Abstractions.IQuery This(); + ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(DoThatParam param); + ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU8> p3, TupleStruct p4); + ICall Noop(); + IQuery> That(); + IQuery This(); } public partial class ThisThat : IThisThat @@ -337,31 +337,31 @@ public ThisThat(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(DoThatParam param) + public ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(DoThatParam param) { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param)); } /// - public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU8> p3, TupleStruct p4) + public ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU8> p3, TupleStruct p4) { return new RemotingAction>(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4)); } /// - public global::Sails.Remoting.Abstractions.ICall Noop() + public ICall Noop() { return new RemotingAction(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 78, 111, 111, 112], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } /// - public global::Sails.Remoting.Abstractions.IQuery> That() + public IQuery> That() { return new RemotingAction>(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } /// - public global::Sails.Remoting.Abstractions.IQuery This() + public IQuery This() { return new RemotingAction(this.remoting, [32, 84, 104, 105, 115, 84, 104, 97, 116, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } @@ -369,7 +369,7 @@ public ThisThat(IRemoting remoting) public interface IValueFee { - global::Sails.Remoting.Abstractions.ICall DoSomethingAndTakeFee(); + ICall DoSomethingAndTakeFee(); } public partial class ValueFee : IValueFee @@ -381,7 +381,7 @@ public ValueFee(IRemoting remoting) } /// - public global::Sails.Remoting.Abstractions.ICall DoSomethingAndTakeFee() + public ICall DoSomethingAndTakeFee() { return new RemotingAction(this.remoting, [32, 86, 97, 108, 117, 101, 70, 101, 101, 84, 68, 111, 83, 111, 109, 101, 116, 104, 105, 110, 103, 65, 110, 100, 84, 97, 107, 101, 70, 101, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust()); } diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/rs/client-gen-dotnet/src/service_generators.rs index 8309c913..0cbecaaf 100644 --- a/rs/client-gen-dotnet/src/service_generators.rs +++ b/rs/client-gen-dotnet/src/service_generators.rs @@ -5,8 +5,6 @@ use genco::prelude::*; use sails_idl_parser::{ast::visitor, ast::visitor::Visitor, ast::*}; const BASE_TUPLE_RUST: &str = "global::Substrate.NetApi.Model.Types.Base.BaseTupleRust"; -const IQUERY: &str = "global::Sails.Remoting.Abstractions.IQuery"; -const ICALL: &str = "global::Sails.Remoting.Abstractions.ICall"; /// Generates a client that implements service trait pub(crate) struct ServiceClientGenerator<'a> { @@ -60,7 +58,6 @@ impl<'a> Visitor<'a> for ServiceClientGenerator<'a> { fn visit_service_func(&mut self, func: &'a ServiceFunc) { let func_name_pascal = &func.name().to_case(Case::Pascal); - let return_type = if func.is_query() { IQUERY } else { ICALL }; let service_route_bytes = path_bytes(self.service_name.as_str()).0; let func_route_bytes = path_bytes(func.name()).0; @@ -71,6 +68,9 @@ impl<'a> Visitor<'a> for ServiceClientGenerator<'a> { let func_return_type = &self.type_generator.generate_type_decl(func.output()); let action = &csharp::import("global::Sails.Remoting", "RemotingAction"); + let call = &csharp::import("global::Sails.Remoting.Abstractions", "ICall"); + let query = &csharp::import("global::Sails.Remoting.Abstractions", "IQuery"); + let return_type = if func.is_query() { query } else { call }; quote_in! { self.interface_tokens => $return_type<$func_return_type> $func_name_pascal($args_with_type);$['\r'] From 6729639c16cbc556598252e3095554f44fe57720 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Sun, 10 Nov 2024 14:19:27 +0100 Subject: [PATCH 30/54] try fix csproj --- net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 0cf4496f..99eb2319 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -28,9 +28,9 @@ - - - + + + From 3e8646727223944974aead639a9bbb55ff000dc3 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Sun, 10 Nov 2024 14:26:50 +0100 Subject: [PATCH 31/54] try fix --- net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 99eb2319..9e0a9ff6 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -28,9 +28,9 @@ - - - + + + From c43446ea1db323594a230c508d3ce96c905e26ab Mon Sep 17 00:00:00 2001 From: vobradovich Date: Sun, 10 Nov 2024 14:48:42 +0100 Subject: [PATCH 32/54] fix csproj --- .../Sails.ClientGenerator.csproj | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 9e0a9ff6..f030743a 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -33,21 +33,14 @@ - - $(TargetsForTfmSpecificContentInPackage);EmbedLibraries - - - - - - - - - - - - + + + + + + + From 7a4653121eaa69e0f06974157072fba45dbdc315 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Sun, 10 Nov 2024 14:51:52 +0100 Subject: [PATCH 33/54] fix tests --- Cargo.lock | 2 +- .../snapshots/generator__basic_works.snap | 10 +++--- .../snapshots/generator__events_works.snap | 6 ++-- .../snapshots/generator__external_types.snap | 10 +++--- .../tests/snapshots/generator__full.snap | 18 +++++----- .../generator__full_with_sails_path.snap | 18 +++++----- .../generator__multiple_services.snap | 14 ++++---- .../snapshots/generator__nonzero_works.snap | 6 ++-- .../snapshots/generator__rmrk_works.snap | 34 ++++++++++--------- 9 files changed, 67 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7830be1c..2bb7edc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6374,7 +6374,7 @@ dependencies = [ [[package]] name = "sails-client-gen-dotnet" -version = "0.6.2" +version = "0.6.3" dependencies = [ "anyhow", "convert_case 0.6.0", diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap index c5ed5982..7cefc5ca 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap @@ -2,7 +2,9 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"Basic\")" --- +using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; +using global::Sails.Remoting.Abstractions.Core; using global::System; using global::System.Collections.Generic; @@ -11,8 +13,8 @@ using global::System.Collections.Generic; namespace Basic.Client; public interface IBasic - { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); -global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); + { ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); +ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } public partial class Basic : IBasic @@ -21,9 +23,9 @@ global::Sails.Remoting.Abstractions.ICall - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } + public ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } /// - public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } + public ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [20, 66, 97, 115, 105, 99, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType { [System.Diagnostics.CodeAnalysis.AllowNull] diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap index 35c39780..393f2a12 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap @@ -2,7 +2,9 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"ServiceWithEvents\")" --- +using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; +using global::Sails.Remoting.Abstractions.Core; using global::System; using global::System.Collections.Generic; @@ -11,7 +13,7 @@ using global::System.Collections.Generic; namespace ServiceWithEvents.Client; public interface IServiceWithEvents - { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); + { ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); } public partial class ServiceWithEvents : IServiceWithEvents @@ -20,7 +22,7 @@ public interface IServiceWithEvents public ServiceWithEvents(IRemoting remoting) { this.remoting = remoting; } /// - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) { return new RemotingAction( this.remoting, [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } } + public ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) { return new RemotingAction( this.remoting, [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } } public enum ServiceWithEventsEvents { One, Two, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap index 97d876c9..d8690cab 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap @@ -2,15 +2,17 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: code --- +using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; +using global::Sails.Remoting.Abstractions.Core; #pragma warning disable RCS0056 // A line is too long namespace Service.Client; public interface IService - { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); -global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); + { ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); +ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } public partial class Service : IService @@ -19,9 +21,9 @@ global::Sails.Remoting.Abstractions.ICall - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } + public ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } /// - public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } + public ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } public enum MyParam2 { Variant1, Variant2, diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap index 1741152f..796c23c1 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full.snap @@ -2,7 +2,9 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(IDL, \"Service\")" --- +using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; +using global::Sails.Remoting.Abstractions.Core; using global::System; using global::System.Collections.Generic; @@ -32,10 +34,10 @@ IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); } public interface IService - { global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); -global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); -global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); -global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); + { ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); +ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); +IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); +IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); } public partial class Service : IService @@ -44,13 +46,13 @@ global::Sails.Remoting.Abstractions.IQuery - public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) ); } + public ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) ); } /// - public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } + public ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } /// - public global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } + public IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } } + public IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } } public enum ServiceEvents { /// diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap index 4c549040..160c0b81 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap @@ -2,7 +2,9 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: code --- +using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; +using global::Sails.Remoting.Abstractions.Core; using global::System; using global::System.Collections.Generic; @@ -29,10 +31,10 @@ IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); } public interface IService - { global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); -global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); -global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); -global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); + { ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); +ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); +IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); +IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); } public partial class Service : IService @@ -41,13 +43,13 @@ global::Sails.Remoting.Abstractions.IQuery - public global::Sails.Remoting.Abstractions.ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) ); } + public ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) ); } /// - public global::Sails.Remoting.Abstractions.ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } + public ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } /// - public global::Sails.Remoting.Abstractions.IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } + public IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } } + public IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } } [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { [System.Diagnostics.CodeAnalysis.AllowNull] public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap index 5a924157..5739587f 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap @@ -2,15 +2,17 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"Multiple\")" --- +using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; +using global::Sails.Remoting.Abstractions.Core; #pragma warning disable RCS0056 // A line is too long namespace Multiple.Client; public interface IMultiple - { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); -global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); + { ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); +ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } public partial class Multiple : IMultiple @@ -19,12 +21,12 @@ global::Sails.Remoting.Abstractions.ICall - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } + public ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } /// - public global::Sails.Remoting.Abstractions.ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } + public ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [32, 77, 117, 108, 116, 105, 112, 108, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } public interface INamed - { global::Sails.Remoting.Abstractions.IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1); + { IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1); } public partial class Named : INamed @@ -33,4 +35,4 @@ public interface INamed public Named(IRemoting remoting) { this.remoting = remoting; } /// - public global::Sails.Remoting.Abstractions.IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1) { return new RemotingAction( this.remoting, [20, 78, 97, 109, 101, 100, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } + public IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1) { return new RemotingAction( this.remoting, [20, 78, 97, 109, 101, 100, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap index 389ffc28..2d9ce3c1 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap @@ -2,7 +2,9 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"NonZeroParams\")" --- +using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; +using global::Sails.Remoting.Abstractions.Core; using global::System; using global::System.Collections.Generic; @@ -11,7 +13,7 @@ using global::System.Collections.Generic; namespace NonZeroParams.Client; public interface INonZeroParams - { global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); + { ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); } public partial class NonZeroParams : INonZeroParams @@ -20,7 +22,7 @@ public interface INonZeroParams public NonZeroParams(IRemoting remoting) { this.remoting = remoting; } /// - public global::Sails.Remoting.Abstractions.ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) { return new RemotingAction( this.remoting, [52, 78, 111, 110, 90, 101, 114, 111, 80, 97, 114, 97, 109, 115, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } } + public ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2) { return new RemotingAction( this.remoting, [52, 78, 111, 110, 90, 101, 114, 111, 80, 97, 114, 97, 109, 115, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } } [global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class MyParam : global::Substrate.NetApi.Model.Types.Base.BaseType { [System.Diagnostics.CodeAnalysis.AllowNull] diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap index 5fe5e382..c4b071b8 100644 --- a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap +++ b/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap @@ -2,7 +2,9 @@ source: rs/client-gen-dotnet/tests/generator.rs expression: "gen(idl, \"RmrkCatalog\")" --- +using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; +using global::Sails.Remoting.Abstractions.Core; using global::System; using global::System.Collections.Generic; @@ -29,14 +31,14 @@ IActivation New(); } public interface IRmrkCatalog - { global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds); -global::Sails.Remoting.Abstractions.ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts); -global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); -global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds); -global::Sails.Remoting.Abstractions.ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); -global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); -global::Sails.Remoting.Abstractions.IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); -global::Sails.Remoting.Abstractions.IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); + { ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds); +ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts); +ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); +ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds); +ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); +ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); +IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId); +IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); } public partial class RmrkCatalog : IRmrkCatalog @@ -45,21 +47,21 @@ global::Sails.Remoting.Abstractions.IQuery - public global::Sails.Remoting.Abstractions.ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds) { return new RemotingAction>, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 56, 65, 100, 100, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionIds) ); } + public ICall>, Error>> AddEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.NetApi.Model.Types.Base.BaseVec collectionIds) { return new RemotingAction>, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 56, 65, 100, 100, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionIds) ); } /// - public global::Sails.Remoting.Abstractions.ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts) { return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 32, 65, 100, 100, 80, 97, 114, 116, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(parts) ); } + public ICall, Error>> AddParts(global::Substrate.Gear.Client.Model.Types.Base.BaseDictionary parts) { return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 32, 65, 100, 100, 80, 97, 114, 116, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(parts) ); } /// - public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 109, 111, 118, 101, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) ); } + public ICall, Error>> RemoveEquippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 109, 111, 118, 101, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) ); } /// - public global::Sails.Remoting.Abstractions.ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds) { return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 44, 82, 101, 109, 111, 118, 101, 80, 97, 114, 116, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partIds) ); } + public ICall, Error>> RemoveParts(global::Substrate.NetApi.Model.Types.Base.BaseVec partIds) { return new RemotingAction, Error>>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 44, 82, 101, 109, 111, 118, 101, 80, 97, 114, 116, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partIds) ); } /// - public global::Sails.Remoting.Abstractions.ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 115, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } + public ICall> ResetEquippables(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 64, 82, 101, 115, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } /// - public global::Sails.Remoting.Abstractions.ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 76, 83, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115, 84, 111, 65, 108, 108], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } + public ICall> SetEquippablesToAll(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 76, 83, 101, 116, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101, 115, 84, 111, 65, 108, 108], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 40, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) ); } + public IQuery> Equippable(global::Substrate.NetApi.Model.Types.Primitive.U32 partId, global::Substrate.Gear.Api.Generated.Model.gprimitives.ActorId collectionId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 40, 69, 113, 117, 105, 112, 112, 97, 98, 108, 101], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId, collectionId) ); } /// - public global::Sails.Remoting.Abstractions.IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 16, 80, 97, 114, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } } + public IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId) { return new RemotingAction>( this.remoting, [44, 82, 109, 114, 107, 67, 97, 116, 97, 108, 111, 103, 16, 80, 97, 114, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(partId) ); } } public enum Error { PartIdCantBeZero, BadConfig, From 585ff20e7ab626fba0b4f7ea3d8f3e039fff7e16 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Sun, 10 Nov 2024 15:04:41 +0100 Subject: [PATCH 34/54] fix ci --- .github/workflows/net-build-client-gen.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index a8bc41a5..b825c169 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -84,10 +84,10 @@ jobs: path: native-libraries - name: Build - run: dotnet build ./net/src/Sails.ClientGenerator/ -c Release -p:Version=0.6.3-rc + run: dotnet build ./net/src/Sails.ClientGenerator/ -c Release -p:LibraryRoot=${{ github.workspace }}/native-libraries -p:Version=0.6.3-rc - name: Pack - run: dotnet pack ./net/src/Sails.ClientGenerator/ -c Release --no-build -p:LibraryRoot=${{ github.workspace }}/native-libraries -p:Version=0.6.3-rc -o ./publish + run: dotnet pack ./net/src/Sails.ClientGenerator/ -c Release --no-build -p:Version=0.6.3-rc -o ./publish - name: Upload NuGet artifact uses: actions/upload-artifact@v4 From dcb2f11fdf3a55565ee43837d947c5569d8538f2 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Sun, 10 Nov 2024 16:30:05 +0100 Subject: [PATCH 35/54] move client-gen-dotnet to new workspace --- Cargo.lock | 24 - Cargo.toml | 2 - net/rs/Cargo.lock | 875 ++++++++++++++++++ net/rs/Cargo.toml | 22 + {rs => net/rs}/client-gen-dotnet/Cargo.toml | 0 {rs => net/rs}/client-gen-dotnet/build.rs | 2 +- .../client-gen-dotnet/src/ctor_generators.rs | 0 .../client-gen-dotnet/src/events_generator.rs | 0 .../rs}/client-gen-dotnet/src/helpers.rs | 0 {rs => net/rs}/client-gen-dotnet/src/lib.rs | 0 .../client-gen-dotnet/src/root_generator.rs | 0 .../src/service_generators.rs | 0 .../client-gen-dotnet/src/type_generators.rs | 0 .../rs}/client-gen-dotnet/tests/generator.rs | 6 +- .../snapshots/generator__basic_works.snap | 0 .../snapshots/generator__events_works.snap | 0 .../snapshots/generator__external_types.snap | 0 .../tests/snapshots/generator__full.snap | 0 .../generator__full_with_sails_path.snap | 0 .../generator__multiple_services.snap | 0 .../snapshots/generator__nonzero_works.snap | 0 .../snapshots/generator__rmrk_works.snap | 0 net/rs/rust-toolchain.toml | 3 + .../Sails.ClientGenerator.csproj | 10 +- 24 files changed, 909 insertions(+), 35 deletions(-) create mode 100644 net/rs/Cargo.lock create mode 100644 net/rs/Cargo.toml rename {rs => net/rs}/client-gen-dotnet/Cargo.toml (100%) rename {rs => net/rs}/client-gen-dotnet/build.rs (70%) rename {rs => net/rs}/client-gen-dotnet/src/ctor_generators.rs (100%) rename {rs => net/rs}/client-gen-dotnet/src/events_generator.rs (100%) rename {rs => net/rs}/client-gen-dotnet/src/helpers.rs (100%) rename {rs => net/rs}/client-gen-dotnet/src/lib.rs (100%) rename {rs => net/rs}/client-gen-dotnet/src/root_generator.rs (100%) rename {rs => net/rs}/client-gen-dotnet/src/service_generators.rs (100%) rename {rs => net/rs}/client-gen-dotnet/src/type_generators.rs (100%) rename {rs => net/rs}/client-gen-dotnet/tests/generator.rs (97%) rename {rs => net/rs}/client-gen-dotnet/tests/snapshots/generator__basic_works.snap (100%) rename {rs => net/rs}/client-gen-dotnet/tests/snapshots/generator__events_works.snap (100%) rename {rs => net/rs}/client-gen-dotnet/tests/snapshots/generator__external_types.snap (100%) rename {rs => net/rs}/client-gen-dotnet/tests/snapshots/generator__full.snap (100%) rename {rs => net/rs}/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap (100%) rename {rs => net/rs}/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap (100%) rename {rs => net/rs}/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap (100%) rename {rs => net/rs}/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap (100%) create mode 100644 net/rs/rust-toolchain.toml diff --git a/Cargo.lock b/Cargo.lock index 2bb7edc2..031735b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1331,16 +1331,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "csbindgen" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c26b9831049b947d154bba920e4124053def72447be6fb106a96f483874b482a" -dependencies = [ - "regex", - "syn 2.0.87", -] - [[package]] name = "curve25519-dalek" version = "2.1.3" @@ -6372,20 +6362,6 @@ dependencies = [ "sails-idl-parser", ] -[[package]] -name = "sails-client-gen-dotnet" -version = "0.6.3" -dependencies = [ - "anyhow", - "convert_case 0.6.0", - "csbindgen", - "genco", - "insta", - "itertools 0.13.0", - "parity-scale-codec", - "sails-idl-parser", -] - [[package]] name = "sails-idl-gen" version = "0.6.3" diff --git a/Cargo.toml b/Cargo.toml index dd96216e..e1c54c07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,6 @@ members = [ "rs", "rs/cli", "rs/client-gen", - "rs/client-gen-dotnet", "rs/idl-gen", "rs/idl-meta", "rs/idl-parser", @@ -56,7 +55,6 @@ cargo-generate = "0.21" cargo_metadata = "0.18" clap = "4.5" convert-case = { package = "convert_case", version = "0.6" } -csbindgen = "1.9.3" futures = { version = "0.3", default-features = false } genco = "0.17" git-download = "0.1" diff --git a/net/rs/Cargo.lock b/net/rs/Cargo.lock new file mode 100644 index 00000000..0cdaf3f0 --- /dev/null +++ b/net/rs/Cargo.lock @@ -0,0 +1,875 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "csbindgen" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c26b9831049b947d154bba920e4124053def72447be6fb106a96f483874b482a" +dependencies = [ + "regex", + "syn 2.0.87", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "genco" +version = "0.17.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afac3cbb14db69ac9fef9cdb60d8a87e39a7a527f85a81a923436efa40ad42c6" +dependencies = [ + "genco-macros", + "relative-path", + "smallvec", +] + +[[package]] +name = "genco-macros" +version = "0.17.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "553630feadf7b76442b0849fd25fdf89b860d933623aec9693fed19af0400c78" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "insta" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9ffc4d4892617c50a928c52b2961cb5174b6fc6ebf252b2fac9d21955c48b8" +dependencies = [ + "console", + "lazy_static", + "linked-hash-map", + "similar", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "lalrpop" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools 0.11.0", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax 0.8.5", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "logos" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" +dependencies = [ + "beef", + "fnv", + "proc-macro2", + "quote", + "regex-syntax 0.6.29", + "syn 2.0.87", +] + +[[package]] +name = "logos-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" +dependencies = [ + "logos-codegen", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "serde", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "sails-client-gen-dotnet" +version = "0.6.3" +dependencies = [ + "anyhow", + "convert_case", + "csbindgen", + "genco", + "insta", + "itertools 0.13.0", + "parity-scale-codec", + "sails-idl-parser", +] + +[[package]] +name = "sails-idl-parser" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de89ffc59a12dbbc342b61a44264b4cf9e209da373b317ad556da6af0c3a65e1" +dependencies = [ + "lalrpop", + "lalrpop-util", + "logos", + "thiserror", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.214" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.214" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "similar" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] diff --git a/net/rs/Cargo.toml b/net/rs/Cargo.toml new file mode 100644 index 00000000..042b87af --- /dev/null +++ b/net/rs/Cargo.toml @@ -0,0 +1,22 @@ +[workspace.package] +version = "0.6.3" +authors = ["Gear Technologies"] +edition = "2021" +license = "GPL-3.0" +repository = "https://github.com/gear-tech/sails" + +[workspace] +resolver = "2" +members = ["client-gen-dotnet"] + +[workspace.dependencies] +# sails +sails-idl-parser = "=0.6.3" +# others +anyhow = "1" +convert-case = { package = "convert_case", version = "0.6" } +csbindgen = "1.9.3" +genco = "0.17" +insta = "1.41" +itertools = "0.13" +parity-scale-codec = "3.6" diff --git a/rs/client-gen-dotnet/Cargo.toml b/net/rs/client-gen-dotnet/Cargo.toml similarity index 100% rename from rs/client-gen-dotnet/Cargo.toml rename to net/rs/client-gen-dotnet/Cargo.toml diff --git a/rs/client-gen-dotnet/build.rs b/net/rs/client-gen-dotnet/build.rs similarity index 70% rename from rs/client-gen-dotnet/build.rs rename to net/rs/client-gen-dotnet/build.rs index 6bb55191..909fd086 100644 --- a/rs/client-gen-dotnet/build.rs +++ b/net/rs/client-gen-dotnet/build.rs @@ -3,6 +3,6 @@ fn main() { .input_extern_file("src/lib.rs") .csharp_dll_name("sails_client_gen_dotnet") .csharp_namespace("Sails.ClientGenerator") - .generate_csharp_file("../../net/src/Sails.ClientGenerator/NativeMethods.g.cs") + .generate_csharp_file("../../src/Sails.ClientGenerator/NativeMethods.g.cs") .unwrap(); } diff --git a/rs/client-gen-dotnet/src/ctor_generators.rs b/net/rs/client-gen-dotnet/src/ctor_generators.rs similarity index 100% rename from rs/client-gen-dotnet/src/ctor_generators.rs rename to net/rs/client-gen-dotnet/src/ctor_generators.rs diff --git a/rs/client-gen-dotnet/src/events_generator.rs b/net/rs/client-gen-dotnet/src/events_generator.rs similarity index 100% rename from rs/client-gen-dotnet/src/events_generator.rs rename to net/rs/client-gen-dotnet/src/events_generator.rs diff --git a/rs/client-gen-dotnet/src/helpers.rs b/net/rs/client-gen-dotnet/src/helpers.rs similarity index 100% rename from rs/client-gen-dotnet/src/helpers.rs rename to net/rs/client-gen-dotnet/src/helpers.rs diff --git a/rs/client-gen-dotnet/src/lib.rs b/net/rs/client-gen-dotnet/src/lib.rs similarity index 100% rename from rs/client-gen-dotnet/src/lib.rs rename to net/rs/client-gen-dotnet/src/lib.rs diff --git a/rs/client-gen-dotnet/src/root_generator.rs b/net/rs/client-gen-dotnet/src/root_generator.rs similarity index 100% rename from rs/client-gen-dotnet/src/root_generator.rs rename to net/rs/client-gen-dotnet/src/root_generator.rs diff --git a/rs/client-gen-dotnet/src/service_generators.rs b/net/rs/client-gen-dotnet/src/service_generators.rs similarity index 100% rename from rs/client-gen-dotnet/src/service_generators.rs rename to net/rs/client-gen-dotnet/src/service_generators.rs diff --git a/rs/client-gen-dotnet/src/type_generators.rs b/net/rs/client-gen-dotnet/src/type_generators.rs similarity index 100% rename from rs/client-gen-dotnet/src/type_generators.rs rename to net/rs/client-gen-dotnet/src/type_generators.rs diff --git a/rs/client-gen-dotnet/tests/generator.rs b/net/rs/client-gen-dotnet/tests/generator.rs similarity index 97% rename from rs/client-gen-dotnet/tests/generator.rs rename to net/rs/client-gen-dotnet/tests/generator.rs index 6131a442..a7c5feff 100644 --- a/rs/client-gen-dotnet/tests/generator.rs +++ b/net/rs/client-gen-dotnet/tests/generator.rs @@ -4,7 +4,7 @@ use sails_client_gen_dotnet::ClientGenerator; fn full() { const IDL: &str = r#" // Comments are supported but ignored by idl-parser - + /// ThisThatSvcAppTupleStruct docs type ThisThatSvcAppTupleStruct = struct { /// field `bool` @@ -23,7 +23,7 @@ fn full() { /// ThisThatSvcAppManyVariants docs type ThisThatSvcAppManyVariants = enum { - /// variant `One` + /// variant `One` One, /// variant `Two` Two: u32, @@ -109,7 +109,7 @@ fn test_multiple_services() { #[test] fn test_rmrk_works() { - let idl = include_str!("../../../examples/rmrk/catalog/wasm/rmrk-catalog.idl"); + let idl = include_str!("../../../../examples/rmrk/catalog/wasm/rmrk-catalog.idl"); insta::assert_snapshot!(gen(idl, "RmrkCatalog")); } diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap b/net/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap similarity index 100% rename from rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap rename to net/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap b/net/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap similarity index 100% rename from rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap rename to net/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap b/net/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap similarity index 100% rename from rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap rename to net/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/net/rs/client-gen-dotnet/tests/snapshots/generator__full.snap similarity index 100% rename from rs/client-gen-dotnet/tests/snapshots/generator__full.snap rename to net/rs/client-gen-dotnet/tests/snapshots/generator__full.snap diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/net/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap similarity index 100% rename from rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap rename to net/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap b/net/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap similarity index 100% rename from rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap rename to net/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap b/net/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap similarity index 100% rename from rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap rename to net/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap diff --git a/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap b/net/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap similarity index 100% rename from rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap rename to net/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap diff --git a/net/rs/rust-toolchain.toml b/net/rs/rust-toolchain.toml new file mode 100644 index 00000000..2394ecae --- /dev/null +++ b/net/rs/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "stable" +components = ["rustfmt", "clippy", "rust-src"] diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index f030743a..6b93021b 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -22,15 +22,15 @@ - + - - - - + + + + From 0812aabe2fd44a0eca20becaf8f12766dfadd2ab Mon Sep 17 00:00:00 2001 From: vobradovich Date: Sun, 10 Nov 2024 16:35:02 +0100 Subject: [PATCH 36/54] update ci --- .github/workflows/net-build-client-gen.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index b825c169..dfaee50f 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -6,13 +6,13 @@ on: - master paths: - '.github/workflows/net-build-client-gen.yml' - - 'rs/client-gen-dotnet/**' + - 'net/rs/**' - 'rs/idl-parser/**' pull_request: paths: - '.github/workflows/net-build-client-gen.yml' - - 'rs/client-gen-dotnet/**' + - 'net/rs/**' - 'rs/idl-parser/**' jobs: @@ -21,11 +21,11 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v4 - - run: cargo build -p sails-client-gen-dotnet --release + - run: cargo build --manifest-path net/rs/Cargo.toml --release - uses: actions/upload-artifact@v4 with: name: win-x64 - path: ./target/release/sails_client_gen_dotnet.dll + path: ./net/rs/target/release/sails_client_gen_dotnet.dll retention-days: 1 overwrite: true @@ -33,11 +33,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: cargo build -p sails-client-gen-dotnet --release + - run: cargo build --manifest-path net/rs/Cargo.toml --release - uses: actions/upload-artifact@v4 with: name: linux-x64 - path: ./target/release/libsails_client_gen_dotnet.so + path: ./net/rs/target/release/libsails_client_gen_dotnet.so retention-days: 1 overwrite: true @@ -46,11 +46,11 @@ jobs: steps: - uses: actions/checkout@v4 - run: rustup target add x86_64-apple-darwin - - run: cargo build -p sails-client-gen-dotnet --release --target x86_64-apple-darwin + - run: cargo build --manifest-path net/rs/Cargo.toml --release --target x86_64-apple-darwin - uses: actions/upload-artifact@v4 with: name: osx-x64 - path: ./target/x86_64-apple-darwin/release/libsails_client_gen_dotnet.dylib + path: ./net/rs/target/x86_64-apple-darwin/release/libsails_client_gen_dotnet.dylib retention-days: 1 overwrite: true @@ -59,11 +59,11 @@ jobs: steps: - uses: actions/checkout@v4 - run: rustup target add aarch64-apple-darwin - - run: cargo build -p sails-client-gen-dotnet --release --target aarch64-apple-darwin + - run: cargo build --manifest-path net/rs/Cargo.toml --release --target aarch64-apple-darwin - uses: actions/upload-artifact@v4 with: name: osx-arm64 - path: ./target/aarch64-apple-darwin/release/libsails_client_gen_dotnet.dylib + path: ./net/rs/target/aarch64-apple-darwin/release/libsails_client_gen_dotnet.dylib retention-days: 1 overwrite: true From 199239a2092a8ee8f290581781399a680d35496f Mon Sep 17 00:00:00 2001 From: vobradovich Date: Sun, 10 Nov 2024 17:36:47 +0100 Subject: [PATCH 37/54] improve SailsClientGenerator --- .../SailsClientGenerator.cs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 3942a57f..28d9f9ce 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -10,20 +10,21 @@ public partial class SailsClientGenerator : IIncrementalGenerator { public void Initialize(IncrementalGeneratorInitializationContext context) { - var source = context.AdditionalTextsProvider.Where(static file => file.Path.EndsWith(".idl")); + var source = context.AdditionalTextsProvider + .Where(static file => file.Path.EndsWith(".idl")) + .Select(static (text, cancellationToken) => + GenerateCode(Path.GetFileNameWithoutExtension(text.Path), text.GetText(cancellationToken)!.ToString()) + ); - context.RegisterSourceOutput(source, Generate); + context.RegisterSourceOutput(source, AddSource); } - private static unsafe void Generate(SourceProductionContext context, AdditionalText source) + private static unsafe (string Name, string Code) GenerateCode(string name, string source) { var handle = NativeMethods.LoadNativeLibrary(); try { - var idl = source.GetText()!.ToString(); - var idlBytes = Encoding.UTF8.GetBytes(idl); - - var name = Path.GetFileNameWithoutExtension(source.Path); + var idlBytes = Encoding.UTF8.GetBytes(source); var nameBytes = Encoding.UTF8.GetBytes(name); fixed (byte* pIdl = idlBytes) @@ -34,8 +35,7 @@ private static unsafe void Generate(SourceProductionContext context, AdditionalT try { var str = new string((sbyte*)cstr); - var formatted = FormatCode(str); - context.AddSource($"{name}.g.cs", SourceText.From(formatted, encoding: Encoding.UTF8)); + return (name, FormatCode(str)); } finally { @@ -50,6 +50,11 @@ private static unsafe void Generate(SourceProductionContext context, AdditionalT } } + private static void AddSource(SourceProductionContext context, (string Name, string Code) source) + { + context.AddSource($"{source.Name}.g.cs", SourceText.From(source.Code, encoding: Encoding.UTF8)); + } + public static string FormatCode(string code, CancellationToken cancelToken = default) => CSharpSyntaxTree.ParseText(code, cancellationToken: cancelToken) .GetRoot(cancelToken) From 6e99033e4b4d27a976d61614b14d0278a3c1ae6e Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 12 Nov 2024 12:11:48 +0100 Subject: [PATCH 38/54] rename to sails_net_client_gen --- .github/workflows/net-build-client-gen.yml | 8 +++--- net/rs/Cargo.lock | 26 +++++++++---------- net/rs/Cargo.toml | 4 +-- .../Cargo.toml | 2 +- .../build.rs | 2 +- .../src/ctor_generators.rs | 0 .../src/events_generator.rs | 0 .../src/helpers.rs | 0 .../src/lib.rs | 2 +- .../src/root_generator.rs | 0 .../src/service_generators.rs | 0 .../src/type_generators.rs | 0 .../tests/generator.rs | 2 +- .../snapshots/generator__basic_works.snap | 2 +- .../snapshots/generator__events_works.snap | 2 +- .../snapshots/generator__external_types.snap | 2 +- .../tests/snapshots/generator__full.snap | 2 +- .../generator__full_with_sails_path.snap | 2 +- .../generator__multiple_services.snap | 2 +- .../snapshots/generator__nonzero_works.snap | 2 +- .../snapshots/generator__rmrk_works.snap | 2 +- .../NativeMethods.Loader.cs | 14 +++++----- .../Sails.ClientGenerator/NativeMethods.g.cs | 2 +- .../Sails.ClientGenerator.csproj | 22 ++++++++-------- .../SailsClientGenerator.cs | 2 ++ 25 files changed, 52 insertions(+), 50 deletions(-) rename net/rs/{client-gen-dotnet => client-gen}/Cargo.toml (94%) rename net/rs/{client-gen-dotnet => client-gen}/build.rs (82%) rename net/rs/{client-gen-dotnet => client-gen}/src/ctor_generators.rs (100%) rename net/rs/{client-gen-dotnet => client-gen}/src/events_generator.rs (100%) rename net/rs/{client-gen-dotnet => client-gen}/src/helpers.rs (100%) rename net/rs/{client-gen-dotnet => client-gen}/src/lib.rs (98%) rename net/rs/{client-gen-dotnet => client-gen}/src/root_generator.rs (100%) rename net/rs/{client-gen-dotnet => client-gen}/src/service_generators.rs (100%) rename net/rs/{client-gen-dotnet => client-gen}/src/type_generators.rs (100%) rename net/rs/{client-gen-dotnet => client-gen}/tests/generator.rs (99%) rename net/rs/{client-gen-dotnet => client-gen}/tests/snapshots/generator__basic_works.snap (98%) rename net/rs/{client-gen-dotnet => client-gen}/tests/snapshots/generator__events_works.snap (99%) rename net/rs/{client-gen-dotnet => client-gen}/tests/snapshots/generator__external_types.snap (98%) rename net/rs/{client-gen-dotnet => client-gen}/tests/snapshots/generator__full.snap (99%) rename net/rs/{client-gen-dotnet => client-gen}/tests/snapshots/generator__full_with_sails_path.snap (99%) rename net/rs/{client-gen-dotnet => client-gen}/tests/snapshots/generator__multiple_services.snap (97%) rename net/rs/{client-gen-dotnet => client-gen}/tests/snapshots/generator__nonzero_works.snap (98%) rename net/rs/{client-gen-dotnet => client-gen}/tests/snapshots/generator__rmrk_works.snap (99%) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index dfaee50f..e4499cde 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/upload-artifact@v4 with: name: win-x64 - path: ./net/rs/target/release/sails_client_gen_dotnet.dll + path: ./net/rs/target/release/sails_net_client_gen.dll retention-days: 1 overwrite: true @@ -37,7 +37,7 @@ jobs: - uses: actions/upload-artifact@v4 with: name: linux-x64 - path: ./net/rs/target/release/libsails_client_gen_dotnet.so + path: ./net/rs/target/release/libsails_net_client_gen.so retention-days: 1 overwrite: true @@ -50,7 +50,7 @@ jobs: - uses: actions/upload-artifact@v4 with: name: osx-x64 - path: ./net/rs/target/x86_64-apple-darwin/release/libsails_client_gen_dotnet.dylib + path: ./net/rs/target/x86_64-apple-darwin/release/libsails_net_client_gen.dylib retention-days: 1 overwrite: true @@ -63,7 +63,7 @@ jobs: - uses: actions/upload-artifact@v4 with: name: osx-arm64 - path: ./net/rs/target/aarch64-apple-darwin/release/libsails_client_gen_dotnet.dylib + path: ./net/rs/target/aarch64-apple-darwin/release/libsails_net_client_gen.dylib retention-days: 1 overwrite: true diff --git a/net/rs/Cargo.lock b/net/rs/Cargo.lock index 0cdaf3f0..e0e9d1ad 100644 --- a/net/rs/Cargo.lock +++ b/net/rs/Cargo.lock @@ -559,7 +559,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] -name = "sails-client-gen-dotnet" +name = "sails-idl-parser" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de89ffc59a12dbbc342b61a44264b4cf9e209da373b317ad556da6af0c3a65e1" +dependencies = [ + "lalrpop", + "lalrpop-util", + "logos", + "thiserror", +] + +[[package]] +name = "sails-net-client-gen" version = "0.6.3" dependencies = [ "anyhow", @@ -572,18 +584,6 @@ dependencies = [ "sails-idl-parser", ] -[[package]] -name = "sails-idl-parser" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de89ffc59a12dbbc342b61a44264b4cf9e209da373b317ad556da6af0c3a65e1" -dependencies = [ - "lalrpop", - "lalrpop-util", - "logos", - "thiserror", -] - [[package]] name = "same-file" version = "1.0.6" diff --git a/net/rs/Cargo.toml b/net/rs/Cargo.toml index 042b87af..368e36bd 100644 --- a/net/rs/Cargo.toml +++ b/net/rs/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/gear-tech/sails" [workspace] resolver = "2" -members = ["client-gen-dotnet"] +members = ["client-gen"] [workspace.dependencies] # sails @@ -15,7 +15,7 @@ sails-idl-parser = "=0.6.3" # others anyhow = "1" convert-case = { package = "convert_case", version = "0.6" } -csbindgen = "1.9.3" +csbindgen = "1.9" genco = "0.17" insta = "1.41" itertools = "0.13" diff --git a/net/rs/client-gen-dotnet/Cargo.toml b/net/rs/client-gen/Cargo.toml similarity index 94% rename from net/rs/client-gen-dotnet/Cargo.toml rename to net/rs/client-gen/Cargo.toml index 490d91aa..199152a7 100644 --- a/net/rs/client-gen-dotnet/Cargo.toml +++ b/net/rs/client-gen/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "sails-client-gen-dotnet" +name = "sails-net-client-gen" description = "Rust .NET client generator for the Sails framework" documentation = "https://docs.rs/sails-client-gen" version.workspace = true diff --git a/net/rs/client-gen-dotnet/build.rs b/net/rs/client-gen/build.rs similarity index 82% rename from net/rs/client-gen-dotnet/build.rs rename to net/rs/client-gen/build.rs index 909fd086..589ff5c5 100644 --- a/net/rs/client-gen-dotnet/build.rs +++ b/net/rs/client-gen/build.rs @@ -1,7 +1,7 @@ fn main() { csbindgen::Builder::default() .input_extern_file("src/lib.rs") - .csharp_dll_name("sails_client_gen_dotnet") + .csharp_dll_name("sails_net_client_gen") .csharp_namespace("Sails.ClientGenerator") .generate_csharp_file("../../src/Sails.ClientGenerator/NativeMethods.g.cs") .unwrap(); diff --git a/net/rs/client-gen-dotnet/src/ctor_generators.rs b/net/rs/client-gen/src/ctor_generators.rs similarity index 100% rename from net/rs/client-gen-dotnet/src/ctor_generators.rs rename to net/rs/client-gen/src/ctor_generators.rs diff --git a/net/rs/client-gen-dotnet/src/events_generator.rs b/net/rs/client-gen/src/events_generator.rs similarity index 100% rename from net/rs/client-gen-dotnet/src/events_generator.rs rename to net/rs/client-gen/src/events_generator.rs diff --git a/net/rs/client-gen-dotnet/src/helpers.rs b/net/rs/client-gen/src/helpers.rs similarity index 100% rename from net/rs/client-gen-dotnet/src/helpers.rs rename to net/rs/client-gen/src/helpers.rs diff --git a/net/rs/client-gen-dotnet/src/lib.rs b/net/rs/client-gen/src/lib.rs similarity index 98% rename from net/rs/client-gen-dotnet/src/lib.rs rename to net/rs/client-gen/src/lib.rs index bf6a9b3b..7e1e1182 100644 --- a/net/rs/client-gen-dotnet/src/lib.rs +++ b/net/rs/client-gen/src/lib.rs @@ -44,7 +44,7 @@ impl<'a, S> ClientGenerator<'a, S> { /// /// Following code generates `use my_crate::MyParam as MyFuncParam;` /// ``` - /// let code = sails_client_gen_dotnet::ClientGenerator::from_idl("") + /// let code = sails_net_client_gen::ClientGenerator::from_idl("") /// .with_external_type("MyFuncParam", "my_crate::MyParam"); /// ``` pub fn with_external_type(self, name: &'a str, path: &'a str) -> Self { diff --git a/net/rs/client-gen-dotnet/src/root_generator.rs b/net/rs/client-gen/src/root_generator.rs similarity index 100% rename from net/rs/client-gen-dotnet/src/root_generator.rs rename to net/rs/client-gen/src/root_generator.rs diff --git a/net/rs/client-gen-dotnet/src/service_generators.rs b/net/rs/client-gen/src/service_generators.rs similarity index 100% rename from net/rs/client-gen-dotnet/src/service_generators.rs rename to net/rs/client-gen/src/service_generators.rs diff --git a/net/rs/client-gen-dotnet/src/type_generators.rs b/net/rs/client-gen/src/type_generators.rs similarity index 100% rename from net/rs/client-gen-dotnet/src/type_generators.rs rename to net/rs/client-gen/src/type_generators.rs diff --git a/net/rs/client-gen-dotnet/tests/generator.rs b/net/rs/client-gen/tests/generator.rs similarity index 99% rename from net/rs/client-gen-dotnet/tests/generator.rs rename to net/rs/client-gen/tests/generator.rs index a7c5feff..8f2714cf 100644 --- a/net/rs/client-gen-dotnet/tests/generator.rs +++ b/net/rs/client-gen/tests/generator.rs @@ -1,4 +1,4 @@ -use sails_client_gen_dotnet::ClientGenerator; +use sails_net_client_gen::ClientGenerator; #[test] fn full() { diff --git a/net/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap b/net/rs/client-gen/tests/snapshots/generator__basic_works.snap similarity index 98% rename from net/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap rename to net/rs/client-gen/tests/snapshots/generator__basic_works.snap index 7cefc5ca..214bf57d 100644 --- a/net/rs/client-gen-dotnet/tests/snapshots/generator__basic_works.snap +++ b/net/rs/client-gen/tests/snapshots/generator__basic_works.snap @@ -1,5 +1,5 @@ --- -source: rs/client-gen-dotnet/tests/generator.rs +source: client-gen/tests/generator.rs expression: "gen(idl, \"Basic\")" --- using global::Sails.Remoting; diff --git a/net/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap b/net/rs/client-gen/tests/snapshots/generator__events_works.snap similarity index 99% rename from net/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap rename to net/rs/client-gen/tests/snapshots/generator__events_works.snap index 393f2a12..74668ca6 100644 --- a/net/rs/client-gen-dotnet/tests/snapshots/generator__events_works.snap +++ b/net/rs/client-gen/tests/snapshots/generator__events_works.snap @@ -1,5 +1,5 @@ --- -source: rs/client-gen-dotnet/tests/generator.rs +source: client-gen/tests/generator.rs expression: "gen(idl, \"ServiceWithEvents\")" --- using global::Sails.Remoting; diff --git a/net/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap b/net/rs/client-gen/tests/snapshots/generator__external_types.snap similarity index 98% rename from net/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap rename to net/rs/client-gen/tests/snapshots/generator__external_types.snap index d8690cab..d508632f 100644 --- a/net/rs/client-gen-dotnet/tests/snapshots/generator__external_types.snap +++ b/net/rs/client-gen/tests/snapshots/generator__external_types.snap @@ -1,5 +1,5 @@ --- -source: rs/client-gen-dotnet/tests/generator.rs +source: client-gen/tests/generator.rs expression: code --- using global::Sails.Remoting; diff --git a/net/rs/client-gen-dotnet/tests/snapshots/generator__full.snap b/net/rs/client-gen/tests/snapshots/generator__full.snap similarity index 99% rename from net/rs/client-gen-dotnet/tests/snapshots/generator__full.snap rename to net/rs/client-gen/tests/snapshots/generator__full.snap index 796c23c1..d9367bd4 100644 --- a/net/rs/client-gen-dotnet/tests/snapshots/generator__full.snap +++ b/net/rs/client-gen/tests/snapshots/generator__full.snap @@ -1,5 +1,5 @@ --- -source: rs/client-gen-dotnet/tests/generator.rs +source: client-gen/tests/generator.rs expression: "gen(IDL, \"Service\")" --- using global::Sails.Remoting; diff --git a/net/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap b/net/rs/client-gen/tests/snapshots/generator__full_with_sails_path.snap similarity index 99% rename from net/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap rename to net/rs/client-gen/tests/snapshots/generator__full_with_sails_path.snap index 160c0b81..be0802fd 100644 --- a/net/rs/client-gen-dotnet/tests/snapshots/generator__full_with_sails_path.snap +++ b/net/rs/client-gen/tests/snapshots/generator__full_with_sails_path.snap @@ -1,5 +1,5 @@ --- -source: rs/client-gen-dotnet/tests/generator.rs +source: client-gen/tests/generator.rs expression: code --- using global::Sails.Remoting; diff --git a/net/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap b/net/rs/client-gen/tests/snapshots/generator__multiple_services.snap similarity index 97% rename from net/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap rename to net/rs/client-gen/tests/snapshots/generator__multiple_services.snap index 5739587f..5c1fb1b9 100644 --- a/net/rs/client-gen-dotnet/tests/snapshots/generator__multiple_services.snap +++ b/net/rs/client-gen/tests/snapshots/generator__multiple_services.snap @@ -1,5 +1,5 @@ --- -source: rs/client-gen-dotnet/tests/generator.rs +source: client-gen/tests/generator.rs expression: "gen(idl, \"Multiple\")" --- using global::Sails.Remoting; diff --git a/net/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap b/net/rs/client-gen/tests/snapshots/generator__nonzero_works.snap similarity index 98% rename from net/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap rename to net/rs/client-gen/tests/snapshots/generator__nonzero_works.snap index 2d9ce3c1..1f67c02f 100644 --- a/net/rs/client-gen-dotnet/tests/snapshots/generator__nonzero_works.snap +++ b/net/rs/client-gen/tests/snapshots/generator__nonzero_works.snap @@ -1,5 +1,5 @@ --- -source: rs/client-gen-dotnet/tests/generator.rs +source: client-gen/tests/generator.rs expression: "gen(idl, \"NonZeroParams\")" --- using global::Sails.Remoting; diff --git a/net/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap b/net/rs/client-gen/tests/snapshots/generator__rmrk_works.snap similarity index 99% rename from net/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap rename to net/rs/client-gen/tests/snapshots/generator__rmrk_works.snap index c4b071b8..00357b9c 100644 --- a/net/rs/client-gen-dotnet/tests/snapshots/generator__rmrk_works.snap +++ b/net/rs/client-gen/tests/snapshots/generator__rmrk_works.snap @@ -1,5 +1,5 @@ --- -source: rs/client-gen-dotnet/tests/generator.rs +source: client-gen/tests/generator.rs expression: "gen(idl, \"RmrkCatalog\")" --- using global::Sails.Remoting; diff --git a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs index 64dc340c..663ee6fd 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs @@ -14,12 +14,12 @@ internal static IntPtr LoadNativeLibrary() var tempDirectory = Path.Combine(Path.GetTempPath(), __DllName); Directory.CreateDirectory(tempDirectory); - var resource = GetResourceName(__DllName); - var nativeLibraryPath = Path.Combine(tempDirectory, __DllName); + var (platform, extension) = GetResourcePlatform(); + var nativeLibraryPath = Path.Combine(tempDirectory, __DllName + extension); // Extract the DLL only if it doesn't already exist if (!File.Exists(nativeLibraryPath)) { - ExtractResourceToFile(resource, nativeLibraryPath); + ExtractResourceToFile($"{platform}.{__DllName}{extension}", nativeLibraryPath); } var ret = LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibraryByPath(nativeLibraryPath); if (ret == IntPtr.Zero) @@ -29,7 +29,9 @@ internal static IntPtr LoadNativeLibrary() return ret; } - private static string GetResourceName(string dllName) + internal static void FreeNativeLibrary(IntPtr handle) => LibraryLoader.GetPlatformDefaultLoader().FreeNativeLibrary(handle); + + private static (string Platform, string Extension) GetResourcePlatform() { string platform; string extension; @@ -62,11 +64,9 @@ private static string GetResourceName(string dllName) { platform += "arm64"; } - return $"{platform}.{dllName}{extension}"; + return (platform, extension); } - internal static void FreeNativeLibrary(IntPtr handle) => LibraryLoader.GetPlatformDefaultLoader().FreeNativeLibrary(handle); - private static void ExtractResourceToFile(string resourceName, string filePath) { var assembly = Assembly.GetExecutingAssembly(); diff --git a/net/src/Sails.ClientGenerator/NativeMethods.g.cs b/net/src/Sails.ClientGenerator/NativeMethods.g.cs index 68809021..ded815e0 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.g.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.g.cs @@ -12,7 +12,7 @@ namespace Sails.ClientGenerator { internal static unsafe partial class NativeMethods { - const string __DllName = "sails_client_gen_dotnet"; + const string __DllName = "sails_net_client_gen"; diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 6b93021b..05845ea4 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -20,27 +20,27 @@ - + - - - - - + + + + + - - - - + + + + - + diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 28d9f9ce..1c2944ad 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -16,6 +16,8 @@ public void Initialize(IncrementalGeneratorInitializationContext context) GenerateCode(Path.GetFileNameWithoutExtension(text.Path), text.GetText(cancellationToken)!.ToString()) ); + var compilationAndFiles = context.CompilationProvider.Combine(source.Collect()); + context.RegisterSourceOutput(source, AddSource); } From c930cec2ebf633bb932213a36e45e4785f8378c3 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 12 Nov 2024 14:25:46 +0100 Subject: [PATCH 39/54] wip: add generator config, add namespace --- net/rs/Cargo.lock | 26 +++++ net/rs/Cargo.toml | 2 + net/rs/client-gen/Cargo.toml | 4 +- net/rs/client-gen/src/lib.rs | 89 ++++----------- net/rs/client-gen/src/root_generator.rs | 6 +- net/rs/client-gen/tests/generator.rs | 78 +------------ .../snapshots/generator__external_types.snap | 38 ------- .../generator__full_with_sails_path.snap | 105 ------------------ .../Sails.ClientGenerator/GeneratorConfig.cs | 10 ++ .../Sails.ClientGenerator/NativeMethods.g.cs | 2 +- .../SailsClientGenerator.cs | 70 ++++++++---- .../SailsClientGeneratorTests.cs | 2 +- ...rTests.Generate_DemoIdl#demo.g.verified.cs | 4 +- 13 files changed, 122 insertions(+), 314 deletions(-) delete mode 100644 net/rs/client-gen/tests/snapshots/generator__external_types.snap delete mode 100644 net/rs/client-gen/tests/snapshots/generator__full_with_sails_path.snap create mode 100644 net/src/Sails.ClientGenerator/GeneratorConfig.cs diff --git a/net/rs/Cargo.lock b/net/rs/Cargo.lock index e0e9d1ad..f057dfeb 100644 --- a/net/rs/Cargo.lock +++ b/net/rs/Cargo.lock @@ -282,6 +282,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "lalrpop" version = "0.20.2" @@ -558,6 +564,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + [[package]] name = "sails-idl-parser" version = "0.6.3" @@ -582,6 +594,8 @@ dependencies = [ "itertools 0.13.0", "parity-scale-codec", "sails-idl-parser", + "serde", + "serde_json", ] [[package]] @@ -619,6 +633,18 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "similar" version = "2.6.0" diff --git a/net/rs/Cargo.toml b/net/rs/Cargo.toml index 368e36bd..8dc05dd7 100644 --- a/net/rs/Cargo.toml +++ b/net/rs/Cargo.toml @@ -20,3 +20,5 @@ genco = "0.17" insta = "1.41" itertools = "0.13" parity-scale-codec = "3.6" +serde = { version = "1.0", features = ["derive"] } +serde-json = { package = "serde_json", version = "1.0" } diff --git a/net/rs/client-gen/Cargo.toml b/net/rs/client-gen/Cargo.toml index 199152a7..ef190654 100644 --- a/net/rs/client-gen/Cargo.toml +++ b/net/rs/client-gen/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true repository.workspace = true [lib] -crate-type = ["cdylib", "lib"] +crate-type = ["cdylib", "rlib"] [build-dependencies] csbindgen.workspace = true @@ -21,6 +21,8 @@ genco.workspace = true itertools.workspace = true parity-scale-codec.workspace = true sails-idl-parser.workspace = true +serde.workspace = true +serde-json.workspace = true [dev-dependencies] insta.workspace = true diff --git a/net/rs/client-gen/src/lib.rs b/net/rs/client-gen/src/lib.rs index 7e1e1182..27d5a49b 100644 --- a/net/rs/client-gen/src/lib.rs +++ b/net/rs/client-gen/src/lib.rs @@ -2,6 +2,7 @@ use anyhow::{Context, Result}; use convert_case::{Case, Casing}; use root_generator::RootGenerator; use sails_idl_parser::ast::visitor; +use serde::Deserialize; use std::{collections::HashMap, ffi::OsStr, fs, path::Path}; mod ctor_generators; @@ -12,58 +13,18 @@ mod service_generators; mod type_generators; pub struct IdlPath<'a>(&'a Path); + pub struct IdlString<'a>(&'a str); + pub struct ClientGenerator<'a, S> { - sails_path: Option<&'a str>, - mocks_feature_name: Option<&'a str>, external_types: HashMap<&'a str, &'a str>, - no_derive_traits: bool, idl: S, } -impl<'a, S> ClientGenerator<'a, S> { - pub fn with_mocks(self, mocks_feature_name: &'a str) -> Self { - Self { - mocks_feature_name: Some(mocks_feature_name), - ..self - } - } - - pub fn with_sails_crate(self, sails_path: &'a str) -> Self { - Self { - sails_path: Some(sails_path), - ..self - } - } - - /// Add an map from IDL type to crate path - /// - /// Instead of generating type in client code, use type path from external crate - /// - /// # Example - /// - /// Following code generates `use my_crate::MyParam as MyFuncParam;` - /// ``` - /// let code = sails_net_client_gen::ClientGenerator::from_idl("") - /// .with_external_type("MyFuncParam", "my_crate::MyParam"); - /// ``` - pub fn with_external_type(self, name: &'a str, path: &'a str) -> Self { - let mut external_types = self.external_types; - external_types.insert(name, path); - Self { - external_types, - ..self - } - } -} - impl<'a> ClientGenerator<'a, IdlPath<'a>> { pub fn from_idl_path(idl_path: &'a Path) -> Self { Self { - sails_path: None, - mocks_feature_name: None, external_types: HashMap::new(), - no_derive_traits: false, idl: IdlPath(idl_path), } } @@ -76,19 +37,17 @@ impl<'a> ClientGenerator<'a, IdlPath<'a>> { let file_name = idl_path.file_stem().unwrap_or(OsStr::new("service")); let service_name = file_name.to_string_lossy().to_case(Case::Pascal); + let namepace = format!("{}.Client", service_name); self.with_idl(&idl) - .generate_to(&service_name, out_path) + .generate_to(&service_name, &namepace, out_path) .context("failed to generate client")?; Ok(()) } fn with_idl(self, idl: &'a str) -> ClientGenerator<'a, IdlString<'a>> { ClientGenerator { - sails_path: self.sails_path, - mocks_feature_name: self.mocks_feature_name, external_types: self.external_types, - no_derive_traits: self.no_derive_traits, idl: IdlString(idl), } } @@ -97,40 +56,32 @@ impl<'a> ClientGenerator<'a, IdlPath<'a>> { impl<'a> ClientGenerator<'a, IdlString<'a>> { pub fn from_idl(idl: &'a str) -> Self { Self { - sails_path: None, - mocks_feature_name: None, external_types: HashMap::new(), - no_derive_traits: false, idl: IdlString(idl), } } - pub fn generate(self, anonymous_service_name: &str) -> Result { + pub fn generate(self, anonymous_service_name: &str, namespace: &str) -> Result { let idl = self.idl.0; let program = sails_idl_parser::ast::parse_idl(idl).context("Failed to parse IDL")?; - let mut generator = RootGenerator::new(anonymous_service_name, self.external_types); + let mut generator = + RootGenerator::new(anonymous_service_name, namespace, self.external_types); visitor::accept_program(&program, &mut generator); let tokens = generator.finalize(); - - let fmt = genco::fmt::Config::from_lang::() - .with_indentation(genco::fmt::Indentation::Space(4)); - let config = genco::lang::csharp::Config::default(); - let mut w = genco::fmt::FmtWriter::new(String::new()); - - tokens.format_file(&mut w.as_formatter(&fmt), &config)?; - - Ok(w.into_inner()) + let code = tokens.to_file_string()?; + Ok(code) } pub fn generate_to( self, anonymous_service_name: &str, + namespace: &str, out_path: impl AsRef, ) -> Result<()> { let out_path = out_path.as_ref(); let code = self - .generate(anonymous_service_name) + .generate(anonymous_service_name, namespace) .context("failed to generate client")?; fs::write(out_path, code).with_context(|| { @@ -148,16 +99,16 @@ impl<'a> ClientGenerator<'a, IdlString<'a>> { pub unsafe extern "C" fn generate_dotnet_client( program_utf8: *const u8, program_len: i32, - service_name_utf8: *const u8, - service_name_len: i32, + config_utf8: *const u8, + config_len: i32, ) -> *const std::ffi::c_char { let slice = unsafe { std::slice::from_raw_parts(program_utf8, program_len as usize) }; let program = unsafe { String::from_utf8_unchecked(slice.to_vec()) }; - let slice = unsafe { std::slice::from_raw_parts(service_name_utf8, service_name_len as usize) }; - let service_name = unsafe { String::from_utf8_unchecked(slice.to_vec()) }; + let slice = unsafe { std::slice::from_raw_parts(config_utf8, config_len as usize) }; + let config: GeneratorConfig = serde_json::from_slice(slice).expect("failed to parse config"); let res = ClientGenerator::from_idl(program.as_str()) - .generate(service_name.as_str()) + .generate(&config.service_name, &config.namespace) .expect("failed to generate client"); std::ffi::CString::new(res) .expect("failed to create cstring") @@ -172,3 +123,9 @@ pub unsafe extern "C" fn free_c_string(str: *mut std::ffi::c_char) { // drop _ = unsafe { std::ffi::CString::from_raw(str) }; } + +#[derive(Deserialize, Debug)] +struct GeneratorConfig { + service_name: String, + namespace: String, +} diff --git a/net/rs/client-gen/src/root_generator.rs b/net/rs/client-gen/src/root_generator.rs index 812a9591..f0a4dc7d 100644 --- a/net/rs/client-gen/src/root_generator.rs +++ b/net/rs/client-gen/src/root_generator.rs @@ -15,6 +15,7 @@ pub(crate) struct RootGenerator<'a> { impl<'a> RootGenerator<'a> { pub(crate) fn new( anonymous_service_name: &'a str, + namespace: &'a str, external_types: HashMap<&'a str, &'a str>, ) -> Self { let mut tokens = Tokens::new(); @@ -22,10 +23,7 @@ impl<'a> RootGenerator<'a> { "#pragma warning disable RCS0056 // A line is too long", )); tokens.line(); - tokens.append(format!( - "namespace {}.Client;", - anonymous_service_name.to_case(Case::Pascal) - )); + tokens.append(format!("namespace {};", namespace)); tokens.line(); Self { tokens, diff --git a/net/rs/client-gen/tests/generator.rs b/net/rs/client-gen/tests/generator.rs index 8f2714cf..6ba27278 100644 --- a/net/rs/client-gen/tests/generator.rs +++ b/net/rs/client-gen/tests/generator.rs @@ -155,83 +155,9 @@ fn test_events_works() { insta::assert_snapshot!(gen(idl, "ServiceWithEvents")); } -#[test] -fn full_with_sails_path() { - const IDL: &str = r#" - type ThisThatSvcAppTupleStruct = struct { - bool, - }; - - type ThisThatSvcAppDoThatParam = struct { - p1: u32, - p2: str, - p3: ThisThatSvcAppManyVariants, - }; - - type ThisThatSvcAppManyVariants = enum { - One, - Two: u32, - Three: opt u32, - Four: struct { a: u32, b: opt u16 }, - Five: struct { str, u32 }, - Six: struct { u32 }, - }; - - type T = enum { One }; - - constructor { - New : (a: u32); - }; - - service { - DoThis : (p1: u32, p2: str, p3: struct { opt str, u8 }, p4: ThisThatSvcAppTupleStruct) -> struct { str, u32 }; - DoThat : (param: ThisThatSvcAppDoThatParam) -> result (struct { str, u32 }, struct { str }); - query This : (v1: vec u16) -> u32; - query That : (v1: null) -> result (str, str); - }; - "#; - - let code = ClientGenerator::from_idl(IDL) - .with_sails_crate("my_crate::sails") - .generate("Service") - .expect("generate client"); - insta::assert_snapshot!(code); -} - -#[test] -fn test_external_types() { - const IDL: &str = r#" - type MyParam = struct { - f1: u32, - f2: vec str, - f3: opt struct { u8, u32 }, - }; - - type MyParam2 = enum { - Variant1, - Variant2: u32, - Variant3: struct { u32 }, - Variant4: struct { u8, u32 }, - Variant5: struct { f1: str, f2: vec u8 }, - }; - - service { - DoThis: (p1: u32, p2: MyParam) -> u16; - DoThat: (p1: struct { u8, u32 }) -> u8; - }; - "#; - - let code = ClientGenerator::from_idl(IDL) - .with_sails_crate("my_crate::sails") - .with_external_type("MyParam", "my_crate::MyParam") - .generate("Service") - .expect("generate client"); - insta::assert_snapshot!(code); -} - fn gen(program: &str, service_name: &str) -> String { + let namepace = format!("{}.Client", service_name); ClientGenerator::from_idl(program) - .with_mocks("with_mocks") - .generate(service_name) + .generate(service_name, &namepace) .expect("generate client") } diff --git a/net/rs/client-gen/tests/snapshots/generator__external_types.snap b/net/rs/client-gen/tests/snapshots/generator__external_types.snap deleted file mode 100644 index d508632f..00000000 --- a/net/rs/client-gen/tests/snapshots/generator__external_types.snap +++ /dev/null @@ -1,38 +0,0 @@ ---- -source: client-gen/tests/generator.rs -expression: code ---- -using global::Sails.Remoting; -using global::Sails.Remoting.Abstractions; -using global::Sails.Remoting.Abstractions.Core; - -#pragma warning disable RCS0056 // A line is too long - -namespace Service.Client; - -public interface IService - { ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2); -ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); - } - - public partial class Service : IService - { private readonly IRemoting remoting; - - public Service(IRemoting remoting) { this.remoting = remoting; } - -/// - public ICall DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, MyParam p2) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2) ); } -/// - public ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1) ); } } - -public enum MyParam2 { Variant1, - Variant2, - Variant3, - Variant4, - Variant5, - } public sealed partial class EnumMyParam2 : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumMyParam2() { this.AddTypeDecoder(MyParam2.Variant1); -this.AddTypeDecoder(MyParam2.Variant2); -this.AddTypeDecoder(MyParam2.Variant3); -this.AddTypeDecoder>(MyParam2.Variant4); -this.AddTypeDecoder>>(MyParam2.Variant5); - } } diff --git a/net/rs/client-gen/tests/snapshots/generator__full_with_sails_path.snap b/net/rs/client-gen/tests/snapshots/generator__full_with_sails_path.snap deleted file mode 100644 index be0802fd..00000000 --- a/net/rs/client-gen/tests/snapshots/generator__full_with_sails_path.snap +++ /dev/null @@ -1,105 +0,0 @@ ---- -source: client-gen/tests/generator.rs -expression: code ---- -using global::Sails.Remoting; -using global::Sails.Remoting.Abstractions; -using global::Sails.Remoting.Abstractions.Core; -using global::System; -using global::System.Collections.Generic; - -#pragma warning disable RCS0056 // A line is too long - -namespace Service.Client; - -public interface IServiceFactory - { -IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); - } - - public partial class ServiceFactory : IServiceFactory - { - - private readonly IRemoting remoting; - - public ServiceFactory(IRemoting remoting) - { this.remoting = remoting; } - -/// - public IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a) { return new RemotingAction( this.remoting, [12, 78, 101, 119], new global::Substrate.NetApi.Model.Types.Primitive.U32(a)); } - - } - -public interface IService - { ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4); -ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param); -IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1); -IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); - } - - public partial class Service : IService - { private readonly IRemoting remoting; - - public Service(IRemoting remoting) { this.remoting = remoting; } - -/// - public ICall> DoThis(global::Substrate.NetApi.Model.Types.Primitive.U32 p1, global::Substrate.NetApi.Model.Types.Primitive.Str p2, global::Substrate.NetApi.Model.Types.Base.BaseTuple, global::Substrate.NetApi.Model.Types.Primitive.U8> p3, ThisThatSvcAppTupleStruct p4) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(p1, p2, p3, p4) ); } -/// - public ICall, global::Substrate.NetApi.Model.Types.Primitive.Str>> DoThat(ThisThatSvcAppDoThatParam param) { return new RemotingAction, global::Substrate.NetApi.Model.Types.Primitive.Str>>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 24, 68, 111, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(param) ); } -/// - public IQuery This(global::Substrate.NetApi.Model.Types.Base.BaseVec v1) { return new RemotingAction( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 105, 115], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } -/// - public IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1) { return new RemotingAction>( this.remoting, [28, 83, 101, 114, 118, 105, 99, 101, 16, 84, 104, 97, 116], new global::Substrate.NetApi.Model.Types.Base.BaseTupleRust(v1) ); } } - -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppTupleStruct : global::Substrate.NetApi.Model.Types.Base.BaseType { [System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.Bool Value { get; set; } -/// - public override string TypeName() => "ThisThatSvcAppTupleStruct"; -/// - public override byte[] Encode() { var result = new List(); result.AddRange(this.Value.Encode()); - return result.ToArray(); } -/// - public override void Decode(byte[] byteArray, ref int p) { var start = p; this.Value = new global::Substrate.NetApi.Model.Types.Primitive.Bool(); - this.Value.Decode(byteArray, ref p); - var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } - -[global::Substrate.NetApi.Attributes.SubstrateNodeType(global::Substrate.NetApi.Model.Types.Metadata.Base.TypeDefEnum.Composite)] public sealed partial class ThisThatSvcAppDoThatParam : global::Substrate.NetApi.Model.Types.Base.BaseType { -[System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.U32 P1 { get; set; } -[System.Diagnostics.CodeAnalysis.AllowNull] - public global::Substrate.NetApi.Model.Types.Primitive.Str P2 { get; set; } -[System.Diagnostics.CodeAnalysis.AllowNull] - public EnumThisThatSvcAppManyVariants P3 { get; set; } -/// - public override string TypeName() => "ThisThatSvcAppDoThatParam"; -/// - public override byte[] Encode() { var result = new List(); result.AddRange(this.P1.Encode()); -result.AddRange(this.P2.Encode()); -result.AddRange(this.P3.Encode()); - return result.ToArray(); } -/// - public override void Decode(byte[] byteArray, ref int p) { var start = p; this.P1 = new global::Substrate.NetApi.Model.Types.Primitive.U32(); - this.P1.Decode(byteArray, ref p); -this.P2 = new global::Substrate.NetApi.Model.Types.Primitive.Str(); - this.P2.Decode(byteArray, ref p); -this.P3 = new EnumThisThatSvcAppManyVariants(); - this.P3.Decode(byteArray, ref p); - var bytesLength = p - start; this.TypeSize = bytesLength; this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } } - -public enum ThisThatSvcAppManyVariants { One, - Two, - Three, - Four, - Five, - Six, - } public sealed partial class EnumThisThatSvcAppManyVariants : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumThisThatSvcAppManyVariants() { this.AddTypeDecoder(ThisThatSvcAppManyVariants.One); -this.AddTypeDecoder(ThisThatSvcAppManyVariants.Two); -this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Three); -this.AddTypeDecoder>>(ThisThatSvcAppManyVariants.Four); -this.AddTypeDecoder>(ThisThatSvcAppManyVariants.Five); -this.AddTypeDecoder(ThisThatSvcAppManyVariants.Six); - } } - -public enum T { One, - } public sealed partial class EnumT : global::Substrate.NetApi.Model.Types.Base.BaseEnumRust { public EnumT() { this.AddTypeDecoder(T.One); - } } diff --git a/net/src/Sails.ClientGenerator/GeneratorConfig.cs b/net/src/Sails.ClientGenerator/GeneratorConfig.cs new file mode 100644 index 00000000..85250d47 --- /dev/null +++ b/net/src/Sails.ClientGenerator/GeneratorConfig.cs @@ -0,0 +1,10 @@ +namespace Sails.ClientGenerator; + +public record struct GeneratorConfig( + string ServiceName, + string Namespace +) +{ + public override string ToString() + => $"{{ \"service_name\": \"{this.ServiceName}\", \"namespace\": \"{this.Namespace}\" }}"; +} diff --git a/net/src/Sails.ClientGenerator/NativeMethods.g.cs b/net/src/Sails.ClientGenerator/NativeMethods.g.cs index ded815e0..5cbf23b7 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.g.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.g.cs @@ -22,7 +22,7 @@ internal static unsafe partial class NativeMethods /// Function [`free_c_string`] should be called after this function /// [DllImport(__DllName, EntryPoint = "generate_dotnet_client", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - internal static extern byte* generate_dotnet_client(byte* program_utf8, int program_len, byte* service_name_utf8, int service_name_len); + internal static extern byte* generate_dotnet_client(byte* program_utf8, int program_len, byte* config_utf8, int config_len); /// /// # Safety diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 1c2944ad..01979923 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -1,4 +1,5 @@ -using System.Text; +using System.Collections.Immutable; +using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; @@ -11,33 +12,51 @@ public partial class SailsClientGenerator : IIncrementalGenerator public void Initialize(IncrementalGeneratorInitializationContext context) { var source = context.AdditionalTextsProvider - .Where(static file => file.Path.EndsWith(".idl")) - .Select(static (text, cancellationToken) => - GenerateCode(Path.GetFileNameWithoutExtension(text.Path), text.GetText(cancellationToken)!.ToString()) - ); + .Where(static file => file.Path.EndsWith(".idl")); var compilationAndFiles = context.CompilationProvider.Combine(source.Collect()); - context.RegisterSourceOutput(source, AddSource); + context.RegisterSourceOutput(compilationAndFiles, AddSource); } - private static unsafe (string Name, string Code) GenerateCode(string name, string source) + private static void AddSource( + SourceProductionContext context, + (Compilation Left, ImmutableArray Right) tuple) + { + var assemblyName = tuple.Left.AssemblyName!; + foreach (var source in tuple.Right) + { + var parts = Path.GetDirectoryName(source.Path) + .Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries) + .Select(FirstUpper) + .ToList(); + parts.Insert(0, assemblyName); + var name = FirstUpper(Path.GetFileNameWithoutExtension(source.Path)); + parts.Add(name); + var ns = string.Join(".", parts); + var code = GenerateCode(source.GetText()!.ToString(), new GeneratorConfig(name, ns)); + + context.AddSource($"{name}.g.cs", SourceText.From(code, encoding: Encoding.UTF8)); + } + } + + private static unsafe string GenerateCode(string source, GeneratorConfig config) { var handle = NativeMethods.LoadNativeLibrary(); try { var idlBytes = Encoding.UTF8.GetBytes(source); - var nameBytes = Encoding.UTF8.GetBytes(name); + var configBytes = Encoding.UTF8.GetBytes(config.ToString()); fixed (byte* pIdl = idlBytes) { - fixed (byte* pName = nameBytes) + fixed (byte* pConfig = configBytes) { - var cstr = NativeMethods.generate_dotnet_client(pIdl, idlBytes.Length, pName, nameBytes.Length); + var cstr = NativeMethods.generate_dotnet_client(pIdl, idlBytes.Length, pConfig, configBytes.Length); try { var str = new string((sbyte*)cstr); - return (name, FormatCode(str)); + return FormatCode(str); } finally { @@ -52,16 +71,27 @@ private static unsafe (string Name, string Code) GenerateCode(string name, strin } } - private static void AddSource(SourceProductionContext context, (string Name, string Code) source) - { - context.AddSource($"{source.Name}.g.cs", SourceText.From(source.Code, encoding: Encoding.UTF8)); - } - - public static string FormatCode(string code, CancellationToken cancelToken = default) - => CSharpSyntaxTree.ParseText(code, cancellationToken: cancelToken) - .GetRoot(cancelToken) + private static string FormatCode(string code, CancellationToken cancellationToken = default) + => CSharpSyntaxTree.ParseText(code, cancellationToken: cancellationToken) + .GetRoot(cancellationToken) .NormalizeWhitespace() .SyntaxTree - .GetText(cancelToken) + .GetText(cancellationToken) .ToString(); + + private static string FirstUpper(string text) + { + if (text.Length == 0) + { + return text; + } + Span res = stackalloc char[text.Length]; + text.AsSpan().CopyTo(res); + var c = res[0]; + if (char.IsLetter(c) && char.IsLower(c)) + { + res[0] = char.ToUpperInvariant(c); + } + return res.ToString(); + } } diff --git a/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs b/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs index 7f467287..c287391d 100644 --- a/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs +++ b/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs @@ -16,7 +16,7 @@ public class SailsClientGeneratorTests private static Task Verify(params string[] fileNames) { // Create a Roslyn compilation for the syntax tree. - var compilation = CSharpCompilation.Create(assemblyName: "Tests"); + var compilation = CSharpCompilation.Create(assemblyName: "Sails.ClientGenerator.Tests"); var additionalFiles = fileNames .Select(x => (file: x, content: File.ReadAllText($"./{x}"))) diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs index 31032eb9..a236710b 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs @@ -1,4 +1,4 @@ -//HintName: demo.g.cs +//HintName: Demo.g.cs using global::Sails.Remoting; using global::Sails.Remoting.Abstractions; using global::Sails.Remoting.Abstractions.Core; @@ -7,7 +7,7 @@ #pragma warning disable RCS0056 // A line is too long -namespace Demo.Client; +namespace Sails.ClientGenerator.Tests.Idl.Demo; public interface IDemoFactory { /// From dc5249907403e9177b155cfece6180d8c495f2ee Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 12 Nov 2024 15:37:29 +0100 Subject: [PATCH 40/54] wip: fix --- .../Sails.ClientGenerator.csproj | 6 +++--- .../SailsClientGenerator.cs | 18 ++++++++++-------- ...orTests.Generate_DemoIdl#demo.g.verified.cs | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 05845ea4..aedd7cd9 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -28,7 +28,7 @@ - + @@ -37,8 +37,8 @@ - - + + diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 01979923..4b5dd784 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -1,4 +1,6 @@ -using System.Collections.Immutable; +#pragma warning disable RS1035 // Do not use APIs banned for analyzers + +using System.Collections.Immutable; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -14,22 +16,22 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var source = context.AdditionalTextsProvider .Where(static file => file.Path.EndsWith(".idl")); - var compilationAndFiles = context.CompilationProvider.Combine(source.Collect()); + var compilationAndFiles = context.CompilationProvider + .Select((c, _) => c.AssemblyName) + .Combine(source.Collect()); context.RegisterSourceOutput(compilationAndFiles, AddSource); } private static void AddSource( SourceProductionContext context, - (Compilation Left, ImmutableArray Right) tuple) + (string? AssemblyName, ImmutableArray Right) tuple) { - var assemblyName = tuple.Left.AssemblyName!; + var assemblyName = tuple.AssemblyName!; foreach (var source in tuple.Right) { - var parts = Path.GetDirectoryName(source.Path) - .Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries) - .Select(FirstUpper) - .ToList(); + // TODO: add relative directory as namespace part + var parts = new List(); parts.Insert(0, assemblyName); var name = FirstUpper(Path.GetFileNameWithoutExtension(source.Path)); parts.Add(name); diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs index a236710b..7b3a5220 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs @@ -7,7 +7,7 @@ #pragma warning disable RCS0056 // A line is too long -namespace Sails.ClientGenerator.Tests.Idl.Demo; +namespace Sails.ClientGenerator.Tests.Demo; public interface IDemoFactory { /// From f2012cc7fc605c0a42d5eda9544d3f68a14f3e05 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 12 Nov 2024 16:06:28 +0100 Subject: [PATCH 41/54] wip: generate sealed classes --- net/rs/client-gen/src/ctor_generators.rs | 2 +- net/rs/client-gen/src/events_generator.rs | 2 +- net/rs/client-gen/src/service_generators.rs | 2 +- .../snapshots/generator__basic_works.snap | 2 +- .../snapshots/generator__events_works.snap | 4 ++-- .../tests/snapshots/generator__full.snap | 6 +++--- .../generator__multiple_services.snap | 4 ++-- .../snapshots/generator__nonzero_works.snap | 2 +- .../snapshots/generator__rmrk_works.snap | 4 ++-- ...rTests.Generate_DemoIdl#demo.g.verified.cs | 20 +++++++++---------- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/net/rs/client-gen/src/ctor_generators.rs b/net/rs/client-gen/src/ctor_generators.rs index f3f25cd5..690f1d84 100644 --- a/net/rs/client-gen/src/ctor_generators.rs +++ b/net/rs/client-gen/src/ctor_generators.rs @@ -34,7 +34,7 @@ impl<'a> CtorFactoryGenerator<'a> { $(self.interface_tokens) } $['\n'] - public partial class $(&class_name) : I$(&class_name)$['\r'] + public sealed partial class $(&class_name) : I$(&class_name)$['\r'] {$['\n'] private readonly $remoting remoting; $['\n'] diff --git a/net/rs/client-gen/src/events_generator.rs b/net/rs/client-gen/src/events_generator.rs index 2d169813..7b7bad38 100644 --- a/net/rs/client-gen/src/events_generator.rs +++ b/net/rs/client-gen/src/events_generator.rs @@ -52,7 +52,7 @@ impl<'a> EventsGenerator<'a> { } } $['\n'] - public partial class $listener_name : $service_listener<$class_name> + public sealed partial class $listener_name : $service_listener<$class_name> { private static readonly byte[][] EventRoutes = [ diff --git a/net/rs/client-gen/src/service_generators.rs b/net/rs/client-gen/src/service_generators.rs index 0cbecaaf..fac502ae 100644 --- a/net/rs/client-gen/src/service_generators.rs +++ b/net/rs/client-gen/src/service_generators.rs @@ -34,7 +34,7 @@ impl<'a> ServiceClientGenerator<'a> { $(self.interface_tokens)$['\r'] } $['\n'] - public partial class $name : I$name$['\r'] + public sealed partial class $name : I$name$['\r'] { private readonly $remoting remoting; $['\n'] diff --git a/net/rs/client-gen/tests/snapshots/generator__basic_works.snap b/net/rs/client-gen/tests/snapshots/generator__basic_works.snap index 214bf57d..81e22285 100644 --- a/net/rs/client-gen/tests/snapshots/generator__basic_works.snap +++ b/net/rs/client-gen/tests/snapshots/generator__basic_works.snap @@ -17,7 +17,7 @@ public interface IBasic ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } - public partial class Basic : IBasic + public sealed partial class Basic : IBasic { private readonly IRemoting remoting; public Basic(IRemoting remoting) { this.remoting = remoting; } diff --git a/net/rs/client-gen/tests/snapshots/generator__events_works.snap b/net/rs/client-gen/tests/snapshots/generator__events_works.snap index 74668ca6..63470064 100644 --- a/net/rs/client-gen/tests/snapshots/generator__events_works.snap +++ b/net/rs/client-gen/tests/snapshots/generator__events_works.snap @@ -16,7 +16,7 @@ public interface IServiceWithEvents { ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); } - public partial class ServiceWithEvents : IServiceWithEvents + public sealed partial class ServiceWithEvents : IServiceWithEvents { private readonly IRemoting remoting; public ServiceWithEvents(IRemoting remoting) { this.remoting = remoting; } @@ -36,7 +36,7 @@ this.AddTypeDecoder(ServiceWithEventsEvents.Three); this.AddTypeDecoder(ServiceWithEventsEvents.Reset); } } - public partial class ServiceWithEventsListener : IRemotingListener { private static readonly byte[][] EventRoutes = [ [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 79, 110, 101],[68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 84, 119, 111],[68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 84, 104, 114, 101, 101],[68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 82, 101, 115, 101, 116], ]; + public sealed partial class ServiceWithEventsListener : IRemotingListener { private static readonly byte[][] EventRoutes = [ [68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 79, 110, 101],[68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 12, 84, 119, 111],[68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 84, 104, 114, 101, 101],[68, 83, 101, 114, 118, 105, 99, 101, 87, 105, 116, 104, 69, 118, 101, 110, 116, 115, 20, 82, 101, 115, 101, 116], ]; private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; diff --git a/net/rs/client-gen/tests/snapshots/generator__full.snap b/net/rs/client-gen/tests/snapshots/generator__full.snap index d9367bd4..13e71722 100644 --- a/net/rs/client-gen/tests/snapshots/generator__full.snap +++ b/net/rs/client-gen/tests/snapshots/generator__full.snap @@ -20,7 +20,7 @@ public interface IServiceFactory IActivation New(global::Substrate.NetApi.Model.Types.Primitive.U32 a); } - public partial class ServiceFactory : IServiceFactory + public sealed partial class ServiceFactory : IServiceFactory { private readonly IRemoting remoting; @@ -40,7 +40,7 @@ IQuery This(global::Substrat IQuery> That(global::Substrate.NetApi.Model.Types.Base.BaseVoid v1); } - public partial class Service : IService + public sealed partial class Service : IService { private readonly IRemoting remoting; public Service(IRemoting remoting) { this.remoting = remoting; } @@ -69,7 +69,7 @@ public enum ServiceEvents { this.AddTypeDecoder(ServiceEvents.ThatDone); } } - public partial class ServiceListener : IRemotingListener { private static readonly byte[][] EventRoutes = [ [28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 105, 115, 68, 111, 110, 101],[28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 97, 116, 68, 111, 110, 101], ]; + public sealed partial class ServiceListener : IRemotingListener { private static readonly byte[][] EventRoutes = [ [28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 105, 115, 68, 111, 110, 101],[28, 83, 101, 114, 118, 105, 99, 101, 32, 84, 104, 97, 116, 68, 111, 110, 101], ]; private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; diff --git a/net/rs/client-gen/tests/snapshots/generator__multiple_services.snap b/net/rs/client-gen/tests/snapshots/generator__multiple_services.snap index 5c1fb1b9..d2185fe8 100644 --- a/net/rs/client-gen/tests/snapshots/generator__multiple_services.snap +++ b/net/rs/client-gen/tests/snapshots/generator__multiple_services.snap @@ -15,7 +15,7 @@ public interface IMultiple ICall DoThat(global::Substrate.NetApi.Model.Types.Base.BaseTuple p1); } - public partial class Multiple : IMultiple + public sealed partial class Multiple : IMultiple { private readonly IRemoting remoting; public Multiple(IRemoting remoting) { this.remoting = remoting; } @@ -29,7 +29,7 @@ public interface INamed { IQuery That(global::Substrate.NetApi.Model.Types.Primitive.U32 p1); } - public partial class Named : INamed + public sealed partial class Named : INamed { private readonly IRemoting remoting; public Named(IRemoting remoting) { this.remoting = remoting; } diff --git a/net/rs/client-gen/tests/snapshots/generator__nonzero_works.snap b/net/rs/client-gen/tests/snapshots/generator__nonzero_works.snap index 1f67c02f..0d0202f6 100644 --- a/net/rs/client-gen/tests/snapshots/generator__nonzero_works.snap +++ b/net/rs/client-gen/tests/snapshots/generator__nonzero_works.snap @@ -16,7 +16,7 @@ public interface INonZeroParams { ICall DoThis(global::Substrate.Gear.Client.Model.Types.Primitive.NonZeroU256 p1, MyParam p2); } - public partial class NonZeroParams : INonZeroParams + public sealed partial class NonZeroParams : INonZeroParams { private readonly IRemoting remoting; public NonZeroParams(IRemoting remoting) { this.remoting = remoting; } diff --git a/net/rs/client-gen/tests/snapshots/generator__rmrk_works.snap b/net/rs/client-gen/tests/snapshots/generator__rmrk_works.snap index 00357b9c..b8d6d178 100644 --- a/net/rs/client-gen/tests/snapshots/generator__rmrk_works.snap +++ b/net/rs/client-gen/tests/snapshots/generator__rmrk_works.snap @@ -17,7 +17,7 @@ public interface IRmrkCatalogFactory IActivation New(); } - public partial class RmrkCatalogFactory : IRmrkCatalogFactory + public sealed partial class RmrkCatalogFactory : IRmrkCatalogFactory { private readonly IRemoting remoting; @@ -41,7 +41,7 @@ IQuery> Part(global::Substrate.NetApi.Model.Types.Primitive.U32 partId); } - public partial class RmrkCatalog : IRmrkCatalog + public sealed partial class RmrkCatalog : IRmrkCatalog { private readonly IRemoting remoting; public RmrkCatalog(IRemoting remoting) { this.remoting = remoting; } diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs index 7b3a5220..6eacbfb6 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs @@ -20,7 +20,7 @@ public interface IDemoFactory IActivation New(global::Substrate.NetApi.Model.Types.Base.BaseOpt counter, global::Substrate.NetApi.Model.Types.Base.BaseOpt> dogPosition); } -public partial class DemoFactory : IDemoFactory +public sealed partial class DemoFactory : IDemoFactory { private readonly IRemoting remoting; public DemoFactory(IRemoting remoting) @@ -48,7 +48,7 @@ public interface ICounter IQuery Value(); } -public partial class Counter : ICounter +public sealed partial class Counter : ICounter { private readonly IRemoting remoting; public Counter(IRemoting remoting) @@ -96,7 +96,7 @@ public EnumCounterEvents() } } -public partial class CounterListener : IRemotingListener +public sealed partial class CounterListener : IRemotingListener { private static readonly byte[][] EventRoutes = [[28, 67, 111, 117, 110, 116, 101, 114, 20, 65, 100, 100, 101, 100], [28, 67, 111, 117, 110, 116, 101, 114, 40, 83, 117, 98, 116, 114, 97, 99, 116, 101, 100], ]; private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; @@ -143,7 +143,7 @@ public interface IDog IQuery> Position(); } -public partial class Dog : IDog +public sealed partial class Dog : IDog { private readonly IRemoting remoting; public Dog(IRemoting remoting) @@ -191,7 +191,7 @@ public EnumDogEvents() } } -public partial class DogListener : IRemotingListener +public sealed partial class DogListener : IRemotingListener { private static readonly byte[][] EventRoutes = [[12, 68, 111, 103, 24, 66, 97, 114, 107, 101, 100], [12, 68, 111, 103, 24, 87, 97, 108, 107, 101, 100], ]; private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; @@ -235,7 +235,7 @@ public interface IPingPong ICall> Ping(global::Substrate.NetApi.Model.Types.Primitive.Str input); } -public partial class PingPong : IPingPong +public sealed partial class PingPong : IPingPong { private readonly IRemoting remoting; public PingPong(IRemoting remoting) @@ -262,7 +262,7 @@ public interface IReferences IQuery> Message(); } -public partial class References : IReferences +public sealed partial class References : IReferences { private readonly IRemoting remoting; public References(IRemoting remoting) @@ -328,7 +328,7 @@ public interface IThisThat IQuery This(); } -public partial class ThisThat : IThisThat +public sealed partial class ThisThat : IThisThat { private readonly IRemoting remoting; public ThisThat(IRemoting remoting) @@ -372,7 +372,7 @@ public interface IValueFee ICall DoSomethingAndTakeFee(); } -public partial class ValueFee : IValueFee +public sealed partial class ValueFee : IValueFee { private readonly IRemoting remoting; public ValueFee(IRemoting remoting) @@ -400,7 +400,7 @@ public EnumValueFeeEvents() } } -public partial class ValueFeeListener : IRemotingListener +public sealed partial class ValueFeeListener : IRemotingListener { private static readonly byte[][] EventRoutes = [[32, 86, 97, 108, 117, 101, 70, 101, 101, 32, 87, 105, 116, 104, 104, 101, 108, 100], ]; private readonly global::Sails.Remoting.Abstractions.Core.IRemotingListener remoting; From 0c29bdb065310adeb030c087113b5e2f2cf73d45 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Tue, 12 Nov 2024 17:21:07 +0100 Subject: [PATCH 42/54] remove csbindgen and native methods generation --- net/rs/Cargo.lock | 11 ----- net/rs/Cargo.toml | 1 - net/rs/client-gen/Cargo.toml | 3 -- net/rs/client-gen/build.rs | 8 ---- .../NativeMethods.Loader.cs | 6 +-- .../Sails.ClientGenerator/NativeMethods.cs | 24 +++++++++++ .../Sails.ClientGenerator/NativeMethods.g.cs | 40 ------------------- .../SailsClientGenerator.cs | 4 +- 8 files changed, 28 insertions(+), 69 deletions(-) delete mode 100644 net/rs/client-gen/build.rs create mode 100644 net/src/Sails.ClientGenerator/NativeMethods.cs delete mode 100644 net/src/Sails.ClientGenerator/NativeMethods.g.cs diff --git a/net/rs/Cargo.lock b/net/rs/Cargo.lock index f057dfeb..b3df8240 100644 --- a/net/rs/Cargo.lock +++ b/net/rs/Cargo.lock @@ -116,16 +116,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "csbindgen" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c26b9831049b947d154bba920e4124053def72447be6fb106a96f483874b482a" -dependencies = [ - "regex", - "syn 2.0.87", -] - [[package]] name = "dirs-next" version = "2.0.0" @@ -588,7 +578,6 @@ version = "0.6.3" dependencies = [ "anyhow", "convert_case", - "csbindgen", "genco", "insta", "itertools 0.13.0", diff --git a/net/rs/Cargo.toml b/net/rs/Cargo.toml index 8dc05dd7..e72e56f4 100644 --- a/net/rs/Cargo.toml +++ b/net/rs/Cargo.toml @@ -15,7 +15,6 @@ sails-idl-parser = "=0.6.3" # others anyhow = "1" convert-case = { package = "convert_case", version = "0.6" } -csbindgen = "1.9" genco = "0.17" insta = "1.41" itertools = "0.13" diff --git a/net/rs/client-gen/Cargo.toml b/net/rs/client-gen/Cargo.toml index ef190654..761cc340 100644 --- a/net/rs/client-gen/Cargo.toml +++ b/net/rs/client-gen/Cargo.toml @@ -11,9 +11,6 @@ repository.workspace = true [lib] crate-type = ["cdylib", "rlib"] -[build-dependencies] -csbindgen.workspace = true - [dependencies] anyhow.workspace = true convert-case.workspace = true diff --git a/net/rs/client-gen/build.rs b/net/rs/client-gen/build.rs deleted file mode 100644 index 589ff5c5..00000000 --- a/net/rs/client-gen/build.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() { - csbindgen::Builder::default() - .input_extern_file("src/lib.rs") - .csharp_dll_name("sails_net_client_gen") - .csharp_namespace("Sails.ClientGenerator") - .generate_csharp_file("../../src/Sails.ClientGenerator/NativeMethods.g.cs") - .unwrap(); -} diff --git a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs index 663ee6fd..e5e1f9a6 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs @@ -11,15 +11,15 @@ internal static unsafe partial class NativeMethods internal static IntPtr LoadNativeLibrary() { // Determine where to extract the DLL - var tempDirectory = Path.Combine(Path.GetTempPath(), __DllName); + var tempDirectory = Path.Combine(Path.GetTempPath(), DllName); Directory.CreateDirectory(tempDirectory); var (platform, extension) = GetResourcePlatform(); - var nativeLibraryPath = Path.Combine(tempDirectory, __DllName + extension); + var nativeLibraryPath = Path.Combine(tempDirectory, DllName + extension); // Extract the DLL only if it doesn't already exist if (!File.Exists(nativeLibraryPath)) { - ExtractResourceToFile($"{platform}.{__DllName}{extension}", nativeLibraryPath); + ExtractResourceToFile($"{platform}.{DllName}{extension}", nativeLibraryPath); } var ret = LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibraryByPath(nativeLibraryPath); if (ret == IntPtr.Zero) diff --git a/net/src/Sails.ClientGenerator/NativeMethods.cs b/net/src/Sails.ClientGenerator/NativeMethods.cs new file mode 100644 index 00000000..565f5971 --- /dev/null +++ b/net/src/Sails.ClientGenerator/NativeMethods.cs @@ -0,0 +1,24 @@ +using System.Runtime.InteropServices; + +namespace Sails.ClientGenerator; + +internal static unsafe partial class NativeMethods +{ + private const string DllName = "sails_net_client_gen"; + + /// + /// # Safety + /// + /// Function [`free_c_string`] should be called after this function + /// + [DllImport(DllName, EntryPoint = "generate_dotnet_client", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + internal static extern byte* generate_dotnet_client(byte* program_utf8, int program_len, byte* config_utf8, int config_len); + + /// + /// # Safety + /// + /// This function should not be called before the [`generate_dotnet_client`] + /// + [DllImport(DllName, EntryPoint = "free_c_string", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] + internal static extern void free_c_string(byte* str); +} diff --git a/net/src/Sails.ClientGenerator/NativeMethods.g.cs b/net/src/Sails.ClientGenerator/NativeMethods.g.cs deleted file mode 100644 index 5cbf23b7..00000000 --- a/net/src/Sails.ClientGenerator/NativeMethods.g.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// This code is generated by csbindgen. -// DON'T CHANGE THIS DIRECTLY. -// -#pragma warning disable CS8500 -#pragma warning disable CS8981 -using System; -using System.Runtime.InteropServices; - - -namespace Sails.ClientGenerator -{ - internal static unsafe partial class NativeMethods - { - const string __DllName = "sails_net_client_gen"; - - - - /// - /// # Safety - /// - /// Function [`free_c_string`] should be called after this function - /// - [DllImport(__DllName, EntryPoint = "generate_dotnet_client", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - internal static extern byte* generate_dotnet_client(byte* program_utf8, int program_len, byte* config_utf8, int config_len); - - /// - /// # Safety - /// - /// This function should not be called before the [`generate_dotnet_client`] - /// - [DllImport(__DllName, EntryPoint = "free_c_string", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - internal static extern void free_c_string(byte* str); - - - } - - - -} diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 4b5dd784..00234881 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -1,6 +1,4 @@ -#pragma warning disable RS1035 // Do not use APIs banned for analyzers - -using System.Collections.Immutable; +using System.Collections.Immutable; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; From 8a2492d69c2f3866a5288308ce87cacf44c2eaff Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 13 Nov 2024 12:07:48 +0100 Subject: [PATCH 43/54] add Sails.Client.Tests --- Sails.Net.sln | 11 ++- net/Directory.Build.props | 3 + net/Directory.Packages.props | 1 + .../Sails.Client.Tests/DemoClientTests.cs | 69 ++++++++++++++ net/tests/Sails.Client.Tests/GlobalUsings.cs | 17 ++++ .../Sails.Client.Tests.csproj | 30 ++++++ net/tests/Sails.Client.Tests/idl/demo.idl | 91 +++++++++++++++++++ 7 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 net/tests/Sails.Client.Tests/DemoClientTests.cs create mode 100644 net/tests/Sails.Client.Tests/GlobalUsings.cs create mode 100644 net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj create mode 100644 net/tests/Sails.Client.Tests/idl/demo.idl diff --git a/Sails.Net.sln b/Sails.Net.sln index 465ff5a2..eedc9fc3 100644 --- a/Sails.Net.sln +++ b/Sails.Net.sln @@ -21,11 +21,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Substrate.Gear.Client", "ne EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sails.ClientGenerator", "net\src\Sails.ClientGenerator\Sails.ClientGenerator.csproj", "{F93FFE42-71C1-44BD-9DBA-3559B307370C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sails.ClientGenerator.Tests", "net\tests\Sails.ClientGenerator.Tests\Sails.ClientGenerator.Tests.csproj", "{A6A2172B-8F8F-4BDC-B519-E7299FFCCA5F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sails.ClientGenerator.Tests", "net\tests\Sails.ClientGenerator.Tests\Sails.ClientGenerator.Tests.csproj", "{A6A2172B-8F8F-4BDC-B519-E7299FFCCA5F}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{19594BCA-94DB-44AD-ACBC-2ACFED242E9F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate.Gear.Client.Tests", "net\tests\Substrate.Gear.Client.Tests\Substrate.Gear.Client.Tests.csproj", "{42B621CE-C2B4-4911-961C-5B087A514AF5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Substrate.Gear.Client.Tests", "net\tests\Substrate.Gear.Client.Tests\Substrate.Gear.Client.Tests.csproj", "{42B621CE-C2B4-4911-961C-5B087A514AF5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sails.Client.Tests", "net\tests\Sails.Client.Tests\Sails.Client.Tests.csproj", "{BC248D44-14CD-4BB0-9AF9-4E0750574492}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -65,12 +67,17 @@ Global {42B621CE-C2B4-4911-961C-5B087A514AF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {42B621CE-C2B4-4911-961C-5B087A514AF5}.Release|Any CPU.ActiveCfg = Release|Any CPU {42B621CE-C2B4-4911-961C-5B087A514AF5}.Release|Any CPU.Build.0 = Release|Any CPU + {BC248D44-14CD-4BB0-9AF9-4E0750574492}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC248D44-14CD-4BB0-9AF9-4E0750574492}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC248D44-14CD-4BB0-9AF9-4E0750574492}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BC248D44-14CD-4BB0-9AF9-4E0750574492}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {A6A2172B-8F8F-4BDC-B519-E7299FFCCA5F} = {19594BCA-94DB-44AD-ACBC-2ACFED242E9F} + {BC248D44-14CD-4BB0-9AF9-4E0750574492} = {19594BCA-94DB-44AD-ACBC-2ACFED242E9F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0894C08B-8BB9-401D-8471-26F5EB5A4EA2} diff --git a/net/Directory.Build.props b/net/Directory.Build.props index 4b9ebbe4..8005fa4e 100644 --- a/net/Directory.Build.props +++ b/net/Directory.Build.props @@ -22,6 +22,9 @@ all + + all + diff --git a/net/Directory.Packages.props b/net/Directory.Packages.props index 10f9998b..d66af75e 100644 --- a/net/Directory.Packages.props +++ b/net/Directory.Packages.props @@ -14,6 +14,7 @@ + diff --git a/net/tests/Sails.Client.Tests/DemoClientTests.cs b/net/tests/Sails.Client.Tests/DemoClientTests.cs new file mode 100644 index 00000000..88a6912c --- /dev/null +++ b/net/tests/Sails.Client.Tests/DemoClientTests.cs @@ -0,0 +1,69 @@ +namespace Sails.Client.Tests; + +public class DemoClientTests +{ + [Fact] + public async Task Demo_DefaultConstructor() + { + // arrange + var route = new Str("Default").Encode(); + var bytes = Utils.HexToByteArray("0xd5c7e252243071f25d8013aa60e87e1650b4f069983eeafcecec10c0a03619ae"); + var expectedProgramId = new ActorId { Value = new Arr32U8 { Value = bytes.ToU8Array() } }; + + var remotingReply = Substitute.For>(); + remotingReply.ReadAsync(Arg.Any()).Returns(Task.FromResult((expectedProgramId, route))); + + var remoting = Substitute.For(); + remoting + .ActivateAsync( + codeId: Arg.Any(), + salt: Arg.Any>(), + encodedPayload: Arg.Any>(), + gasLimit: Arg.Any(), + value: Arg.Any(), + cancellationToken: Arg.Any()) + .Returns(Task.FromResult(remotingReply)); + + var codeId = new CodeId { Value = new Arr32U8 { Value = (new byte[32]).ToU8Array() } }; + + // act + var demoFactory = new Demo.DemoFactory(remoting); + var activate = await demoFactory.Default().ActivateAsync(codeId, [], CancellationToken.None); + var programId = await activate.ReceiveAsync(CancellationToken.None); + + // assert + Assert.True(programId.IsEqualTo(expectedProgramId)); + } + + [Fact] + public async Task PingPong_Works() + { + // arrange + var res = new BaseResult(); + res.Create(BaseResultEnum.Ok, new Str("pong")); + var replyBytes = new BaseTuple>(new Str("PingPong"), new Str("Ping"), res).Encode(); + + var remotingReply = Substitute.For>(); + remotingReply.ReadAsync(Arg.Any()).Returns(Task.FromResult(replyBytes)); + + var programId = new ActorId { Value = new Arr32U8 { Value = (new byte[32]).ToU8Array() } }; + + var remoting = Substitute.For(); + remoting + .MessageAsync( + programId: programId, + encodedPayload: Arg.Any>(), + gasLimit: Arg.Any(), + value: Arg.Any(), + cancellationToken: Arg.Any()) + .Returns(Task.FromResult(remotingReply)); + + // act + var pingPong = new Demo.PingPong(remoting); + var message = await pingPong.Ping((Str)"ping").MessageAsync(programId, CancellationToken.None); + var pingReply = await message.ReceiveAsync(CancellationToken.None); + + // assert + Assert.True(pingReply.Matches(BaseResultEnum.Ok, s => s == "pong")); + } +} diff --git a/net/tests/Sails.Client.Tests/GlobalUsings.cs b/net/tests/Sails.Client.Tests/GlobalUsings.cs new file mode 100644 index 00000000..3dc1a4c7 --- /dev/null +++ b/net/tests/Sails.Client.Tests/GlobalUsings.cs @@ -0,0 +1,17 @@ +global using System; +global using System.Collections.Generic; +global using System.Linq; +global using System.Threading; +global using System.Threading.Tasks; +global using NSubstitute; +global using Sails.Remoting.Abstractions.Core; +global using Substrate.Gear.Api.Generated.Model.gprimitives; +global using Substrate.Gear.Api.Generated.Types.Base; +global using Substrate.Gear.Api.Helper; +global using Substrate.Gear.Client.Model.Types.Base; +global using Substrate.NetApi; +global using Substrate.NetApi.Model.Types.Base; +global using Substrate.NetApi.Model.Types.Primitive; +global using Xunit; +global using GasUnit = Substrate.NetApi.Model.Types.Primitive.U64; +global using ValueUnit = Substrate.NetApi.Model.Types.Primitive.U128; diff --git a/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj new file mode 100644 index 00000000..2c53f255 --- /dev/null +++ b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj @@ -0,0 +1,30 @@ + + + + net8.0 + false + enable + + false + true + + + + + + + + + + + + + + + + + + + + + diff --git a/net/tests/Sails.Client.Tests/idl/demo.idl b/net/tests/Sails.Client.Tests/idl/demo.idl new file mode 100644 index 00000000..d7cc6728 --- /dev/null +++ b/net/tests/Sails.Client.Tests/idl/demo.idl @@ -0,0 +1,91 @@ +type ReferenceCount = struct { + u32, +}; + +type DoThatParam = struct { + p1: nat32, + p2: actor_id, + p3: ManyVariants, +}; + +type ManyVariants = enum { + One, + Two: u32, + Three: opt u256, + Four: struct { a: u32, b: opt u16 }, + Five: struct { str, h256 }, + Six: struct { u32 }, +}; + +type TupleStruct = struct { + bool, +}; + +constructor { + /// Program constructor (called once at the very beginning of the program lifetime) + Default : (); + /// Another program constructor (called once at the very beginning of the program lifetime) + New : (counter: opt u32, dog_position: opt struct { i32, i32 }); +}; + +service Counter { + /// Add a value to the counter + Add : (value: u32) -> u32; + /// Substract a value from the counter + Sub : (value: u32) -> u32; + /// Get the current value + query Value : () -> u32; + + events { + /// Emitted when a new value is added to the counter + Added: u32; + /// Emitted when a value is subtracted from the counter + Subtracted: u32; + } +}; + +service Dog { + MakeSound : () -> str; + Walk : (dx: i32, dy: i32) -> null; + query AvgWeight : () -> u32; + query Position : () -> struct { i32, i32 }; + + events { + Barked; + Walked: struct { from: struct { i32, i32 }, to: struct { i32, i32 } }; + } +}; + +service PingPong { + Ping : (input: str) -> result (str, str); +}; + +service References { + Add : (v: u32) -> u32; + AddByte : (byte: u8) -> vec u8; + GuessNum : (number: u8) -> result (str, str); + Incr : () -> ReferenceCount; + SetNum : (number: u8) -> result (null, str); + query Baked : () -> str; + query LastByte : () -> opt u8; + query Message : () -> opt str; +}; + +service ThisThat { + DoThat : (param: DoThatParam) -> result (struct { actor_id, nat32 }, struct { str }); + DoThis : (p1: u32, p2: str, p3: struct { opt h160, nat8 }, p4: TupleStruct) -> struct { str, u32 }; + Noop : () -> null; + query That : () -> result (str, str); + query This : () -> u32; +}; + +service ValueFee { + /// Return flag if fee taken and remain value, + /// using special type `CommandReply` + DoSomethingAndTakeFee : () -> bool; + + events { + Withheld: u128; + } +}; + From ca06052accf9c8b545d0db78a35c58c0e1ee72fa Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 13 Nov 2024 12:24:32 +0100 Subject: [PATCH 44/54] tyr fix --- net/Directory.Packages.props | 1 + net/src/Sails.ClientGenerator/NativeMethods.cs | 2 +- .../Sails.ClientGenerator.csproj | 16 ++++++++-------- .../Sails.Client.Tests/Sails.Client.Tests.csproj | 1 + 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/net/Directory.Packages.props b/net/Directory.Packages.props index d66af75e..9a246b32 100644 --- a/net/Directory.Packages.props +++ b/net/Directory.Packages.props @@ -5,6 +5,7 @@ + diff --git a/net/src/Sails.ClientGenerator/NativeMethods.cs b/net/src/Sails.ClientGenerator/NativeMethods.cs index 565f5971..4ed3bd8a 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.cs @@ -4,7 +4,7 @@ namespace Sails.ClientGenerator; internal static unsafe partial class NativeMethods { - private const string DllName = "sails_net_client_gen"; + private const string DllName = "libsails_net_client_gen"; /// /// # Safety diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index aedd7cd9..e568f2be 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -27,18 +27,18 @@ - - - - + + + + - - - - + + + + diff --git a/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj index 2c53f255..aece6a1b 100644 --- a/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj +++ b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj @@ -15,6 +15,7 @@ + From 7f251f7297379ac1052acaca2d4c05768cae6240 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 13 Nov 2024 16:05:55 +0100 Subject: [PATCH 45/54] try fix 2 --- net/Directory.Build.props | 7 ------- net/Directory.Packages.props | 3 ++- net/src/Sails.ClientGenerator/.cargo/config.toml | 2 ++ .../Sails.ClientGenerator/Sails.ClientGenerator.csproj | 8 ++++---- 4 files changed, 8 insertions(+), 12 deletions(-) create mode 100644 net/src/Sails.ClientGenerator/.cargo/config.toml diff --git a/net/Directory.Build.props b/net/Directory.Build.props index 8005fa4e..f432a50a 100644 --- a/net/Directory.Build.props +++ b/net/Directory.Build.props @@ -15,13 +15,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - all - all diff --git a/net/Directory.Packages.props b/net/Directory.Packages.props index 9a246b32..01df280b 100644 --- a/net/Directory.Packages.props +++ b/net/Directory.Packages.props @@ -5,7 +5,7 @@ - + @@ -14,6 +14,7 @@ + diff --git a/net/src/Sails.ClientGenerator/.cargo/config.toml b/net/src/Sails.ClientGenerator/.cargo/config.toml new file mode 100644 index 00000000..efb1a8a9 --- /dev/null +++ b/net/src/Sails.ClientGenerator/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.x86_64-unknown-linux-gnu] +rustflags = ["-C", "link-arg=-Wl,-soname,libsails_net_client_gen.so"] diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index e568f2be..9cbe682d 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -2,6 +2,7 @@ netstandard2.0 + false enable enable @@ -15,8 +16,7 @@ - - + @@ -41,9 +41,9 @@ - - + + From 9d3f3785310e32ed968f5522a07eab09598634be Mon Sep 17 00:00:00 2001 From: vobradovich Date: Wed, 13 Nov 2024 17:18:28 +0100 Subject: [PATCH 46/54] fix comments --- net/rs/Cargo.lock | 2 +- net/rs/Cargo.toml | 2 +- .../Loader/LibraryLoader.cs | 10 +++++----- .../Sails.Client.Tests.csproj | 1 - .../Sails.ClientGenerator.Tests/GlobalUsings.cs | 12 ++++++++++++ .../InMemoryAdditionalText.cs | 2 -- .../Sails.ClientGenerator.Tests.csproj | 17 ++++------------- .../SailsClientGeneratorTests.cs | 5 ----- 8 files changed, 23 insertions(+), 28 deletions(-) create mode 100644 net/tests/Sails.ClientGenerator.Tests/GlobalUsings.cs diff --git a/net/rs/Cargo.lock b/net/rs/Cargo.lock index b3df8240..0263b829 100644 --- a/net/rs/Cargo.lock +++ b/net/rs/Cargo.lock @@ -574,7 +574,7 @@ dependencies = [ [[package]] name = "sails-net-client-gen" -version = "0.6.3" +version = "0.0.1" dependencies = [ "anyhow", "convert_case", diff --git a/net/rs/Cargo.toml b/net/rs/Cargo.toml index e72e56f4..64cb154f 100644 --- a/net/rs/Cargo.toml +++ b/net/rs/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "0.6.3" +version = "0.0.1" authors = ["Gear Technologies"] edition = "2021" license = "GPL-3.0" diff --git a/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs b/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs index 9925dd39..100332c7 100644 --- a/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs +++ b/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs @@ -7,7 +7,7 @@ namespace Sails.ClientGenerator.Loader; /// /// Exposes functionality for loading native libraries and function pointers. /// -public abstract class LibraryLoader +internal abstract class LibraryLoader { /// /// Loads a native library by name and returns an operating system handle to it. @@ -16,9 +16,9 @@ public abstract class LibraryLoader /// The operating system handle for the shared library. /// /// - public IntPtr LoadNativeLibraryByPath(params string[] names) + internal IntPtr LoadNativeLibraryByPath(params string[] names) { - foreach (var loadTarget in names!) + foreach (var loadTarget in names) { if (File.Exists(loadTarget)) { @@ -38,7 +38,7 @@ public IntPtr LoadNativeLibraryByPath(params string[] names) /// The operating system handle of the opened shared library. /// The name of the exported function to load. /// A pointer to the loaded function. - public IntPtr LoadFunctionPointer(IntPtr handle, string functionName) + internal IntPtr LoadFunctionPointer(IntPtr handle, string functionName) { if (string.IsNullOrEmpty(functionName)) { @@ -52,7 +52,7 @@ public IntPtr LoadFunctionPointer(IntPtr handle, string functionName) /// Frees the library represented by the given operating system handle. /// /// The handle of the open shared library. - public void FreeNativeLibrary(IntPtr handle) + internal void FreeNativeLibrary(IntPtr handle) { if (handle == IntPtr.Zero) { diff --git a/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj index aece6a1b..37d5807e 100644 --- a/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj +++ b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj @@ -3,7 +3,6 @@ net8.0 false - enable false true diff --git a/net/tests/Sails.ClientGenerator.Tests/GlobalUsings.cs b/net/tests/Sails.ClientGenerator.Tests/GlobalUsings.cs new file mode 100644 index 00000000..c2d2d1db --- /dev/null +++ b/net/tests/Sails.ClientGenerator.Tests/GlobalUsings.cs @@ -0,0 +1,12 @@ +global using System.Collections.Immutable; +global using System.IO; +global using System.Linq; +global using System.Runtime.CompilerServices; +global using System.Threading; +global using System.Threading.Tasks; +global using Microsoft.CodeAnalysis; +global using Microsoft.CodeAnalysis.CSharp; +global using Microsoft.CodeAnalysis.Text; +global using VerifyTests; +global using VerifyXunit; +global using Xunit; diff --git a/net/tests/Sails.ClientGenerator.Tests/InMemoryAdditionalText.cs b/net/tests/Sails.ClientGenerator.Tests/InMemoryAdditionalText.cs index d64ebecf..3646a41c 100644 --- a/net/tests/Sails.ClientGenerator.Tests/InMemoryAdditionalText.cs +++ b/net/tests/Sails.ClientGenerator.Tests/InMemoryAdditionalText.cs @@ -1,6 +1,4 @@ using System.Text; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Text; namespace Sails.ClientGenerator.Tests; diff --git a/net/tests/Sails.ClientGenerator.Tests/Sails.ClientGenerator.Tests.csproj b/net/tests/Sails.ClientGenerator.Tests/Sails.ClientGenerator.Tests.csproj index d37e346c..63beab01 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Sails.ClientGenerator.Tests.csproj +++ b/net/tests/Sails.ClientGenerator.Tests/Sails.ClientGenerator.Tests.csproj @@ -2,15 +2,16 @@ net8.0 - enable - enable + false false true - + + PreserveNewest + @@ -26,14 +27,4 @@ - - - - - - - PreserveNewest - - - diff --git a/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs b/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs index c287391d..2b3e7e6f 100644 --- a/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs +++ b/net/tests/Sails.ClientGenerator.Tests/SailsClientGeneratorTests.cs @@ -1,8 +1,3 @@ -using System.Collections.Immutable; -using System.Runtime.CompilerServices; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; - namespace Sails.ClientGenerator.Tests; public class SailsClientGeneratorTests From 0aab4fea5e201888367ee1a95e7b441d2c4a2dff Mon Sep 17 00:00:00 2001 From: vobradovich Date: Thu, 14 Nov 2024 11:50:10 +0100 Subject: [PATCH 47/54] resolve linux lib loading --- .../Sails.ClientGenerator/.cargo/config.toml | 2 - net/src/Sails.ClientGenerator/GlobalUsings.cs | 12 +++++ .../Sails.ClientGenerator/Loader/Kernel32.cs | 4 +- net/src/Sails.ClientGenerator/Loader/Libdl.cs | 2 - .../Loader/LibraryLoader.cs | 2 - .../Loader/NativeLibrary.cs | 54 +++++++++++++++++++ .../NativeMethods.Loader.cs | 13 +---- .../Sails.ClientGenerator/NativeMethods.cs | 8 +-- .../Sails.ClientGenerator.csproj | 1 - .../SailsClientGenerator.cs | 44 +++++++-------- 10 files changed, 89 insertions(+), 53 deletions(-) delete mode 100644 net/src/Sails.ClientGenerator/.cargo/config.toml create mode 100644 net/src/Sails.ClientGenerator/GlobalUsings.cs create mode 100644 net/src/Sails.ClientGenerator/Loader/NativeLibrary.cs diff --git a/net/src/Sails.ClientGenerator/.cargo/config.toml b/net/src/Sails.ClientGenerator/.cargo/config.toml deleted file mode 100644 index efb1a8a9..00000000 --- a/net/src/Sails.ClientGenerator/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.x86_64-unknown-linux-gnu] -rustflags = ["-C", "link-arg=-Wl,-soname,libsails_net_client_gen.so"] diff --git a/net/src/Sails.ClientGenerator/GlobalUsings.cs b/net/src/Sails.ClientGenerator/GlobalUsings.cs new file mode 100644 index 00000000..c7d70746 --- /dev/null +++ b/net/src/Sails.ClientGenerator/GlobalUsings.cs @@ -0,0 +1,12 @@ +global using System; +global using System.Collections.Generic; +global using System.Collections.Immutable; +global using System.IO; +global using System.Reflection; +global using System.Runtime.InteropServices; +global using System.Text; +global using System.Threading; +global using Microsoft.CodeAnalysis; +global using Microsoft.CodeAnalysis.CSharp; +global using Microsoft.CodeAnalysis.Text; +global using Sails.ClientGenerator.Loader; diff --git a/net/src/Sails.ClientGenerator/Loader/Kernel32.cs b/net/src/Sails.ClientGenerator/Loader/Kernel32.cs index 632bf383..94a9941e 100644 --- a/net/src/Sails.ClientGenerator/Loader/Kernel32.cs +++ b/net/src/Sails.ClientGenerator/Loader/Kernel32.cs @@ -1,6 +1,4 @@ -using System.Runtime.InteropServices; - -namespace Sails.ClientGenerator.Loader; +namespace Sails.ClientGenerator.Loader; internal static class Kernel32 { diff --git a/net/src/Sails.ClientGenerator/Loader/Libdl.cs b/net/src/Sails.ClientGenerator/Loader/Libdl.cs index 6ae3bb60..abd662e3 100644 --- a/net/src/Sails.ClientGenerator/Loader/Libdl.cs +++ b/net/src/Sails.ClientGenerator/Loader/Libdl.cs @@ -1,7 +1,5 @@ #pragma warning disable RCS0056 // A line is too long -using System.Runtime.InteropServices; - namespace Sails.ClientGenerator.Loader; internal static class Libdl diff --git a/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs b/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs index 100332c7..a71d331b 100644 --- a/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs +++ b/net/src/Sails.ClientGenerator/Loader/LibraryLoader.cs @@ -1,7 +1,5 @@ #pragma warning disable RS1035 // Do not use APIs banned for analyzers -using System.Runtime.InteropServices; - namespace Sails.ClientGenerator.Loader; /// diff --git a/net/src/Sails.ClientGenerator/Loader/NativeLibrary.cs b/net/src/Sails.ClientGenerator/Loader/NativeLibrary.cs new file mode 100644 index 00000000..dc83c563 --- /dev/null +++ b/net/src/Sails.ClientGenerator/Loader/NativeLibrary.cs @@ -0,0 +1,54 @@ +namespace Sails.ClientGenerator.Loader; +internal class NativeLibrary : IDisposable +{ + private static readonly LibraryLoader Loader = LibraryLoader.GetPlatformDefaultLoader(); + + /// + /// The operating system handle of the loaded library. + /// + public IntPtr Handle { get; } + + /// + /// Constructs a new NativeLibrary using the platform's default library loader. + /// + /// The path to the library to load. + public NativeLibrary(string path) + { + var libPtr = Loader.LoadNativeLibraryByPath(path); + if (libPtr == IntPtr.Zero) + { + throw new FileNotFoundException($"Could not find or load the native library: {path}"); + } + this.Handle = libPtr; + } + + /// + /// Loads a function whose signature matches the given delegate type's signature. + /// + /// The type of delegate to return. + /// The name of the native export. + /// A delegate wrapping the native function. + /// Thrown when no function with the given name + /// is exported from the native library. + public T LoadFunction(string name) + { + var functionPtr = Loader.LoadFunctionPointer(this.Handle, name); + if (functionPtr == IntPtr.Zero) + { + throw new InvalidOperationException($"No function was found with the name {name}."); + } + return Marshal.GetDelegateForFunctionPointer(functionPtr); + } + + /// + /// Loads a function pointer with the given name. + /// + /// The name of the native export. + /// A function pointer for the given name, or 0 if no function with that name exists. + public IntPtr LoadFunction(string name) => Loader.LoadFunctionPointer(this.Handle, name); + + /// + /// Frees the native library. Function pointers retrieved from this library will be void. + /// + public void Dispose() => Loader.FreeNativeLibrary(this.Handle); +} diff --git a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs index e5e1f9a6..e7ad7983 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs @@ -1,14 +1,10 @@ #pragma warning disable RS1035 // Do not use APIs banned for analyzers -using System.Reflection; -using System.Runtime.InteropServices; -using Sails.ClientGenerator.Loader; - namespace Sails.ClientGenerator; internal static unsafe partial class NativeMethods { - internal static IntPtr LoadNativeLibrary() + internal static NativeLibrary LoadNativeLibrary() { // Determine where to extract the DLL var tempDirectory = Path.Combine(Path.GetTempPath(), DllName); @@ -21,12 +17,7 @@ internal static IntPtr LoadNativeLibrary() { ExtractResourceToFile($"{platform}.{DllName}{extension}", nativeLibraryPath); } - var ret = LibraryLoader.GetPlatformDefaultLoader().LoadNativeLibraryByPath(nativeLibraryPath); - if (ret == IntPtr.Zero) - { - throw new FileNotFoundException($"Could not find or load the native library: {nativeLibraryPath}"); - } - return ret; + return new NativeLibrary(nativeLibraryPath); } internal static void FreeNativeLibrary(IntPtr handle) => LibraryLoader.GetPlatformDefaultLoader().FreeNativeLibrary(handle); diff --git a/net/src/Sails.ClientGenerator/NativeMethods.cs b/net/src/Sails.ClientGenerator/NativeMethods.cs index 4ed3bd8a..73d333f2 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Sails.ClientGenerator; internal static unsafe partial class NativeMethods @@ -11,14 +9,12 @@ internal static unsafe partial class NativeMethods /// /// Function [`free_c_string`] should be called after this function /// - [DllImport(DllName, EntryPoint = "generate_dotnet_client", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - internal static extern byte* generate_dotnet_client(byte* program_utf8, int program_len, byte* config_utf8, int config_len); + internal delegate byte* GenerateDotnetClient(byte* program_utf8, int program_len, byte* config_utf8, int config_len); /// /// # Safety /// /// This function should not be called before the [`generate_dotnet_client`] /// - [DllImport(DllName, EntryPoint = "free_c_string", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - internal static extern void free_c_string(byte* str); + internal delegate void FreeCString(byte* str); } diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 9cbe682d..36771b84 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -4,7 +4,6 @@ netstandard2.0 false - enable enable latest true diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index 00234881..e183be61 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -1,8 +1,4 @@ -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Text; +using static Sails.ClientGenerator.NativeMethods; namespace Sails.ClientGenerator; @@ -42,33 +38,29 @@ private static void AddSource( private static unsafe string GenerateCode(string source, GeneratorConfig config) { - var handle = NativeMethods.LoadNativeLibrary(); - try - { - var idlBytes = Encoding.UTF8.GetBytes(source); - var configBytes = Encoding.UTF8.GetBytes(config.ToString()); + using var library = LoadNativeLibrary(); + var generateFunc = library.LoadFunction("generate_dotnet_client"); + var freeFunc = library.LoadFunction("free_c_string"); + + var idlBytes = Encoding.UTF8.GetBytes(source); + var configBytes = Encoding.UTF8.GetBytes(config.ToString()); - fixed (byte* pIdl = idlBytes) + fixed (byte* idlPtr = idlBytes) + { + fixed (byte* configPtr = configBytes) { - fixed (byte* pConfig = configBytes) + var cstr = generateFunc(idlPtr, idlBytes.Length, configPtr, configBytes.Length); + try { - var cstr = NativeMethods.generate_dotnet_client(pIdl, idlBytes.Length, pConfig, configBytes.Length); - try - { - var str = new string((sbyte*)cstr); - return FormatCode(str); - } - finally - { - NativeMethods.free_c_string(cstr); - } + var str = new string((sbyte*)cstr); + return FormatCode(str); + } + finally + { + freeFunc(cstr); } } } - finally - { - NativeMethods.FreeNativeLibrary(handle); - } } private static string FormatCode(string code, CancellationToken cancellationToken = default) From 29490e757b18785241f43e85371c72f906532e1c Mon Sep 17 00:00:00 2001 From: vobradovich Date: Thu, 14 Nov 2024 14:54:43 +0100 Subject: [PATCH 48/54] fix comments --- .github/workflows/net-build-client-gen.yml | 2 -- net/Directory.Build.props | 6 +++--- net/Directory.Packages.props | 3 ++- .../Sails.ClientGenerator/GeneratorConfig.cs | 2 +- .../NativeMethods.Loader.cs | 3 ++- .../Sails.ClientGenerator.csproj | 2 -- .../SailsClientGenerator.cs | 18 ++++++++++++++---- .../Sails.Client.Tests.csproj | 1 - 8 files changed, 22 insertions(+), 15 deletions(-) diff --git a/.github/workflows/net-build-client-gen.yml b/.github/workflows/net-build-client-gen.yml index e4499cde..5e743526 100644 --- a/.github/workflows/net-build-client-gen.yml +++ b/.github/workflows/net-build-client-gen.yml @@ -7,13 +7,11 @@ on: paths: - '.github/workflows/net-build-client-gen.yml' - 'net/rs/**' - - 'rs/idl-parser/**' pull_request: paths: - '.github/workflows/net-build-client-gen.yml' - 'net/rs/**' - - 'rs/idl-parser/**' jobs: win-x64: diff --git a/net/Directory.Build.props b/net/Directory.Build.props index f432a50a..67092710 100644 --- a/net/Directory.Build.props +++ b/net/Directory.Build.props @@ -7,6 +7,9 @@ + + all + all runtime; build; native; contentfiles; analyzers @@ -15,9 +18,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - all - diff --git a/net/Directory.Packages.props b/net/Directory.Packages.props index 079e5d8f..cd00f1f8 100644 --- a/net/Directory.Packages.props +++ b/net/Directory.Packages.props @@ -22,7 +22,8 @@ + - + diff --git a/net/src/Sails.ClientGenerator/GeneratorConfig.cs b/net/src/Sails.ClientGenerator/GeneratorConfig.cs index 85250d47..bb34df13 100644 --- a/net/src/Sails.ClientGenerator/GeneratorConfig.cs +++ b/net/src/Sails.ClientGenerator/GeneratorConfig.cs @@ -5,6 +5,6 @@ public record struct GeneratorConfig( string Namespace ) { - public override string ToString() + public readonly string ToJsonString() => $"{{ \"service_name\": \"{this.ServiceName}\", \"namespace\": \"{this.Namespace}\" }}"; } diff --git a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs index e7ad7983..d0c00a43 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs @@ -7,7 +7,8 @@ internal static unsafe partial class NativeMethods internal static NativeLibrary LoadNativeLibrary() { // Determine where to extract the DLL - var tempDirectory = Path.Combine(Path.GetTempPath(), DllName); + var version = typeof(NativeMethods).Assembly.GetName().Version.ToString(); + var tempDirectory = Path.Combine(Path.GetTempPath(), DllName, version); Directory.CreateDirectory(tempDirectory); var (platform, extension) = GetResourcePlatform(); diff --git a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj index 36771b84..d5dfcbd0 100644 --- a/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj +++ b/net/src/Sails.ClientGenerator/Sails.ClientGenerator.csproj @@ -4,8 +4,6 @@ netstandard2.0 false - enable - latest true true $(NoWarn);NU5128 diff --git a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs index e183be61..a26c735d 100644 --- a/net/src/Sails.ClientGenerator/SailsClientGenerator.cs +++ b/net/src/Sails.ClientGenerator/SailsClientGenerator.cs @@ -19,18 +19,28 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private static void AddSource( SourceProductionContext context, - (string? AssemblyName, ImmutableArray Right) tuple) + (string? AssemblyName, ImmutableArray Texts) tuple) { + if (tuple.AssemblyName is null) + { + // Do not generated code without Assembly in Compilation + return; + } var assemblyName = tuple.AssemblyName!; - foreach (var source in tuple.Right) + foreach (var source in tuple.Texts) { + var text = source.GetText(); + if (text is null) + { + continue; + } // TODO: add relative directory as namespace part var parts = new List(); parts.Insert(0, assemblyName); var name = FirstUpper(Path.GetFileNameWithoutExtension(source.Path)); parts.Add(name); var ns = string.Join(".", parts); - var code = GenerateCode(source.GetText()!.ToString(), new GeneratorConfig(name, ns)); + var code = GenerateCode(text.ToString(), new GeneratorConfig(name, ns)); context.AddSource($"{name}.g.cs", SourceText.From(code, encoding: Encoding.UTF8)); } @@ -43,7 +53,7 @@ private static unsafe string GenerateCode(string source, GeneratorConfig config) var freeFunc = library.LoadFunction("free_c_string"); var idlBytes = Encoding.UTF8.GetBytes(source); - var configBytes = Encoding.UTF8.GetBytes(config.ToString()); + var configBytes = Encoding.UTF8.GetBytes(config.ToJsonString()); fixed (byte* idlPtr = idlBytes) { diff --git a/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj index 37d5807e..5cd70bb8 100644 --- a/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj +++ b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj @@ -17,7 +17,6 @@ - From 1144f8180fd0dca74a50d0695ee3a323063f8b5f Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 15 Nov 2024 11:28:19 +0100 Subject: [PATCH 49/54] ref test analyzer --- net/Directory.Build.props | 3 --- net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/net/Directory.Build.props b/net/Directory.Build.props index 67092710..6c268046 100644 --- a/net/Directory.Build.props +++ b/net/Directory.Build.props @@ -7,9 +7,6 @@ - - all - all runtime; build; native; contentfiles; analyzers diff --git a/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj index 5cd70bb8..37d5807e 100644 --- a/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj +++ b/net/tests/Sails.Client.Tests/Sails.Client.Tests.csproj @@ -17,6 +17,7 @@ + From 2c39ec5de5930fbe0cb90f97445ea63faf4a642f Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 15 Nov 2024 12:21:57 +0100 Subject: [PATCH 50/54] add Verify settings --- .gitattributes | 6 ++++++ .gitignore | 4 ++++ net/.editorconfig | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/.gitattributes b/.gitattributes index b4642704..53e1cf47 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,3 +8,9 @@ *.ts text *.json text yarn.lock merge=union + +# Verify +*.verified.txt text eol=lf working-tree-encoding=UTF-8 +*.verified.xml text eol=lf working-tree-encoding=UTF-8 +*.verified.json text eol=lf working-tree-encoding=UTF-8 +*.verified.cs text eol=lf working-tree-encoding=UTF-8 diff --git a/.gitignore b/.gitignore index 06aa6dda..6d635378 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,7 @@ js/test/demo/ !.yarn/sdks !.yarn/versions .npmrc + +# Verify +*.received.* +*.received/ diff --git a/net/.editorconfig b/net/.editorconfig index 08a259ed..b71af5bf 100644 --- a/net/.editorconfig +++ b/net/.editorconfig @@ -501,3 +501,13 @@ dotnet_diagnostic.IDE0060.severity = none csharp_style_unused_value_assignment_preference = discard_variable:none dotnet_diagnostic.IDE0059.severity = none dotnet_diagnostic.CA1416.severity = warning + +# Verify settings +[*.{received,verified}.{json,txt,xml,cs}] +charset = "utf-8-bom" +end_of_line = lf +indent_size = unset +indent_style = unset +insert_final_newline = false +tab_width = unset +trim_trailing_whitespace = false From 5c90b38e0fad9c115163d470d5a4680205739258 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 15 Nov 2024 12:30:04 +0100 Subject: [PATCH 51/54] fix --- ...ailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs index 6eacbfb6..f8d8fcfa 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs @@ -559,4 +559,4 @@ public override void Decode(byte[] byteArray, ref int p) this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } -} +} \ No newline at end of file From 2055f712900298bdad75238173c789584d80b4bb Mon Sep 17 00:00:00 2001 From: Vadim Obradovich Date: Fri, 15 Nov 2024 12:54:29 +0100 Subject: [PATCH 52/54] Rename SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs to SailsClientGeneratorTests.Generate_DemoIdl#Demo.g.verified.cs --- ...ilsClientGeneratorTests.Generate_DemoIdl#Demo.g.verified.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename net/tests/Sails.ClientGenerator.Tests/Snapshots/{SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs => SailsClientGeneratorTests.Generate_DemoIdl#Demo.g.verified.cs} (99%) diff --git a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#Demo.g.verified.cs similarity index 99% rename from net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs rename to net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#Demo.g.verified.cs index f8d8fcfa..6eacbfb6 100644 --- a/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#demo.g.verified.cs +++ b/net/tests/Sails.ClientGenerator.Tests/Snapshots/SailsClientGeneratorTests.Generate_DemoIdl#Demo.g.verified.cs @@ -559,4 +559,4 @@ public override void Decode(byte[] byteArray, ref int p) this.Bytes = new byte[bytesLength]; Array.Copy(byteArray, start, this.Bytes, 0, bytesLength); } -} \ No newline at end of file +} From 6e2a8a6c248cbd71d07c28db3b70c38e5e61a283 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 15 Nov 2024 14:12:30 +0100 Subject: [PATCH 53/54] save lib in folder with hash --- .../NativeMethods.Loader.cs | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs index d0c00a43..2304b4a1 100644 --- a/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs +++ b/net/src/Sails.ClientGenerator/NativeMethods.Loader.cs @@ -1,23 +1,14 @@ #pragma warning disable RS1035 // Do not use APIs banned for analyzers +using System.Security.Cryptography; + namespace Sails.ClientGenerator; internal static unsafe partial class NativeMethods { internal static NativeLibrary LoadNativeLibrary() { - // Determine where to extract the DLL - var version = typeof(NativeMethods).Assembly.GetName().Version.ToString(); - var tempDirectory = Path.Combine(Path.GetTempPath(), DllName, version); - Directory.CreateDirectory(tempDirectory); - - var (platform, extension) = GetResourcePlatform(); - var nativeLibraryPath = Path.Combine(tempDirectory, DllName + extension); - // Extract the DLL only if it doesn't already exist - if (!File.Exists(nativeLibraryPath)) - { - ExtractResourceToFile($"{platform}.{DllName}{extension}", nativeLibraryPath); - } + var nativeLibraryPath = ExtractResourceToFile(DllName); return new NativeLibrary(nativeLibraryPath); } @@ -59,15 +50,40 @@ private static (string Platform, string Extension) GetResourcePlatform() return (platform, extension); } - private static void ExtractResourceToFile(string resourceName, string filePath) + private static string ExtractResourceToFile(string dllName) { + var (platform, extension) = GetResourcePlatform(); + var resourceName = $"{platform}.{DllName}{extension}"; + + // Get library bytes var assembly = Assembly.GetExecutingAssembly(); using var resourceStream = assembly.GetManifestResourceStream(resourceName); if (resourceStream == null) { throw new Exception($"Resource '{resourceName}' not found in assembly."); } - using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write); - resourceStream.CopyTo(fileStream); + using var memoryStream = new MemoryStream(); + resourceStream.CopyTo(memoryStream); + var bytes = memoryStream.ToArray(); + + var hash = SHA1.Create().ComputeHash(bytes); + var hashString = Convert.ToBase64String(hash) + .Replace('+', '-') // replace URL unsafe characters with safe ones + .Replace('/', '_') // replace URL unsafe characters with safe ones + .Replace("=", "") // no padding + .ToLowerInvariant(); + + // Determine where to extract the DLL + var tempDirectory = Path.Combine(Path.GetTempPath(), DllName, hashString); + Directory.CreateDirectory(tempDirectory); + + var nativeLibraryPath = Path.Combine(tempDirectory, DllName + extension); + // Extract the DLL only if it doesn't already exist + if (!File.Exists(nativeLibraryPath)) + { + using var fileStream = new FileStream(nativeLibraryPath, FileMode.Create, FileAccess.Write); + fileStream.Write(bytes, 0, bytes.Length); + } + return nativeLibraryPath; } } From 2376211d414262c81fb2927a3fd86b1afd468553 Mon Sep 17 00:00:00 2001 From: vobradovich Date: Fri, 15 Nov 2024 15:05:58 +0100 Subject: [PATCH 54/54] set nullable disable for types --- net/src/Substrate.Gear.Client/Model/Types/Base/BaseNonZero.cs | 4 ++-- net/src/Substrate.Gear.Client/Model/Types/Primitive/H160.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/src/Substrate.Gear.Client/Model/Types/Base/BaseNonZero.cs b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseNonZero.cs index ae4db676..63f3149f 100644 --- a/net/src/Substrate.Gear.Client/Model/Types/Base/BaseNonZero.cs +++ b/net/src/Substrate.Gear.Client/Model/Types/Base/BaseNonZero.cs @@ -1,4 +1,5 @@ -using System; +#nullable disable +using System; using Substrate.NetApi.Model.Types.Base; namespace Substrate.Gear.Client.Model.Types.Base; @@ -11,7 +12,6 @@ public class BaseNonZero : BaseType /// /// >> value /// - [System.Diagnostics.CodeAnalysis.AllowNull] public T Value { get; set; } public BaseNonZero() diff --git a/net/src/Substrate.Gear.Client/Model/Types/Primitive/H160.cs b/net/src/Substrate.Gear.Client/Model/Types/Primitive/H160.cs index 49555c71..39a48ffc 100644 --- a/net/src/Substrate.Gear.Client/Model/Types/Primitive/H160.cs +++ b/net/src/Substrate.Gear.Client/Model/Types/Primitive/H160.cs @@ -1,4 +1,5 @@ -using System; +#nullable disable +using System; using Substrate.Gear.Api.Generated.Types.Base; using Substrate.NetApi.Attributes; using Substrate.NetApi.Model.Types.Base; @@ -15,7 +16,6 @@ public sealed class H160 : BaseType /// /// >> value /// - [System.Diagnostics.CodeAnalysis.AllowNull] public Arr20U8 Value { get; set; } ///