From 1af86b89b208010c19a0569b840b0655a814828c Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:23:48 +1000 Subject: [PATCH 01/20] Generate schemars derives in Rust generator --- lib/xdrgen/generators/rust.rb | 20 ++++++++++---------- lib/xdrgen/generators/rust/src/types.rs | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index e43077308..26b9e5a0f 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -99,7 +99,7 @@ def render_enum_of_all_types(out, types) #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -152,7 +152,7 @@ def render_enum_of_all_types(out, types) #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] @@ -365,9 +365,9 @@ def render_struct(out, struct) out.puts "#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]" out.puts %{#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]} if @options[:rust_types_custom_str_impl].include?(name struct) - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))]} else - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))]} end out.puts "pub struct #{name struct} {" out.indent do @@ -411,9 +411,9 @@ def render_enum(out, enum) out.puts "#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]" out.puts %{#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]} if @options[:rust_types_custom_str_impl].include?(name enum) - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))]} else - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))]} end out.puts "#[repr(i32)]" out.puts "pub enum #{name enum} {" @@ -540,9 +540,9 @@ def render_union(out, union) out.puts "#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]" out.puts %{#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]} if @options[:rust_types_custom_str_impl].include?(name union) - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))]} else - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))]} end out.puts "#[allow(clippy::large_enum_variant)]" out.puts "pub enum #{name union} {" @@ -674,9 +674,9 @@ def render_typedef(out, typedef) out.puts %{#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]} out.puts "#[derive(Default)]" if is_var_array_type(typedef.type) if is_fixed_array_opaque(typedef.type) || @options[:rust_types_custom_str_impl].include?(name typedef) - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))]} else - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))]} end if !is_fixed_array_opaque(typedef.type) out.puts "#[derive(Debug)]" diff --git a/lib/xdrgen/generators/rust/src/types.rs b/lib/xdrgen/generators/rust/src/types.rs index bc05694ad..22b7e6423 100644 --- a/lib/xdrgen/generators/rust/src/types.rs +++ b/lib/xdrgen/generators/rust/src/types.rs @@ -863,7 +863,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1269,7 +1269,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1650,7 +1650,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2020,7 +2020,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) From 8cb548165a86ef3de504d68159948f852ad7e988 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:26:57 +1000 Subject: [PATCH 02/20] update tsets --- .../block_comments.x/MyXDR.rs | 14 +++--- .../generator_spec_rust/const.x/MyXDR.rs | 12 ++--- .../generator_spec_rust/enum.x/MyXDR.rs | 18 +++---- .../generator_spec_rust/nesting.x/MyXDR.rs | 20 ++++---- .../generator_spec_rust/optional.x/MyXDR.rs | 14 +++--- .../generator_spec_rust/struct.x/MyXDR.rs | 14 +++--- .../generator_spec_rust/test.x/MyXDR.rs | 50 +++++++++---------- .../generator_spec_rust/union.x/MyXDR.rs | 20 ++++---- .../block_comments.x/MyXDR.rs | 14 +++--- .../const.x/MyXDR.rs | 12 ++--- .../enum.x/MyXDR.rs | 18 +++---- .../nesting.x/MyXDR.rs | 20 ++++---- .../optional.x/MyXDR.rs | 14 +++--- .../struct.x/MyXDR.rs | 14 +++--- .../test.x/MyXDR.rs | 50 +++++++++---------- .../union.x/MyXDR.rs | 20 ++++---- 16 files changed, 162 insertions(+), 162 deletions(-) diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index 70fa480fb..2e64bf021 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2698,7 +2698,7 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum AccountFlags { AuthRequiredFlag = 1, @@ -2786,7 +2786,7 @@ impl WriteXdr for AccountFlags { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -2839,7 +2839,7 @@ impl core::str::FromStr for TypeVariant { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index 459077778..14fafaded 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2713,7 +2713,7 @@ pub type TestArray2 = VecM::; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -2771,7 +2771,7 @@ Self::TestArray2 => "TestArray2", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index 80740add2..ccf469a00 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2717,7 +2717,7 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum MessageType { ErrorMsg = 0, @@ -2880,7 +2880,7 @@ Self::FbaMessage => "FbaMessage", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum Color { Red = 0, @@ -2988,7 +2988,7 @@ Self::Blue => "Blue", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum Color2 { Red2 = 0, @@ -3086,7 +3086,7 @@ Self::Blue2 => "Blue2", #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -3149,7 +3149,7 @@ Self::Color2 => "Color2", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 677ed00aa..03ccf84bc 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2699,7 +2699,7 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum UnionKey { One = 1, @@ -2812,7 +2812,7 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct MyUnionOne { pub some_int: i32, } @@ -2849,7 +2849,7 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct MyUnionTwo { pub some_int: i32, pub foo: i32, @@ -2902,7 +2902,7 @@ self.foo.write_xdr(w)?; // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { One(MyUnionOne), @@ -3006,7 +3006,7 @@ Self::Offer => ().write_xdr(w)?, #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -3079,7 +3079,7 @@ Self::MyUnionTwo => "MyUnionTwo", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index c38ee2890..554eec3c2 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2707,7 +2707,7 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct HasOptions { pub first_option: Option, pub second_option: Option, @@ -2742,7 +2742,7 @@ self.third_option.write_xdr(w)?; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -2800,7 +2800,7 @@ Self::HasOptions => "HasOptions", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index 1c59b5e8c..56f9bd2e5 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2709,7 +2709,7 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct MyStruct { pub some_int: i32, pub a_big_int: i64, @@ -2750,7 +2750,7 @@ self.max_string.write_xdr(w)?; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -2808,7 +2808,7 @@ Self::MyStruct => "MyStruct", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index bd9f912c2..b542b0d81 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2694,7 +2694,7 @@ mod test { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2810,7 +2810,7 @@ impl AsRef<[u8]> for Uint512 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Uint513(pub BytesM::<64>); @@ -2911,7 +2911,7 @@ impl AsRef<[u8]> for Uint513 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Uint514(pub BytesM); @@ -3012,7 +3012,7 @@ impl AsRef<[u8]> for Uint514 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Str(pub StringM::<64>); @@ -3113,7 +3113,7 @@ impl AsRef<[u8]> for Str { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Str2(pub StringM); @@ -3213,7 +3213,7 @@ impl AsRef<[u8]> for Str2 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3328,7 +3328,7 @@ impl AsRef<[u8]> for Hash { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Hashes1(pub [Hash; 12]); @@ -3417,7 +3417,7 @@ impl AsRef<[Hash]> for Hashes1 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Hashes2(pub VecM::); @@ -3518,7 +3518,7 @@ impl AsRef<[Hash]> for Hashes2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Hashes3(pub VecM::); @@ -3618,7 +3618,7 @@ impl AsRef<[Hash]> for Hashes3 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct OptHash1(pub Option); @@ -3669,7 +3669,7 @@ impl WriteXdr for OptHash1 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct OptHash2(pub Option); @@ -3761,7 +3761,7 @@ pub type Int4 = u64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct MyStruct { pub field1: Uint512, pub field2: OptHash1, @@ -3816,7 +3816,7 @@ self.field7.write_xdr(w)?; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct LotsOfMyStructs { pub members: VecM::, } @@ -3853,7 +3853,7 @@ impl WriteXdr for LotsOfMyStructs { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct HasStuff { pub data: LotsOfMyStructs, } @@ -3892,7 +3892,7 @@ impl WriteXdr for HasStuff { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum Color { Red = 0, @@ -4015,7 +4015,7 @@ pub const BAR: u64 = FOO; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum NesterNestedEnum { 1 = 0, @@ -4115,7 +4115,7 @@ Self::2 => "2", /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct NesterNestedStruct { pub blah: i32, } @@ -4155,7 +4155,7 @@ impl WriteXdr for NesterNestedStruct { // union with discriminant Color #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[allow(clippy::large_enum_variant)] pub enum NesterNestedUnion { Red, @@ -4269,7 +4269,7 @@ impl WriteXdr for NesterNestedUnion { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct Nester { pub nested_enum: NesterNestedEnum, pub nested_struct: NesterNestedStruct, @@ -4304,7 +4304,7 @@ self.nested_union.write_xdr(w)?; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -4467,7 +4467,7 @@ Self::NesterNestedUnion => "NesterNestedUnion", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 9c601f042..a7e8d8cfd 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2714,7 +2714,7 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum UnionKey { Error = 0, @@ -2821,7 +2821,7 @@ Self::Multi => "Multi", // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { Error(i32), @@ -2931,7 +2931,7 @@ Self::Multi(v) => v.write_xdr(w)?, // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[allow(clippy::large_enum_variant)] pub enum IntUnion { V0(i32), @@ -3033,7 +3033,7 @@ Self::V1(v) => v.write_xdr(w)?, /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3079,7 +3079,7 @@ impl WriteXdr for IntUnion2 { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -3157,7 +3157,7 @@ Self::IntUnion2 => "IntUnion2", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index 70fa480fb..2e64bf021 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2698,7 +2698,7 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum AccountFlags { AuthRequiredFlag = 1, @@ -2786,7 +2786,7 @@ impl WriteXdr for AccountFlags { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -2839,7 +2839,7 @@ impl core::str::FromStr for TypeVariant { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index 459077778..14fafaded 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2713,7 +2713,7 @@ pub type TestArray2 = VecM::; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -2771,7 +2771,7 @@ Self::TestArray2 => "TestArray2", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index 3e9b8dd70..c16fd1aa6 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2717,7 +2717,7 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum MessageType { ErrorMsg = 0, @@ -2880,7 +2880,7 @@ Self::FbaMessage => "FbaMessage", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum Color { Red = 0, @@ -2988,7 +2988,7 @@ Self::Blue => "Blue", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] #[repr(i32)] pub enum Color2 { Red2 = 0, @@ -3086,7 +3086,7 @@ Self::Blue2 => "Blue2", #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -3149,7 +3149,7 @@ Self::Color2 => "Color2", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 3b9486e32..65d3c5e18 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2699,7 +2699,7 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { One = 1, @@ -2812,7 +2812,7 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct MyUnionOne { pub some_int: i32, } @@ -2849,7 +2849,7 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct MyUnionTwo { pub some_int: i32, pub foo: i32, @@ -2902,7 +2902,7 @@ self.foo.write_xdr(w)?; // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { One(MyUnionOne), @@ -3006,7 +3006,7 @@ Self::Offer => ().write_xdr(w)?, #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -3079,7 +3079,7 @@ Self::MyUnionTwo => "MyUnionTwo", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index 735992c52..6e5d07c38 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2707,7 +2707,7 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] pub struct HasOptions { pub first_option: Option, pub second_option: Option, @@ -2742,7 +2742,7 @@ self.third_option.write_xdr(w)?; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -2800,7 +2800,7 @@ Self::HasOptions => "HasOptions", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index ace8f79b3..e727d03b1 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2709,7 +2709,7 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] pub struct MyStruct { pub some_int: i32, pub a_big_int: i64, @@ -2750,7 +2750,7 @@ self.max_string.write_xdr(w)?; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -2808,7 +2808,7 @@ Self::MyStruct => "MyStruct", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index a4b4224a9..3e55699ea 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2694,7 +2694,7 @@ mod test { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2810,7 +2810,7 @@ impl AsRef<[u8]> for Uint512 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Uint513(pub BytesM::<64>); @@ -2911,7 +2911,7 @@ impl AsRef<[u8]> for Uint513 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Uint514(pub BytesM); @@ -3012,7 +3012,7 @@ impl AsRef<[u8]> for Uint514 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Str(pub StringM::<64>); @@ -3113,7 +3113,7 @@ impl AsRef<[u8]> for Str { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Str2(pub StringM); @@ -3213,7 +3213,7 @@ impl AsRef<[u8]> for Str2 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3328,7 +3328,7 @@ impl AsRef<[u8]> for Hash { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Hashes1(pub [Hash; 12]); @@ -3417,7 +3417,7 @@ impl AsRef<[Hash]> for Hashes1 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Hashes2(pub VecM::); @@ -3518,7 +3518,7 @@ impl AsRef<[Hash]> for Hashes2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct Hashes3(pub VecM::); @@ -3618,7 +3618,7 @@ impl AsRef<[Hash]> for Hashes3 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct OptHash1(pub Option); @@ -3669,7 +3669,7 @@ impl WriteXdr for OptHash1 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct OptHash2(pub Option); @@ -3761,7 +3761,7 @@ pub type Int4 = u64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] pub struct MyStruct { pub field1: Uint512, pub field2: OptHash1, @@ -3816,7 +3816,7 @@ self.field7.write_xdr(w)?; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] pub struct LotsOfMyStructs { pub members: VecM::, } @@ -3853,7 +3853,7 @@ impl WriteXdr for LotsOfMyStructs { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct HasStuff { pub data: LotsOfMyStructs, } @@ -3892,7 +3892,7 @@ impl WriteXdr for HasStuff { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum Color { Red = 0, @@ -4015,7 +4015,7 @@ pub const BAR: u64 = FOO; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum NesterNestedEnum { 1 = 0, @@ -4115,7 +4115,7 @@ Self::2 => "2", /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct NesterNestedStruct { pub blah: i32, } @@ -4155,7 +4155,7 @@ impl WriteXdr for NesterNestedStruct { // union with discriminant Color #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[allow(clippy::large_enum_variant)] pub enum NesterNestedUnion { Red, @@ -4269,7 +4269,7 @@ impl WriteXdr for NesterNestedUnion { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] pub struct Nester { pub nested_enum: NesterNestedEnum, pub nested_struct: NesterNestedStruct, @@ -4304,7 +4304,7 @@ self.nested_union.write_xdr(w)?; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -4467,7 +4467,7 @@ Self::NesterNestedUnion => "NesterNestedUnion", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index 54787a07d..b5f378dca 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -873,7 +873,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,7 +1279,7 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,7 +1660,7 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) )] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,7 +2030,7 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub struct Frame(pub T) @@ -2714,7 +2714,7 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { Error = 0, @@ -2821,7 +2821,7 @@ Self::Multi => "Multi", // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { Error(i32), @@ -2931,7 +2931,7 @@ Self::Multi(v) => v.write_xdr(w)?, // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[allow(clippy::large_enum_variant)] pub enum IntUnion { V0(i32), @@ -3033,7 +3033,7 @@ Self::V1(v) => v.write_xdr(w)?, /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3079,7 +3079,7 @@ impl WriteXdr for IntUnion2 { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] pub enum TypeVariant { @@ -3157,7 +3157,7 @@ Self::IntUnion2 => "IntUnion2", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"), serde(untagged), )] From ad48c8bf6ed3a03e3526984a124f42e021ffaed1 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 5 Mar 2024 23:48:47 +1000 Subject: [PATCH 03/20] move jsonschema behind own feature and add support for custom --- README.md | 1 + lib/xdrgen/cli.rb | 2 + lib/xdrgen/generators/rust.rb | 36 +- lib/xdrgen/generators/rust/src/types.rs | 12 +- spec/lib/xdrgen/rust_spec.rb | 19 +- .../block_comments.x/MyXDR.rs | 23 +- .../generator_spec_rust/const.x/MyXDR.rs | 20 +- .../generator_spec_rust/enum.x/MyXDR.rs | 29 +- .../generator_spec_rust/nesting.x/MyXDR.rs | 32 +- .../generator_spec_rust/optional.x/MyXDR.rs | 23 +- .../generator_spec_rust/struct.x/MyXDR.rs | 23 +- .../generator_spec_rust/test.x/MyXDR.rs | 77 +- .../generator_spec_rust/union.x/MyXDR.rs | 32 +- .../block_comments.x/MyXDR.rs | 3003 ++++++++++ .../const.x/MyXDR.rs | 2946 ++++++++++ .../enum.x/MyXDR.rs | 3338 +++++++++++ .../nesting.x/MyXDR.rs | 3292 +++++++++++ .../optional.x/MyXDR.rs | 2975 ++++++++++ .../struct.x/MyXDR.rs | 2983 ++++++++++ .../test.x/MyXDR.rs | 4911 +++++++++++++++++ .../union.x/MyXDR.rs | 3382 ++++++++++++ .../block_comments.x/MyXDR.rs | 23 +- .../const.x/MyXDR.rs | 20 +- .../enum.x/MyXDR.rs | 29 +- .../nesting.x/MyXDR.rs | 32 +- .../optional.x/MyXDR.rs | 23 +- .../struct.x/MyXDR.rs | 23 +- .../test.x/MyXDR.rs | 77 +- .../union.x/MyXDR.rs | 32 +- 29 files changed, 27275 insertions(+), 143 deletions(-) create mode 100644 spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs create mode 100644 spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs create mode 100644 spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs create mode 100644 spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs create mode 100644 spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs create mode 100644 spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs create mode 100644 spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs create mode 100644 spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs diff --git a/README.md b/README.md index 751d211bc..35533ca87 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ c = Xdrgen::Compilation.new( namespace: "MyProgram::XDR", options: { rust_types_custom_str_impl: [], + rust_types_custom_jsonschema_impl: [], }, ) diff --git a/lib/xdrgen/cli.rb b/lib/xdrgen/cli.rb index f818c51f5..f01e09c0f 100644 --- a/lib/xdrgen/cli.rb +++ b/lib/xdrgen/cli.rb @@ -10,6 +10,7 @@ def self.run(args) on 'l', 'language=', 'The output language', default: 'ruby' on 'n', 'namespace=', '"namespace" to generate code within (language-specific)' on 'rust-types-custom-str-impl=', 'Rust types that should not have str implementations generated as they will be provided via custom implementations (rust-specific)' + on 'rust-types-custom-jsonschema-impl=', 'Rust types that should not have jsonschema implementations generated as they will be provided via custom implementations (rust-specific)' end fail(opts) if args.blank? @@ -22,6 +23,7 @@ def self.run(args) namespace: opts[:namespace], options: { rust_types_custom_str_impl: opts[:"rust-types-custom-str-impl"]&.split(',') || [], + rust_types_custom_jsonschema_impl: opts[:"rust-types-custom-jsonschema-impl"]&.split(',') || [], }, ) compilation.compile diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index 26b9e5a0f..41077ce9e 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -102,6 +102,10 @@ def render_enum_of_all_types(out, types) derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { #{types.map { |t| "#{t}," }.join("\n")} } @@ -156,6 +160,10 @@ def render_enum_of_all_types(out, types) serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { #{types.map { |t| "#{t}(Box<#{t}>)," }.join("\n")} } @@ -365,9 +373,12 @@ def render_struct(out, struct) out.puts "#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]" out.puts %{#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]} if @options[:rust_types_custom_str_impl].include?(name struct) - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))]} else - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} + end + if !@options[:rust_types_custom_jsonschema_impl].include?(name struct) + out.puts %{#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))]} end out.puts "pub struct #{name struct} {" out.indent do @@ -411,9 +422,12 @@ def render_enum(out, enum) out.puts "#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]" out.puts %{#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]} if @options[:rust_types_custom_str_impl].include?(name enum) - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))]} else - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} + end + if !@options[:rust_types_custom_jsonschema_impl].include?(name enum) + out.puts %{#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))]} end out.puts "#[repr(i32)]" out.puts "pub enum #{name enum} {" @@ -540,9 +554,12 @@ def render_union(out, union) out.puts "#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]" out.puts %{#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]} if @options[:rust_types_custom_str_impl].include?(name union) - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))]} else - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} + end + if !@options[:rust_types_custom_jsonschema_impl].include?(name union) + out.puts %{#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))]} end out.puts "#[allow(clippy::large_enum_variant)]" out.puts "pub enum #{name union} {" @@ -674,9 +691,12 @@ def render_typedef(out, typedef) out.puts %{#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]} out.puts "#[derive(Default)]" if is_var_array_type(typedef.type) if is_fixed_array_opaque(typedef.type) || @options[:rust_types_custom_str_impl].include?(name typedef) - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))]} else - out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))]} + out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} + end + if !@options[:rust_types_custom_jsonschema_impl].include?(name typedef) + out.puts %{#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))]} end if !is_fixed_array_opaque(typedef.type) out.puts "#[derive(Debug)]" diff --git a/lib/xdrgen/generators/rust/src/types.rs b/lib/xdrgen/generators/rust/src/types.rs index 22b7e6423..593987397 100644 --- a/lib/xdrgen/generators/rust/src/types.rs +++ b/lib/xdrgen/generators/rust/src/types.rs @@ -863,7 +863,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1269,8 +1270,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1650,8 +1652,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2020,9 +2023,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; diff --git a/spec/lib/xdrgen/rust_spec.rb b/spec/lib/xdrgen/rust_spec.rb index 1aa158b17..34fa37dc4 100644 --- a/spec/lib/xdrgen/rust_spec.rb +++ b/spec/lib/xdrgen/rust_spec.rb @@ -18,11 +18,28 @@ "MyStruct", "LotsOfMyStructs", ], + rust_types_custom_jsonschema_impl: [], + } + end + + it "can generate #{File.basename path} with custom jsonschema impls" do + c = generate path, "_custom_jsonschema_impls", { + rust_types_custom_str_impl: [], + rust_types_custom_jsonschema_impl: [ + "Foo", + "TestArray", + "Color2", + "UnionKey", + "MyUnion", + "HasOptions", + "MyStruct", + "LotsOfMyStructs", + ], } end end - def generate(path, output_sub_path, options = {rust_types_custom_str_impl: []}) + def generate(path, output_sub_path, options = {rust_types_custom_str_impl: [], rust_types_custom_jsonschema_impl: []}) compilation = Xdrgen::Compilation.new( [path], output_dir: "#{SPEC_ROOT}/output/generator_spec_rust#{output_sub_path}/#{File.basename path}", diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index 2e64bf021..c4a26e2ad 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2698,7 +2702,8 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum AccountFlags { AuthRequiredFlag = 1, @@ -2789,6 +2794,10 @@ impl WriteXdr for AccountFlags { derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] +#[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) +)] pub enum TypeVariant { AccountFlags, } @@ -2843,6 +2852,10 @@ impl core::str::FromStr for TypeVariant { serde(rename_all = "snake_case"), serde(untagged), )] +#[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) +)] pub enum Type { AccountFlags(Box), } diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index 14fafaded..e825a26e0 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2716,6 +2720,10 @@ pub type TestArray2 = VecM::; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { TestArray, TestArray2, @@ -2775,6 +2783,10 @@ Self::TestArray2 => "TestArray2", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { TestArray(Box), TestArray2(Box), diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index ccf469a00..a5a302aaf 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2717,7 +2721,8 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum MessageType { ErrorMsg = 0, @@ -2880,7 +2885,8 @@ Self::FbaMessage => "FbaMessage", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { Red = 0, @@ -2988,7 +2994,8 @@ Self::Blue => "Blue", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color2 { Red2 = 0, @@ -3089,6 +3096,10 @@ Self::Blue2 => "Blue2", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { MessageType, Color, @@ -3153,6 +3164,10 @@ Self::Color2 => "Color2", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { MessageType(Box), Color(Box), diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 03ccf84bc..9f9b11976 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2699,7 +2703,8 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { One = 1, @@ -2812,7 +2817,8 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct MyUnionOne { pub some_int: i32, } @@ -2849,7 +2855,8 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct MyUnionTwo { pub some_int: i32, pub foo: i32, @@ -2902,7 +2909,8 @@ self.foo.write_xdr(w)?; // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { One(MyUnionOne), @@ -3009,6 +3017,10 @@ Self::Offer => ().write_xdr(w)?, derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { UnionKey, Foo, @@ -3083,6 +3095,10 @@ Self::MyUnionTwo => "MyUnionTwo", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { UnionKey(Box), Foo(Box), diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 554eec3c2..576149b20 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2707,7 +2711,8 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct HasOptions { pub first_option: Option, pub second_option: Option, @@ -2745,6 +2750,10 @@ self.third_option.write_xdr(w)?; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { Arr, HasOptions, @@ -2804,6 +2813,10 @@ Self::HasOptions => "HasOptions", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { Arr(Box), HasOptions(Box), diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index 56f9bd2e5..a6e91403c 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2709,7 +2713,8 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct MyStruct { pub some_int: i32, pub a_big_int: i64, @@ -2753,6 +2758,10 @@ self.max_string.write_xdr(w)?; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { Int64, MyStruct, @@ -2812,6 +2821,10 @@ Self::MyStruct => "MyStruct", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { Int64(Box), MyStruct(Box), diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index b542b0d81..fbb23396f 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2694,7 +2698,8 @@ mod test { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2810,7 +2815,8 @@ impl AsRef<[u8]> for Uint512 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint513(pub BytesM::<64>); @@ -2911,7 +2917,8 @@ impl AsRef<[u8]> for Uint513 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint514(pub BytesM); @@ -3012,7 +3019,8 @@ impl AsRef<[u8]> for Uint514 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str(pub StringM::<64>); @@ -3113,7 +3121,8 @@ impl AsRef<[u8]> for Str { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str2(pub StringM); @@ -3213,7 +3222,8 @@ impl AsRef<[u8]> for Str2 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3328,7 +3338,8 @@ impl AsRef<[u8]> for Hash { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes1(pub [Hash; 12]); @@ -3417,7 +3428,8 @@ impl AsRef<[Hash]> for Hashes1 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes2(pub VecM::); @@ -3518,7 +3530,8 @@ impl AsRef<[Hash]> for Hashes2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes3(pub VecM::); @@ -3618,7 +3631,8 @@ impl AsRef<[Hash]> for Hashes3 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash1(pub Option); @@ -3669,7 +3683,8 @@ impl WriteXdr for OptHash1 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash2(pub Option); @@ -3761,7 +3776,8 @@ pub type Int4 = u64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct MyStruct { pub field1: Uint512, pub field2: OptHash1, @@ -3816,7 +3832,8 @@ self.field7.write_xdr(w)?; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct LotsOfMyStructs { pub members: VecM::, } @@ -3853,7 +3870,8 @@ impl WriteXdr for LotsOfMyStructs { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct HasStuff { pub data: LotsOfMyStructs, } @@ -3892,7 +3910,8 @@ impl WriteXdr for HasStuff { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { Red = 0, @@ -4015,7 +4034,8 @@ pub const BAR: u64 = FOO; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum NesterNestedEnum { 1 = 0, @@ -4115,7 +4135,8 @@ Self::2 => "2", /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct NesterNestedStruct { pub blah: i32, } @@ -4155,7 +4176,8 @@ impl WriteXdr for NesterNestedStruct { // union with discriminant Color #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum NesterNestedUnion { Red, @@ -4269,7 +4291,8 @@ impl WriteXdr for NesterNestedUnion { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Nester { pub nested_enum: NesterNestedEnum, pub nested_struct: NesterNestedStruct, @@ -4307,6 +4330,10 @@ self.nested_union.write_xdr(w)?; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { Uint512, Uint513, @@ -4471,6 +4498,10 @@ Self::NesterNestedUnion => "NesterNestedUnion", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { Uint512(Box), Uint513(Box), diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index a7e8d8cfd..9999db598 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2714,7 +2718,8 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { Error = 0, @@ -2821,7 +2826,8 @@ Self::Multi => "Multi", // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { Error(i32), @@ -2931,7 +2937,8 @@ Self::Multi(v) => v.write_xdr(w)?, // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum IntUnion { V0(i32), @@ -3033,7 +3040,8 @@ Self::V1(v) => v.write_xdr(w)?, /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3082,6 +3090,10 @@ impl WriteXdr for IntUnion2 { derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { SError, Multi, @@ -3161,6 +3173,10 @@ Self::IntUnion2 => "IntUnion2", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { SError(Box), Multi(Box), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs new file mode 100644 index 000000000..c4a26e2ad --- /dev/null +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -0,0 +1,3003 @@ +// Module is generated from: +// spec/fixtures/generator/block_comments.x + +#![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] + +/// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/block_comments.x", "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30") +]; + +use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; + +#[cfg(feature = "std")] +use core::marker::PhantomData; + +// When feature alloc is turned off use static lifetime Box and Vec types. +#[cfg(not(feature = "alloc"))] +mod noalloc { + pub mod boxed { + pub type Box = &'static T; + } + pub mod vec { + pub type Vec = &'static [T]; + } +} +#[cfg(not(feature = "alloc"))] +use noalloc::{boxed::Box, vec::Vec}; + +// When feature std is turned off, but feature alloc is turned on import the +// alloc crate and use its Box and Vec types. +#[cfg(all(not(feature = "std"), feature = "alloc"))] +extern crate alloc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::{ + borrow::ToOwned, + boxed::Box, + string::{FromUtf8Error, String}, + vec::Vec, +}; +#[cfg(feature = "std")] +use std::string::FromUtf8Error; + +#[cfg(feature = "arbitrary")] +use arbitrary::Arbitrary; + +// TODO: Add support for read/write xdr fns when std not available. + +#[cfg(feature = "std")] +use std::{ + error, io, + io::{BufRead, BufReader, Cursor, Read, Write}, +}; + +/// Error contains all errors returned by functions in this crate. It can be +/// compared via `PartialEq`, however any contained IO errors will only be +/// compared on their `ErrorKind`. +#[derive(Debug)] +pub enum Error { + Invalid, + Unsupported, + LengthExceedsMax, + LengthMismatch, + NonZeroPadding, + Utf8Error(core::str::Utf8Error), + #[cfg(feature = "alloc")] + InvalidHex, + #[cfg(feature = "std")] + Io(io::Error), + DepthLimitExceeded, + #[cfg(feature = "serde_json")] + Json(serde_json::Error), + LengthLimitExceeded, +} + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Utf8Error(l), Self::Utf8Error(r)) => l == r, + // IO errors cannot be compared, but in the absence of any more + // meaningful way to compare the errors we compare the kind of error + // and ignore the embedded source error or OS error. The main use + // case for comparing errors outputted by the XDR library is for + // error case testing, and a lack of the ability to compare has a + // detrimental affect on failure testing, so this is a tradeoff. + #[cfg(feature = "std")] + (Self::Io(l), Self::Io(r)) => l.kind() == r.kind(), + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + #[must_use] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Io(e) => Some(e), + #[cfg(feature = "serde_json")] + Self::Json(e) => Some(e), + _ => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Invalid => write!(f, "xdr value invalid"), + Error::Unsupported => write!(f, "xdr value unsupported"), + Error::LengthExceedsMax => write!(f, "xdr value max length exceeded"), + Error::LengthMismatch => write!(f, "xdr value length does not match"), + Error::NonZeroPadding => write!(f, "xdr padding contains non-zero bytes"), + Error::Utf8Error(e) => write!(f, "{e}"), + #[cfg(feature = "alloc")] + Error::InvalidHex => write!(f, "hex invalid"), + #[cfg(feature = "std")] + Error::Io(e) => write!(f, "{e}"), + Error::DepthLimitExceeded => write!(f, "depth limit exceeded"), + #[cfg(feature = "serde_json")] + Error::Json(e) => write!(f, "{e}"), + Error::LengthLimitExceeded => write!(f, "length limit exceeded"), + } + } +} + +impl From for Error { + fn from(_: TryFromSliceError) -> Error { + Error::LengthMismatch + } +} + +impl From for Error { + #[must_use] + fn from(e: core::str::Utf8Error) -> Self { + Error::Utf8Error(e) + } +} + +#[cfg(feature = "alloc")] +impl From for Error { + #[must_use] + fn from(e: FromUtf8Error) -> Self { + Error::Utf8Error(e.utf8_error()) + } +} + +#[cfg(feature = "std")] +impl From for Error { + #[must_use] + fn from(e: io::Error) -> Self { + Error::Io(e) + } +} + +#[cfg(feature = "serde_json")] +impl From for Error { + #[must_use] + fn from(e: serde_json::Error) -> Self { + Error::Json(e) + } +} + +impl From for () { + fn from(_: Error) {} +} + +#[allow(dead_code)] +type Result = core::result::Result; + +/// Name defines types that assign a static name to their value, such as the +/// name given to an identifier in an XDR enum, or the name given to the case in +/// a union. +pub trait Name { + fn name(&self) -> &'static str; +} + +/// Discriminant defines types that may contain a one-of value determined +/// according to the discriminant, and exposes the value of the discriminant for +/// that type, such as in an XDR union. +pub trait Discriminant { + fn discriminant(&self) -> D; +} + +/// Iter defines types that have variants that can be iterated. +pub trait Variants { + fn variants() -> slice::Iter<'static, V> + where + V: Sized; +} + +// Enum defines a type that is represented as an XDR enumeration when encoded. +pub trait Enum: Name + Variants + Sized {} + +// Union defines a type that is represented as an XDR union when encoded. +pub trait Union: Name + Discriminant + Variants +where + D: Sized, +{ +} + +/// `Limits` contains the limits that a limited reader or writer will be +/// constrained to. +#[cfg(feature = "std")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Limits { + /// Defines the maximum depth for recursive calls in `Read/WriteXdr` to + /// prevent stack overflow. + /// + /// The depth limit is akin to limiting stack depth. Its purpose is to + /// prevent the program from hitting the maximum stack size allowed by Rust, + /// which would result in an unrecoverable `SIGABRT`. For more information + /// about Rust's stack size limit, refer to the [Rust + /// documentation](https://doc.rust-lang.org/std/thread/#stack-size). + pub depth: u32, + + /// Defines the maximum number of bytes that will be read or written. + pub len: usize, +} + +#[cfg(feature = "std")] +impl Limits { + #[must_use] + pub fn none() -> Self { + Self { + depth: u32::MAX, + len: usize::MAX, + } + } + + #[must_use] + pub fn depth(depth: u32) -> Self { + Limits { + depth, + ..Limits::none() + } + } + + #[must_use] + pub fn len(len: usize) -> Self { + Limits { + len, + ..Limits::none() + } + } +} + +/// `Limited` wraps an object and provides functions for enforcing limits. +/// +/// Intended for use with readers and writers and limiting their reads and +/// writes. +#[cfg(feature = "std")] +pub struct Limited { + pub inner: L, + pub(crate) limits: Limits, +} + +#[cfg(feature = "std")] +impl Limited { + /// Constructs a new `Limited`. + /// + /// - `inner`: The value being limited. + /// - `limits`: The limits to enforce. + pub fn new(inner: L, limits: Limits) -> Self { + Limited { inner, limits } + } + + /// Consume the given length from the internal remaining length limit. + /// + /// ### Errors + /// + /// If the length would consume more length than the remaining length limit + /// allows. + pub(crate) fn consume_len(&mut self, len: usize) -> Result<()> { + if let Some(len) = self.limits.len.checked_sub(len) { + self.limits.len = len; + Ok(()) + } else { + Err(Error::LengthLimitExceeded) + } + } + + /// Consumes a single depth for the duration of the given function. + /// + /// ### Errors + /// + /// If the depth limit is already exhausted. + pub(crate) fn with_limited_depth(&mut self, f: F) -> Result + where + F: FnOnce(&mut Self) -> Result, + { + if let Some(depth) = self.limits.depth.checked_sub(1) { + self.limits.depth = depth; + let res = f(self); + self.limits.depth = self.limits.depth.saturating_add(1); + res + } else { + Err(Error::DepthLimitExceeded) + } + } +} + +#[cfg(feature = "std")] +impl Read for Limited { + /// Forwards the read operation to the wrapped object. + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.inner.read(buf) + } +} + +#[cfg(feature = "std")] +impl BufRead for Limited { + /// Forwards the read operation to the wrapped object. + fn fill_buf(&mut self) -> std::io::Result<&[u8]> { + self.inner.fill_buf() + } + + /// Forwards the read operation to the wrapped object. + fn consume(&mut self, amt: usize) { + self.inner.consume(amt); + } +} + +#[cfg(feature = "std")] +impl Write for Limited { + /// Forwards the write operation to the wrapped object. + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.inner.write(buf) + } + + /// Forwards the flush operation to the wrapped object. + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } +} + +#[cfg(feature = "std")] +pub struct ReadXdrIter { + reader: Limited>, + _s: PhantomData, +} + +#[cfg(feature = "std")] +impl ReadXdrIter { + fn new(r: R, limits: Limits) -> Self { + Self { + reader: Limited { + inner: BufReader::new(r), + limits, + }, + _s: PhantomData, + } + } +} + +#[cfg(feature = "std")] +impl Iterator for ReadXdrIter { + type Item = Result; + + // Next reads the internal reader and XDR decodes it into the Self type. If + // the EOF is reached without reading any new bytes `None` is returned. If + // EOF is reached after reading some bytes a truncated entry is assumed an + // an `Error::Io` containing an `UnexpectedEof`. If any other IO error + // occurs it is returned. Iteration of this iterator stops naturally when + // `None` is returned, but not when a `Some(Err(...))` is returned. The + // caller is responsible for checking each Result. + fn next(&mut self) -> Option { + // Try to fill the buffer to see if the EOF has been reached or not. + // This happens to effectively peek to see if the stream has finished + // and there are no more items. It is necessary to do this because the + // xdr types in this crate heavily use the `std::io::Read::read_exact` + // method that doesn't distinguish between an EOF at the beginning of a + // read and an EOF after a partial fill of a read_exact. + match self.reader.fill_buf() { + // If the reader has no more data and is unable to fill any new data + // into its internal buf, then the EOF has been reached. + Ok([]) => return None, + // If an error occurs filling the buffer, treat that as an error and stop. + Err(e) => return Some(Err(Error::Io(e))), + // If there is data in the buf available for reading, continue. + Ok([..]) => (), + }; + // Read the buf into the type. + let r = self.reader.with_limited_depth(|dlr| S::read_xdr(dlr)); + match r { + Ok(s) => Some(Ok(s)), + Err(e) => Some(Err(e)), + } + } +} + +pub trait ReadXdr +where + Self: Sized, +{ + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_to_end`] when the intent is for all bytes in the + /// read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result; + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_to_end(r: &mut Limited) -> Result { + let s = Self::read_xdr(r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64_to_end(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_into_to_end`] when the intent is for all bytes + /// in the read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr_into(&mut self, r: &mut Limited) -> Result<()> { + *self = Self::read_xdr(r)?; + Ok(()) + } + + /// Read the XDR into the existing value, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_into_to_end(&mut self, r: &mut Limited) -> Result<()> { + Self::read_xdr_into(self, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(()) + } else { + Err(Error::Invalid) + } + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_iter(r: &mut Limited) -> ReadXdrIter<&mut R, Self> { + ReadXdrIter::new(&mut r.inner, r.limits.clone()) + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + #[cfg(feature = "base64")] + fn read_xdr_base64_iter( + r: &mut Limited, + ) -> ReadXdrIter, Self> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + ReadXdrIter::new(dec, r.limits.clone()) + } + + /// Construct the type from the XDR bytes. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "std")] + fn from_xdr(bytes: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(&mut cursor)?; + Ok(t) + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn from_xdr_base64(b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } +} + +pub trait WriteXdr { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()>; + + #[cfg(feature = "std")] + fn to_xdr(&self, limits: Limits) -> Result> { + let mut cursor = Limited::new(Cursor::new(vec![]), limits); + self.write_xdr(&mut cursor)?; + let bytes = cursor.inner.into_inner(); + Ok(bytes) + } + + #[cfg(feature = "base64")] + fn to_xdr_base64(&self, limits: Limits) -> Result { + let mut enc = Limited::new( + base64::write::EncoderStringWriter::new(base64::STANDARD), + limits, + ); + self.write_xdr(&mut enc)?; + let b64 = enc.inner.into_inner(); + Ok(b64) + } +} + +/// `Pad_len` returns the number of bytes to pad an XDR value of the given +/// length to make the final serialized size a multiple of 4. +#[cfg(feature = "std")] +fn pad_len(len: usize) -> usize { + (4 - (len % 4)) % 4 +} + +impl ReadXdr for i32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for i64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for f32 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f32 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for f64 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f64 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for bool { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + let b = i == 1; + Ok(b) + }) + } +} + +impl WriteXdr for bool { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i = u32::from(*self); // true = 1, false = 0 + i.write_xdr(w) + }) + } +} + +impl ReadXdr for Option { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + match i { + 0 => Ok(None), + 1 => { + let t = T::read_xdr(r)?; + Ok(Some(t)) + } + _ => Err(Error::Invalid), + } + }) + } +} + +impl WriteXdr for Option { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + if let Some(t) = self { + 1u32.write_xdr(w)?; + t.write_xdr(w)?; + } else { + 0u32.write_xdr(w)?; + } + Ok(()) + }) + } +} + +impl ReadXdr for Box { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| Ok(Box::new(T::read_xdr(r)?))) + } +} + +impl WriteXdr for Box { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| T::write_xdr(self, w)) + } +} + +impl ReadXdr for () { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + Ok(()) + } +} + +impl WriteXdr for () { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + Ok(()) + } +} + +impl ReadXdr for [u8; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + r.consume_len(N)?; + let padding = pad_len(N); + r.consume_len(padding)?; + let mut arr = [0u8; N]; + r.read_exact(&mut arr)?; + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + Ok(arr) + }) + } +} + +impl WriteXdr for [u8; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + w.consume_len(N)?; + let padding = pad_len(N); + w.consume_len(padding)?; + w.write_all(self)?; + w.write_all(&[0u8; 3][..padding])?; + Ok(()) + }) + } +} + +impl ReadXdr for [T; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let mut vec = Vec::with_capacity(N); + for _ in 0..N { + let t = T::read_xdr(r)?; + vec.push(t); + } + let arr: [T; N] = vec.try_into().unwrap_or_else(|_: Vec| unreachable!()); + Ok(arr) + }) + } +} + +impl WriteXdr for [T; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + for t in self { + t.write_xdr(w)?; + } + Ok(()) + }) + } +} + +// VecM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec) +where + T: 'static; + +impl Deref for VecM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for VecM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl VecM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl VecM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl VecM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl VecM { + #[must_use] + pub fn to_option(&self) -> Option { + if self.len() > 0 { + Some(self.0[0].clone()) + } else { + None + } + } +} + +#[cfg(not(feature = "alloc"))] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.to_option() + } +} + +#[cfg(feature = "alloc")] +impl VecM { + #[must_use] + pub fn into_option(mut self) -> Option { + self.0.drain(..).next() + } +} + +#[cfg(feature = "alloc")] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.into_option() + } +} + +impl TryFrom> for VecM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: VecM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&VecM> for Vec { + #[must_use] + fn from(v: &VecM) -> Self { + v.0.clone() + } +} + +impl AsRef> for VecM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for VecM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T]> for VecM { + type Error = Error; + + fn try_from(v: &[T]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[T]> for VecM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[T; N]> for VecM { + type Error = Error; + + fn try_from(v: [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [T; N] { + type Error = VecM; + + fn try_from(v: VecM) -> core::result::Result { + let s: [T; N] = v.0.try_into().map_err(|v: Vec| VecM::(v))?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T; N]> for VecM { + type Error = Error; + + fn try_from(v: &[T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [T; N]> for VecM { + type Error = Error; + + fn try_from(v: &'static [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for VecM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for VecM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: VecM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&VecM> for String { + type Error = Error; + + fn try_from(v: &VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for VecM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for VecM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a VecM> for &'a str { + type Error = Error; + + fn try_from(v: &'a VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + let mut vec = Vec::new(); + for _ in 0..len { + let t = T::read_xdr(r)?; + vec.push(t); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + for t in &self.0 { + t.write_xdr(w)?; + } + + Ok(()) + }) + } +} + +// BytesM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +impl core::fmt::Display for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +impl core::fmt::Debug for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "BytesM(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for BytesM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} + +impl Deref for BytesM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for BytesM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl BytesM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl BytesM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl BytesM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for BytesM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: BytesM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&BytesM> for Vec { + #[must_use] + fn from(v: &BytesM) -> Self { + v.0.clone() + } +} + +impl AsRef> for BytesM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for BytesM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for BytesM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = BytesM; + + fn try_from(v: BytesM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(BytesM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for BytesM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for BytesM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: BytesM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&BytesM> for String { + type Error = Error; + + fn try_from(v: &BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for BytesM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for BytesM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a BytesM> for &'a str { + type Error = Error; + + fn try_from(v: &'a BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for BytesM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(BytesM(vec)) + }) + } +} + +impl WriteXdr for BytesM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..pad_len(len as usize)])?; + + Ok(()) + }) + } +} + +// StringM ------------------------------------------------------------------------ + +/// A string type that contains arbitrary bytes. +/// +/// Convertible, fallibly, to/from a Rust UTF-8 String using +/// [`TryFrom`]/[`TryInto`]/[`StringM::to_utf8_string`]. +/// +/// Convertible, lossyly, to a Rust UTF-8 String using +/// [`StringM::to_utf8_string_lossy`]. +/// +/// Convertible to/from escaped printable-ASCII using +/// [`Display`]/[`ToString`]/[`FromStr`]. + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +impl core::fmt::Display for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + Ok(()) + } +} + +impl core::fmt::Debug for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "StringM(")?; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for StringM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?; + Ok(Self(b)) + } +} + +impl Deref for StringM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for StringM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl StringM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl StringM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl StringM { + #[cfg(feature = "alloc")] + pub fn to_utf8_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_utf8_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_utf8_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_utf8_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for StringM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: StringM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&StringM> for Vec { + #[must_use] + fn from(v: &StringM) -> Self { + v.0.clone() + } +} + +impl AsRef> for StringM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for StringM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for StringM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for StringM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = StringM; + + fn try_from(v: StringM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(StringM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for StringM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for StringM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: StringM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&StringM> for String { + type Error = Error; + + fn try_from(v: &StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for StringM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for StringM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a StringM> for &'a str { + type Error = Error; + + fn try_from(v: &'a StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for StringM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(StringM(vec)) + }) + } +} + +impl WriteXdr for StringM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +// Frame ------------------------------------------------------------------------ + +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Frame(pub T) +where + T: ReadXdr; + +impl ReadXdr for Frame +where + T: ReadXdr, +{ + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + // Read the frame header value that contains 1 flag-bit and a 33-bit length. + // - The 1 flag bit is 0 when there are more frames for the same record. + // - The 31-bit length is the length of the bytes within the frame that + // follow the frame header. + let header = u32::read_xdr(r)?; + // TODO: Use the length and cap the length we'll read from `r`. + let last_record = header >> 31 == 1; + if last_record { + // Read the record in the frame. + Ok(Self(T::read_xdr(r)?)) + } else { + // TODO: Support reading those additional frames for the same + // record. + Err(Error::Unsupported) + } + } +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + pub fn vec_u8_read_without_padding() { + let buf = Cursor::new(vec![0, 0, 0, 4, 2, 2, 2, 2]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_read_with_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0, 0]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2]); + } + + #[test] + pub fn vec_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn vec_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 3, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn vec_u8_write_without_padding() { + let mut buf = vec![]; + let v: VecM = vec![2, 2, 2, 2].try_into().unwrap(); + + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 4, 2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_write_with_padding() { + let mut buf = vec![]; + let v: VecM = vec![2].try_into().unwrap(); + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 1, 2, 0, 0, 0]); + } + + #[test] + pub fn arr_u8_read_without_padding() { + let buf = Cursor::new(vec![2, 2, 2, 2]); + let v = <[u8; 4]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_read_with_padding() { + let buf = Cursor::new(vec![2, 0, 0, 0]); + let v = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2]); + } + + #[test] + pub fn arr_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![2, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn arr_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![2, 3, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn arr_u8_write_without_padding() { + let mut buf = vec![]; + [2u8, 2, 2, 2] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_write_with_padding() { + let mut buf = vec![]; + [2u8] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 0, 0, 0]); + } +} + +#[cfg(all(test, feature = "std"))] +mod test { + use super::*; + + #[test] + fn into_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.into_option(), None); + } + + #[test] + fn into_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.into_option(), Some(1)); + } + + #[test] + fn to_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } + + #[test] + fn depth_limited_read_write_under_the_limit_success() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(4)); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::depth(4)); + let a_back: Option>> = ReadXdr::read_xdr(&mut dlr).unwrap(); + assert_eq!(a, a_back); + } + + #[test] + fn write_over_depth_limit_fail() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(3)); + let res = a.write_xdr(&mut buf); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn read_over_depth_limit_fail() { + let read_limits = Limits::depth(3); + let write_limits = Limits::depth(5); + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), write_limits); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), read_limits); + let res: Result>>> = ReadXdr::read_xdr(&mut dlr); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn length_limited_read_write_i32() { + // Exact limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u32() { + // Exact limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_i64() { + // Exact limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u64() { + // Exact limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bool() { + // Exact limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_option() { + // Exact limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_u8() { + // Exact limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + <[u8; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_type() { + // Exact limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(12)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(13)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(13)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(11)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(11)); + assert_eq!( + <[bool; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_vec() { + // Exact limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(16)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(17)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(17)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(15)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(15)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bytes() { + // Exact limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_string() { + // Exact limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } +} + +#[cfg(all(test, not(feature = "alloc")))] +mod test { + use super::VecM; + + #[test] + fn to_option_none() { + let v: VecM = (&[]).try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = (&[1]).try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } +} + +/// AccountFlags is an XDR Enum defines as: +/// +/// ```text +/// enum AccountFlags +/// { // masks for each flag +/// AUTH_REQUIRED_FLAG = 0x1 +/// }; +/// ``` +/// +// enum +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[repr(i32)] +pub enum AccountFlags { + AuthRequiredFlag = 1, +} + +impl AccountFlags { + pub const VARIANTS: [AccountFlags; 1] = [ AccountFlags::AuthRequiredFlag, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AuthRequiredFlag", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::AuthRequiredFlag => "AuthRequiredFlag", + } + } + + #[must_use] + pub const fn variants() -> [AccountFlags; 1] { + Self::VARIANTS + } +} + +impl Name for AccountFlags { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for AccountFlags { + fn variants() -> slice::Iter<'static, AccountFlags> { + Self::VARIANTS.iter() + } +} + +impl Enum for AccountFlags {} + +impl fmt::Display for AccountFlags { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} + +impl TryFrom for AccountFlags { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 1 => AccountFlags::AuthRequiredFlag, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} + +impl From for i32 { + #[must_use] + fn from(e: AccountFlags) -> Self { + e as Self + } +} + +impl ReadXdr for AccountFlags { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for AccountFlags { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} + +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + AccountFlags, +} + +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::AccountFlags => "AccountFlags", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 1] { + Self::VARIANTS + } +} + +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "AccountFlags" => Ok(Self::AccountFlags), + _ => Err(Error::Invalid), + } + } +} + +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged), +)] +#[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) +)] +pub enum Type { + AccountFlags(Box), +} + +impl Type { + pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::AccountFlags => r.with_limited_depth(|r| Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?)))), + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0))))), + } + } + + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } + + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::AccountFlags => Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))), + } + } + + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::AccountFlags(ref v) => v.as_ref(), + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::AccountFlags(_) => "AccountFlags", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 1] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::AccountFlags(_) => TypeVariant::AccountFlags, + } + } +} + +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::AccountFlags(v) => v.write_xdr(w), + } + } +} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs new file mode 100644 index 000000000..e825a26e0 --- /dev/null +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -0,0 +1,2946 @@ +// Module is generated from: +// spec/fixtures/generator/const.x + +#![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] + +/// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/const.x", "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37") +]; + +use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; + +#[cfg(feature = "std")] +use core::marker::PhantomData; + +// When feature alloc is turned off use static lifetime Box and Vec types. +#[cfg(not(feature = "alloc"))] +mod noalloc { + pub mod boxed { + pub type Box = &'static T; + } + pub mod vec { + pub type Vec = &'static [T]; + } +} +#[cfg(not(feature = "alloc"))] +use noalloc::{boxed::Box, vec::Vec}; + +// When feature std is turned off, but feature alloc is turned on import the +// alloc crate and use its Box and Vec types. +#[cfg(all(not(feature = "std"), feature = "alloc"))] +extern crate alloc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::{ + borrow::ToOwned, + boxed::Box, + string::{FromUtf8Error, String}, + vec::Vec, +}; +#[cfg(feature = "std")] +use std::string::FromUtf8Error; + +#[cfg(feature = "arbitrary")] +use arbitrary::Arbitrary; + +// TODO: Add support for read/write xdr fns when std not available. + +#[cfg(feature = "std")] +use std::{ + error, io, + io::{BufRead, BufReader, Cursor, Read, Write}, +}; + +/// Error contains all errors returned by functions in this crate. It can be +/// compared via `PartialEq`, however any contained IO errors will only be +/// compared on their `ErrorKind`. +#[derive(Debug)] +pub enum Error { + Invalid, + Unsupported, + LengthExceedsMax, + LengthMismatch, + NonZeroPadding, + Utf8Error(core::str::Utf8Error), + #[cfg(feature = "alloc")] + InvalidHex, + #[cfg(feature = "std")] + Io(io::Error), + DepthLimitExceeded, + #[cfg(feature = "serde_json")] + Json(serde_json::Error), + LengthLimitExceeded, +} + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Utf8Error(l), Self::Utf8Error(r)) => l == r, + // IO errors cannot be compared, but in the absence of any more + // meaningful way to compare the errors we compare the kind of error + // and ignore the embedded source error or OS error. The main use + // case for comparing errors outputted by the XDR library is for + // error case testing, and a lack of the ability to compare has a + // detrimental affect on failure testing, so this is a tradeoff. + #[cfg(feature = "std")] + (Self::Io(l), Self::Io(r)) => l.kind() == r.kind(), + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + #[must_use] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Io(e) => Some(e), + #[cfg(feature = "serde_json")] + Self::Json(e) => Some(e), + _ => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Invalid => write!(f, "xdr value invalid"), + Error::Unsupported => write!(f, "xdr value unsupported"), + Error::LengthExceedsMax => write!(f, "xdr value max length exceeded"), + Error::LengthMismatch => write!(f, "xdr value length does not match"), + Error::NonZeroPadding => write!(f, "xdr padding contains non-zero bytes"), + Error::Utf8Error(e) => write!(f, "{e}"), + #[cfg(feature = "alloc")] + Error::InvalidHex => write!(f, "hex invalid"), + #[cfg(feature = "std")] + Error::Io(e) => write!(f, "{e}"), + Error::DepthLimitExceeded => write!(f, "depth limit exceeded"), + #[cfg(feature = "serde_json")] + Error::Json(e) => write!(f, "{e}"), + Error::LengthLimitExceeded => write!(f, "length limit exceeded"), + } + } +} + +impl From for Error { + fn from(_: TryFromSliceError) -> Error { + Error::LengthMismatch + } +} + +impl From for Error { + #[must_use] + fn from(e: core::str::Utf8Error) -> Self { + Error::Utf8Error(e) + } +} + +#[cfg(feature = "alloc")] +impl From for Error { + #[must_use] + fn from(e: FromUtf8Error) -> Self { + Error::Utf8Error(e.utf8_error()) + } +} + +#[cfg(feature = "std")] +impl From for Error { + #[must_use] + fn from(e: io::Error) -> Self { + Error::Io(e) + } +} + +#[cfg(feature = "serde_json")] +impl From for Error { + #[must_use] + fn from(e: serde_json::Error) -> Self { + Error::Json(e) + } +} + +impl From for () { + fn from(_: Error) {} +} + +#[allow(dead_code)] +type Result = core::result::Result; + +/// Name defines types that assign a static name to their value, such as the +/// name given to an identifier in an XDR enum, or the name given to the case in +/// a union. +pub trait Name { + fn name(&self) -> &'static str; +} + +/// Discriminant defines types that may contain a one-of value determined +/// according to the discriminant, and exposes the value of the discriminant for +/// that type, such as in an XDR union. +pub trait Discriminant { + fn discriminant(&self) -> D; +} + +/// Iter defines types that have variants that can be iterated. +pub trait Variants { + fn variants() -> slice::Iter<'static, V> + where + V: Sized; +} + +// Enum defines a type that is represented as an XDR enumeration when encoded. +pub trait Enum: Name + Variants + Sized {} + +// Union defines a type that is represented as an XDR union when encoded. +pub trait Union: Name + Discriminant + Variants +where + D: Sized, +{ +} + +/// `Limits` contains the limits that a limited reader or writer will be +/// constrained to. +#[cfg(feature = "std")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Limits { + /// Defines the maximum depth for recursive calls in `Read/WriteXdr` to + /// prevent stack overflow. + /// + /// The depth limit is akin to limiting stack depth. Its purpose is to + /// prevent the program from hitting the maximum stack size allowed by Rust, + /// which would result in an unrecoverable `SIGABRT`. For more information + /// about Rust's stack size limit, refer to the [Rust + /// documentation](https://doc.rust-lang.org/std/thread/#stack-size). + pub depth: u32, + + /// Defines the maximum number of bytes that will be read or written. + pub len: usize, +} + +#[cfg(feature = "std")] +impl Limits { + #[must_use] + pub fn none() -> Self { + Self { + depth: u32::MAX, + len: usize::MAX, + } + } + + #[must_use] + pub fn depth(depth: u32) -> Self { + Limits { + depth, + ..Limits::none() + } + } + + #[must_use] + pub fn len(len: usize) -> Self { + Limits { + len, + ..Limits::none() + } + } +} + +/// `Limited` wraps an object and provides functions for enforcing limits. +/// +/// Intended for use with readers and writers and limiting their reads and +/// writes. +#[cfg(feature = "std")] +pub struct Limited { + pub inner: L, + pub(crate) limits: Limits, +} + +#[cfg(feature = "std")] +impl Limited { + /// Constructs a new `Limited`. + /// + /// - `inner`: The value being limited. + /// - `limits`: The limits to enforce. + pub fn new(inner: L, limits: Limits) -> Self { + Limited { inner, limits } + } + + /// Consume the given length from the internal remaining length limit. + /// + /// ### Errors + /// + /// If the length would consume more length than the remaining length limit + /// allows. + pub(crate) fn consume_len(&mut self, len: usize) -> Result<()> { + if let Some(len) = self.limits.len.checked_sub(len) { + self.limits.len = len; + Ok(()) + } else { + Err(Error::LengthLimitExceeded) + } + } + + /// Consumes a single depth for the duration of the given function. + /// + /// ### Errors + /// + /// If the depth limit is already exhausted. + pub(crate) fn with_limited_depth(&mut self, f: F) -> Result + where + F: FnOnce(&mut Self) -> Result, + { + if let Some(depth) = self.limits.depth.checked_sub(1) { + self.limits.depth = depth; + let res = f(self); + self.limits.depth = self.limits.depth.saturating_add(1); + res + } else { + Err(Error::DepthLimitExceeded) + } + } +} + +#[cfg(feature = "std")] +impl Read for Limited { + /// Forwards the read operation to the wrapped object. + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.inner.read(buf) + } +} + +#[cfg(feature = "std")] +impl BufRead for Limited { + /// Forwards the read operation to the wrapped object. + fn fill_buf(&mut self) -> std::io::Result<&[u8]> { + self.inner.fill_buf() + } + + /// Forwards the read operation to the wrapped object. + fn consume(&mut self, amt: usize) { + self.inner.consume(amt); + } +} + +#[cfg(feature = "std")] +impl Write for Limited { + /// Forwards the write operation to the wrapped object. + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.inner.write(buf) + } + + /// Forwards the flush operation to the wrapped object. + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } +} + +#[cfg(feature = "std")] +pub struct ReadXdrIter { + reader: Limited>, + _s: PhantomData, +} + +#[cfg(feature = "std")] +impl ReadXdrIter { + fn new(r: R, limits: Limits) -> Self { + Self { + reader: Limited { + inner: BufReader::new(r), + limits, + }, + _s: PhantomData, + } + } +} + +#[cfg(feature = "std")] +impl Iterator for ReadXdrIter { + type Item = Result; + + // Next reads the internal reader and XDR decodes it into the Self type. If + // the EOF is reached without reading any new bytes `None` is returned. If + // EOF is reached after reading some bytes a truncated entry is assumed an + // an `Error::Io` containing an `UnexpectedEof`. If any other IO error + // occurs it is returned. Iteration of this iterator stops naturally when + // `None` is returned, but not when a `Some(Err(...))` is returned. The + // caller is responsible for checking each Result. + fn next(&mut self) -> Option { + // Try to fill the buffer to see if the EOF has been reached or not. + // This happens to effectively peek to see if the stream has finished + // and there are no more items. It is necessary to do this because the + // xdr types in this crate heavily use the `std::io::Read::read_exact` + // method that doesn't distinguish between an EOF at the beginning of a + // read and an EOF after a partial fill of a read_exact. + match self.reader.fill_buf() { + // If the reader has no more data and is unable to fill any new data + // into its internal buf, then the EOF has been reached. + Ok([]) => return None, + // If an error occurs filling the buffer, treat that as an error and stop. + Err(e) => return Some(Err(Error::Io(e))), + // If there is data in the buf available for reading, continue. + Ok([..]) => (), + }; + // Read the buf into the type. + let r = self.reader.with_limited_depth(|dlr| S::read_xdr(dlr)); + match r { + Ok(s) => Some(Ok(s)), + Err(e) => Some(Err(e)), + } + } +} + +pub trait ReadXdr +where + Self: Sized, +{ + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_to_end`] when the intent is for all bytes in the + /// read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result; + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_to_end(r: &mut Limited) -> Result { + let s = Self::read_xdr(r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64_to_end(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_into_to_end`] when the intent is for all bytes + /// in the read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr_into(&mut self, r: &mut Limited) -> Result<()> { + *self = Self::read_xdr(r)?; + Ok(()) + } + + /// Read the XDR into the existing value, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_into_to_end(&mut self, r: &mut Limited) -> Result<()> { + Self::read_xdr_into(self, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(()) + } else { + Err(Error::Invalid) + } + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_iter(r: &mut Limited) -> ReadXdrIter<&mut R, Self> { + ReadXdrIter::new(&mut r.inner, r.limits.clone()) + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + #[cfg(feature = "base64")] + fn read_xdr_base64_iter( + r: &mut Limited, + ) -> ReadXdrIter, Self> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + ReadXdrIter::new(dec, r.limits.clone()) + } + + /// Construct the type from the XDR bytes. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "std")] + fn from_xdr(bytes: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(&mut cursor)?; + Ok(t) + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn from_xdr_base64(b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } +} + +pub trait WriteXdr { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()>; + + #[cfg(feature = "std")] + fn to_xdr(&self, limits: Limits) -> Result> { + let mut cursor = Limited::new(Cursor::new(vec![]), limits); + self.write_xdr(&mut cursor)?; + let bytes = cursor.inner.into_inner(); + Ok(bytes) + } + + #[cfg(feature = "base64")] + fn to_xdr_base64(&self, limits: Limits) -> Result { + let mut enc = Limited::new( + base64::write::EncoderStringWriter::new(base64::STANDARD), + limits, + ); + self.write_xdr(&mut enc)?; + let b64 = enc.inner.into_inner(); + Ok(b64) + } +} + +/// `Pad_len` returns the number of bytes to pad an XDR value of the given +/// length to make the final serialized size a multiple of 4. +#[cfg(feature = "std")] +fn pad_len(len: usize) -> usize { + (4 - (len % 4)) % 4 +} + +impl ReadXdr for i32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for i64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for f32 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f32 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for f64 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f64 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for bool { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + let b = i == 1; + Ok(b) + }) + } +} + +impl WriteXdr for bool { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i = u32::from(*self); // true = 1, false = 0 + i.write_xdr(w) + }) + } +} + +impl ReadXdr for Option { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + match i { + 0 => Ok(None), + 1 => { + let t = T::read_xdr(r)?; + Ok(Some(t)) + } + _ => Err(Error::Invalid), + } + }) + } +} + +impl WriteXdr for Option { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + if let Some(t) = self { + 1u32.write_xdr(w)?; + t.write_xdr(w)?; + } else { + 0u32.write_xdr(w)?; + } + Ok(()) + }) + } +} + +impl ReadXdr for Box { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| Ok(Box::new(T::read_xdr(r)?))) + } +} + +impl WriteXdr for Box { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| T::write_xdr(self, w)) + } +} + +impl ReadXdr for () { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + Ok(()) + } +} + +impl WriteXdr for () { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + Ok(()) + } +} + +impl ReadXdr for [u8; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + r.consume_len(N)?; + let padding = pad_len(N); + r.consume_len(padding)?; + let mut arr = [0u8; N]; + r.read_exact(&mut arr)?; + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + Ok(arr) + }) + } +} + +impl WriteXdr for [u8; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + w.consume_len(N)?; + let padding = pad_len(N); + w.consume_len(padding)?; + w.write_all(self)?; + w.write_all(&[0u8; 3][..padding])?; + Ok(()) + }) + } +} + +impl ReadXdr for [T; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let mut vec = Vec::with_capacity(N); + for _ in 0..N { + let t = T::read_xdr(r)?; + vec.push(t); + } + let arr: [T; N] = vec.try_into().unwrap_or_else(|_: Vec| unreachable!()); + Ok(arr) + }) + } +} + +impl WriteXdr for [T; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + for t in self { + t.write_xdr(w)?; + } + Ok(()) + }) + } +} + +// VecM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec) +where + T: 'static; + +impl Deref for VecM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for VecM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl VecM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl VecM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl VecM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl VecM { + #[must_use] + pub fn to_option(&self) -> Option { + if self.len() > 0 { + Some(self.0[0].clone()) + } else { + None + } + } +} + +#[cfg(not(feature = "alloc"))] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.to_option() + } +} + +#[cfg(feature = "alloc")] +impl VecM { + #[must_use] + pub fn into_option(mut self) -> Option { + self.0.drain(..).next() + } +} + +#[cfg(feature = "alloc")] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.into_option() + } +} + +impl TryFrom> for VecM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: VecM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&VecM> for Vec { + #[must_use] + fn from(v: &VecM) -> Self { + v.0.clone() + } +} + +impl AsRef> for VecM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for VecM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T]> for VecM { + type Error = Error; + + fn try_from(v: &[T]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[T]> for VecM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[T; N]> for VecM { + type Error = Error; + + fn try_from(v: [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [T; N] { + type Error = VecM; + + fn try_from(v: VecM) -> core::result::Result { + let s: [T; N] = v.0.try_into().map_err(|v: Vec| VecM::(v))?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T; N]> for VecM { + type Error = Error; + + fn try_from(v: &[T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [T; N]> for VecM { + type Error = Error; + + fn try_from(v: &'static [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for VecM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for VecM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: VecM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&VecM> for String { + type Error = Error; + + fn try_from(v: &VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for VecM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for VecM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a VecM> for &'a str { + type Error = Error; + + fn try_from(v: &'a VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + let mut vec = Vec::new(); + for _ in 0..len { + let t = T::read_xdr(r)?; + vec.push(t); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + for t in &self.0 { + t.write_xdr(w)?; + } + + Ok(()) + }) + } +} + +// BytesM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +impl core::fmt::Display for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +impl core::fmt::Debug for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "BytesM(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for BytesM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} + +impl Deref for BytesM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for BytesM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl BytesM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl BytesM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl BytesM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for BytesM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: BytesM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&BytesM> for Vec { + #[must_use] + fn from(v: &BytesM) -> Self { + v.0.clone() + } +} + +impl AsRef> for BytesM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for BytesM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for BytesM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = BytesM; + + fn try_from(v: BytesM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(BytesM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for BytesM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for BytesM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: BytesM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&BytesM> for String { + type Error = Error; + + fn try_from(v: &BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for BytesM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for BytesM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a BytesM> for &'a str { + type Error = Error; + + fn try_from(v: &'a BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for BytesM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(BytesM(vec)) + }) + } +} + +impl WriteXdr for BytesM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..pad_len(len as usize)])?; + + Ok(()) + }) + } +} + +// StringM ------------------------------------------------------------------------ + +/// A string type that contains arbitrary bytes. +/// +/// Convertible, fallibly, to/from a Rust UTF-8 String using +/// [`TryFrom`]/[`TryInto`]/[`StringM::to_utf8_string`]. +/// +/// Convertible, lossyly, to a Rust UTF-8 String using +/// [`StringM::to_utf8_string_lossy`]. +/// +/// Convertible to/from escaped printable-ASCII using +/// [`Display`]/[`ToString`]/[`FromStr`]. + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +impl core::fmt::Display for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + Ok(()) + } +} + +impl core::fmt::Debug for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "StringM(")?; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for StringM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?; + Ok(Self(b)) + } +} + +impl Deref for StringM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for StringM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl StringM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl StringM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl StringM { + #[cfg(feature = "alloc")] + pub fn to_utf8_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_utf8_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_utf8_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_utf8_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for StringM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: StringM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&StringM> for Vec { + #[must_use] + fn from(v: &StringM) -> Self { + v.0.clone() + } +} + +impl AsRef> for StringM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for StringM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for StringM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for StringM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = StringM; + + fn try_from(v: StringM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(StringM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for StringM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for StringM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: StringM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&StringM> for String { + type Error = Error; + + fn try_from(v: &StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for StringM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for StringM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a StringM> for &'a str { + type Error = Error; + + fn try_from(v: &'a StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for StringM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(StringM(vec)) + }) + } +} + +impl WriteXdr for StringM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +// Frame ------------------------------------------------------------------------ + +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Frame(pub T) +where + T: ReadXdr; + +impl ReadXdr for Frame +where + T: ReadXdr, +{ + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + // Read the frame header value that contains 1 flag-bit and a 33-bit length. + // - The 1 flag bit is 0 when there are more frames for the same record. + // - The 31-bit length is the length of the bytes within the frame that + // follow the frame header. + let header = u32::read_xdr(r)?; + // TODO: Use the length and cap the length we'll read from `r`. + let last_record = header >> 31 == 1; + if last_record { + // Read the record in the frame. + Ok(Self(T::read_xdr(r)?)) + } else { + // TODO: Support reading those additional frames for the same + // record. + Err(Error::Unsupported) + } + } +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + pub fn vec_u8_read_without_padding() { + let buf = Cursor::new(vec![0, 0, 0, 4, 2, 2, 2, 2]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_read_with_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0, 0]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2]); + } + + #[test] + pub fn vec_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn vec_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 3, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn vec_u8_write_without_padding() { + let mut buf = vec![]; + let v: VecM = vec![2, 2, 2, 2].try_into().unwrap(); + + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 4, 2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_write_with_padding() { + let mut buf = vec![]; + let v: VecM = vec![2].try_into().unwrap(); + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 1, 2, 0, 0, 0]); + } + + #[test] + pub fn arr_u8_read_without_padding() { + let buf = Cursor::new(vec![2, 2, 2, 2]); + let v = <[u8; 4]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_read_with_padding() { + let buf = Cursor::new(vec![2, 0, 0, 0]); + let v = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2]); + } + + #[test] + pub fn arr_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![2, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn arr_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![2, 3, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn arr_u8_write_without_padding() { + let mut buf = vec![]; + [2u8, 2, 2, 2] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_write_with_padding() { + let mut buf = vec![]; + [2u8] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 0, 0, 0]); + } +} + +#[cfg(all(test, feature = "std"))] +mod test { + use super::*; + + #[test] + fn into_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.into_option(), None); + } + + #[test] + fn into_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.into_option(), Some(1)); + } + + #[test] + fn to_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } + + #[test] + fn depth_limited_read_write_under_the_limit_success() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(4)); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::depth(4)); + let a_back: Option>> = ReadXdr::read_xdr(&mut dlr).unwrap(); + assert_eq!(a, a_back); + } + + #[test] + fn write_over_depth_limit_fail() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(3)); + let res = a.write_xdr(&mut buf); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn read_over_depth_limit_fail() { + let read_limits = Limits::depth(3); + let write_limits = Limits::depth(5); + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), write_limits); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), read_limits); + let res: Result>>> = ReadXdr::read_xdr(&mut dlr); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn length_limited_read_write_i32() { + // Exact limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u32() { + // Exact limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_i64() { + // Exact limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u64() { + // Exact limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bool() { + // Exact limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_option() { + // Exact limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_u8() { + // Exact limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + <[u8; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_type() { + // Exact limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(12)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(13)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(13)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(11)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(11)); + assert_eq!( + <[bool; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_vec() { + // Exact limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(16)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(17)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(17)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(15)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(15)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bytes() { + // Exact limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_string() { + // Exact limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } +} + +#[cfg(all(test, not(feature = "alloc")))] +mod test { + use super::VecM; + + #[test] + fn to_option_none() { + let v: VecM = (&[]).try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = (&[1]).try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } +} + +/// Foo is an XDR Const defines as: +/// +/// ```text +/// const FOO = 1; +/// ``` +/// +pub const FOO: u64 = 1; + +/// TestArray is an XDR Typedef defines as: +/// +/// ```text +/// typedef int TestArray[FOO]; +/// ``` +/// +pub type TestArray = [i32; Foo]; + +/// TestArray2 is an XDR Typedef defines as: +/// +/// ```text +/// typedef int TestArray2; +/// ``` +/// +pub type TestArray2 = VecM::; + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum TypeVariant { + TestArray, +TestArray2, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, +TypeVariant::TestArray2, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", +"TestArray2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray => "TestArray", +Self::TestArray2 => "TestArray2", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + } + + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "TestArray" => Ok(Self::TestArray), +"TestArray2" => Ok(Self::TestArray2), + _ => Err(Error::Invalid), + } + } + } + + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum Type { + TestArray(Box), +TestArray2(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, +TypeVariant::TestArray2, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", +"TestArray2", ]; + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::TestArray => r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))), +TypeVariant::TestArray2 => r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))), + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t.0))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t.0))))), + } + } + + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } + + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), +TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), + } + } + + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::TestArray(ref v) => v.as_ref(), +Self::TestArray2(ref v) => v.as_ref(), + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray(_) => "TestArray", +Self::TestArray2(_) => "TestArray2", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::TestArray(_) => TypeVariant::TestArray, +Self::TestArray2(_) => TypeVariant::TestArray2, + } + } + } + + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::TestArray(v) => v.write_xdr(w), +Self::TestArray2(v) => v.write_xdr(w), + } + } + } diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs new file mode 100644 index 000000000..183011106 --- /dev/null +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -0,0 +1,3338 @@ +// Module is generated from: +// spec/fixtures/generator/enum.x + +#![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] + +/// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/enum.x", "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f") +]; + +use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; + +#[cfg(feature = "std")] +use core::marker::PhantomData; + +// When feature alloc is turned off use static lifetime Box and Vec types. +#[cfg(not(feature = "alloc"))] +mod noalloc { + pub mod boxed { + pub type Box = &'static T; + } + pub mod vec { + pub type Vec = &'static [T]; + } +} +#[cfg(not(feature = "alloc"))] +use noalloc::{boxed::Box, vec::Vec}; + +// When feature std is turned off, but feature alloc is turned on import the +// alloc crate and use its Box and Vec types. +#[cfg(all(not(feature = "std"), feature = "alloc"))] +extern crate alloc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::{ + borrow::ToOwned, + boxed::Box, + string::{FromUtf8Error, String}, + vec::Vec, +}; +#[cfg(feature = "std")] +use std::string::FromUtf8Error; + +#[cfg(feature = "arbitrary")] +use arbitrary::Arbitrary; + +// TODO: Add support for read/write xdr fns when std not available. + +#[cfg(feature = "std")] +use std::{ + error, io, + io::{BufRead, BufReader, Cursor, Read, Write}, +}; + +/// Error contains all errors returned by functions in this crate. It can be +/// compared via `PartialEq`, however any contained IO errors will only be +/// compared on their `ErrorKind`. +#[derive(Debug)] +pub enum Error { + Invalid, + Unsupported, + LengthExceedsMax, + LengthMismatch, + NonZeroPadding, + Utf8Error(core::str::Utf8Error), + #[cfg(feature = "alloc")] + InvalidHex, + #[cfg(feature = "std")] + Io(io::Error), + DepthLimitExceeded, + #[cfg(feature = "serde_json")] + Json(serde_json::Error), + LengthLimitExceeded, +} + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Utf8Error(l), Self::Utf8Error(r)) => l == r, + // IO errors cannot be compared, but in the absence of any more + // meaningful way to compare the errors we compare the kind of error + // and ignore the embedded source error or OS error. The main use + // case for comparing errors outputted by the XDR library is for + // error case testing, and a lack of the ability to compare has a + // detrimental affect on failure testing, so this is a tradeoff. + #[cfg(feature = "std")] + (Self::Io(l), Self::Io(r)) => l.kind() == r.kind(), + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + #[must_use] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Io(e) => Some(e), + #[cfg(feature = "serde_json")] + Self::Json(e) => Some(e), + _ => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Invalid => write!(f, "xdr value invalid"), + Error::Unsupported => write!(f, "xdr value unsupported"), + Error::LengthExceedsMax => write!(f, "xdr value max length exceeded"), + Error::LengthMismatch => write!(f, "xdr value length does not match"), + Error::NonZeroPadding => write!(f, "xdr padding contains non-zero bytes"), + Error::Utf8Error(e) => write!(f, "{e}"), + #[cfg(feature = "alloc")] + Error::InvalidHex => write!(f, "hex invalid"), + #[cfg(feature = "std")] + Error::Io(e) => write!(f, "{e}"), + Error::DepthLimitExceeded => write!(f, "depth limit exceeded"), + #[cfg(feature = "serde_json")] + Error::Json(e) => write!(f, "{e}"), + Error::LengthLimitExceeded => write!(f, "length limit exceeded"), + } + } +} + +impl From for Error { + fn from(_: TryFromSliceError) -> Error { + Error::LengthMismatch + } +} + +impl From for Error { + #[must_use] + fn from(e: core::str::Utf8Error) -> Self { + Error::Utf8Error(e) + } +} + +#[cfg(feature = "alloc")] +impl From for Error { + #[must_use] + fn from(e: FromUtf8Error) -> Self { + Error::Utf8Error(e.utf8_error()) + } +} + +#[cfg(feature = "std")] +impl From for Error { + #[must_use] + fn from(e: io::Error) -> Self { + Error::Io(e) + } +} + +#[cfg(feature = "serde_json")] +impl From for Error { + #[must_use] + fn from(e: serde_json::Error) -> Self { + Error::Json(e) + } +} + +impl From for () { + fn from(_: Error) {} +} + +#[allow(dead_code)] +type Result = core::result::Result; + +/// Name defines types that assign a static name to their value, such as the +/// name given to an identifier in an XDR enum, or the name given to the case in +/// a union. +pub trait Name { + fn name(&self) -> &'static str; +} + +/// Discriminant defines types that may contain a one-of value determined +/// according to the discriminant, and exposes the value of the discriminant for +/// that type, such as in an XDR union. +pub trait Discriminant { + fn discriminant(&self) -> D; +} + +/// Iter defines types that have variants that can be iterated. +pub trait Variants { + fn variants() -> slice::Iter<'static, V> + where + V: Sized; +} + +// Enum defines a type that is represented as an XDR enumeration when encoded. +pub trait Enum: Name + Variants + Sized {} + +// Union defines a type that is represented as an XDR union when encoded. +pub trait Union: Name + Discriminant + Variants +where + D: Sized, +{ +} + +/// `Limits` contains the limits that a limited reader or writer will be +/// constrained to. +#[cfg(feature = "std")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Limits { + /// Defines the maximum depth for recursive calls in `Read/WriteXdr` to + /// prevent stack overflow. + /// + /// The depth limit is akin to limiting stack depth. Its purpose is to + /// prevent the program from hitting the maximum stack size allowed by Rust, + /// which would result in an unrecoverable `SIGABRT`. For more information + /// about Rust's stack size limit, refer to the [Rust + /// documentation](https://doc.rust-lang.org/std/thread/#stack-size). + pub depth: u32, + + /// Defines the maximum number of bytes that will be read or written. + pub len: usize, +} + +#[cfg(feature = "std")] +impl Limits { + #[must_use] + pub fn none() -> Self { + Self { + depth: u32::MAX, + len: usize::MAX, + } + } + + #[must_use] + pub fn depth(depth: u32) -> Self { + Limits { + depth, + ..Limits::none() + } + } + + #[must_use] + pub fn len(len: usize) -> Self { + Limits { + len, + ..Limits::none() + } + } +} + +/// `Limited` wraps an object and provides functions for enforcing limits. +/// +/// Intended for use with readers and writers and limiting their reads and +/// writes. +#[cfg(feature = "std")] +pub struct Limited { + pub inner: L, + pub(crate) limits: Limits, +} + +#[cfg(feature = "std")] +impl Limited { + /// Constructs a new `Limited`. + /// + /// - `inner`: The value being limited. + /// - `limits`: The limits to enforce. + pub fn new(inner: L, limits: Limits) -> Self { + Limited { inner, limits } + } + + /// Consume the given length from the internal remaining length limit. + /// + /// ### Errors + /// + /// If the length would consume more length than the remaining length limit + /// allows. + pub(crate) fn consume_len(&mut self, len: usize) -> Result<()> { + if let Some(len) = self.limits.len.checked_sub(len) { + self.limits.len = len; + Ok(()) + } else { + Err(Error::LengthLimitExceeded) + } + } + + /// Consumes a single depth for the duration of the given function. + /// + /// ### Errors + /// + /// If the depth limit is already exhausted. + pub(crate) fn with_limited_depth(&mut self, f: F) -> Result + where + F: FnOnce(&mut Self) -> Result, + { + if let Some(depth) = self.limits.depth.checked_sub(1) { + self.limits.depth = depth; + let res = f(self); + self.limits.depth = self.limits.depth.saturating_add(1); + res + } else { + Err(Error::DepthLimitExceeded) + } + } +} + +#[cfg(feature = "std")] +impl Read for Limited { + /// Forwards the read operation to the wrapped object. + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.inner.read(buf) + } +} + +#[cfg(feature = "std")] +impl BufRead for Limited { + /// Forwards the read operation to the wrapped object. + fn fill_buf(&mut self) -> std::io::Result<&[u8]> { + self.inner.fill_buf() + } + + /// Forwards the read operation to the wrapped object. + fn consume(&mut self, amt: usize) { + self.inner.consume(amt); + } +} + +#[cfg(feature = "std")] +impl Write for Limited { + /// Forwards the write operation to the wrapped object. + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.inner.write(buf) + } + + /// Forwards the flush operation to the wrapped object. + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } +} + +#[cfg(feature = "std")] +pub struct ReadXdrIter { + reader: Limited>, + _s: PhantomData, +} + +#[cfg(feature = "std")] +impl ReadXdrIter { + fn new(r: R, limits: Limits) -> Self { + Self { + reader: Limited { + inner: BufReader::new(r), + limits, + }, + _s: PhantomData, + } + } +} + +#[cfg(feature = "std")] +impl Iterator for ReadXdrIter { + type Item = Result; + + // Next reads the internal reader and XDR decodes it into the Self type. If + // the EOF is reached without reading any new bytes `None` is returned. If + // EOF is reached after reading some bytes a truncated entry is assumed an + // an `Error::Io` containing an `UnexpectedEof`. If any other IO error + // occurs it is returned. Iteration of this iterator stops naturally when + // `None` is returned, but not when a `Some(Err(...))` is returned. The + // caller is responsible for checking each Result. + fn next(&mut self) -> Option { + // Try to fill the buffer to see if the EOF has been reached or not. + // This happens to effectively peek to see if the stream has finished + // and there are no more items. It is necessary to do this because the + // xdr types in this crate heavily use the `std::io::Read::read_exact` + // method that doesn't distinguish between an EOF at the beginning of a + // read and an EOF after a partial fill of a read_exact. + match self.reader.fill_buf() { + // If the reader has no more data and is unable to fill any new data + // into its internal buf, then the EOF has been reached. + Ok([]) => return None, + // If an error occurs filling the buffer, treat that as an error and stop. + Err(e) => return Some(Err(Error::Io(e))), + // If there is data in the buf available for reading, continue. + Ok([..]) => (), + }; + // Read the buf into the type. + let r = self.reader.with_limited_depth(|dlr| S::read_xdr(dlr)); + match r { + Ok(s) => Some(Ok(s)), + Err(e) => Some(Err(e)), + } + } +} + +pub trait ReadXdr +where + Self: Sized, +{ + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_to_end`] when the intent is for all bytes in the + /// read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result; + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_to_end(r: &mut Limited) -> Result { + let s = Self::read_xdr(r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64_to_end(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_into_to_end`] when the intent is for all bytes + /// in the read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr_into(&mut self, r: &mut Limited) -> Result<()> { + *self = Self::read_xdr(r)?; + Ok(()) + } + + /// Read the XDR into the existing value, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_into_to_end(&mut self, r: &mut Limited) -> Result<()> { + Self::read_xdr_into(self, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(()) + } else { + Err(Error::Invalid) + } + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_iter(r: &mut Limited) -> ReadXdrIter<&mut R, Self> { + ReadXdrIter::new(&mut r.inner, r.limits.clone()) + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + #[cfg(feature = "base64")] + fn read_xdr_base64_iter( + r: &mut Limited, + ) -> ReadXdrIter, Self> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + ReadXdrIter::new(dec, r.limits.clone()) + } + + /// Construct the type from the XDR bytes. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "std")] + fn from_xdr(bytes: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(&mut cursor)?; + Ok(t) + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn from_xdr_base64(b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } +} + +pub trait WriteXdr { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()>; + + #[cfg(feature = "std")] + fn to_xdr(&self, limits: Limits) -> Result> { + let mut cursor = Limited::new(Cursor::new(vec![]), limits); + self.write_xdr(&mut cursor)?; + let bytes = cursor.inner.into_inner(); + Ok(bytes) + } + + #[cfg(feature = "base64")] + fn to_xdr_base64(&self, limits: Limits) -> Result { + let mut enc = Limited::new( + base64::write::EncoderStringWriter::new(base64::STANDARD), + limits, + ); + self.write_xdr(&mut enc)?; + let b64 = enc.inner.into_inner(); + Ok(b64) + } +} + +/// `Pad_len` returns the number of bytes to pad an XDR value of the given +/// length to make the final serialized size a multiple of 4. +#[cfg(feature = "std")] +fn pad_len(len: usize) -> usize { + (4 - (len % 4)) % 4 +} + +impl ReadXdr for i32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for i64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for f32 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f32 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for f64 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f64 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for bool { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + let b = i == 1; + Ok(b) + }) + } +} + +impl WriteXdr for bool { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i = u32::from(*self); // true = 1, false = 0 + i.write_xdr(w) + }) + } +} + +impl ReadXdr for Option { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + match i { + 0 => Ok(None), + 1 => { + let t = T::read_xdr(r)?; + Ok(Some(t)) + } + _ => Err(Error::Invalid), + } + }) + } +} + +impl WriteXdr for Option { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + if let Some(t) = self { + 1u32.write_xdr(w)?; + t.write_xdr(w)?; + } else { + 0u32.write_xdr(w)?; + } + Ok(()) + }) + } +} + +impl ReadXdr for Box { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| Ok(Box::new(T::read_xdr(r)?))) + } +} + +impl WriteXdr for Box { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| T::write_xdr(self, w)) + } +} + +impl ReadXdr for () { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + Ok(()) + } +} + +impl WriteXdr for () { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + Ok(()) + } +} + +impl ReadXdr for [u8; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + r.consume_len(N)?; + let padding = pad_len(N); + r.consume_len(padding)?; + let mut arr = [0u8; N]; + r.read_exact(&mut arr)?; + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + Ok(arr) + }) + } +} + +impl WriteXdr for [u8; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + w.consume_len(N)?; + let padding = pad_len(N); + w.consume_len(padding)?; + w.write_all(self)?; + w.write_all(&[0u8; 3][..padding])?; + Ok(()) + }) + } +} + +impl ReadXdr for [T; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let mut vec = Vec::with_capacity(N); + for _ in 0..N { + let t = T::read_xdr(r)?; + vec.push(t); + } + let arr: [T; N] = vec.try_into().unwrap_or_else(|_: Vec| unreachable!()); + Ok(arr) + }) + } +} + +impl WriteXdr for [T; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + for t in self { + t.write_xdr(w)?; + } + Ok(()) + }) + } +} + +// VecM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec) +where + T: 'static; + +impl Deref for VecM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for VecM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl VecM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl VecM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl VecM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl VecM { + #[must_use] + pub fn to_option(&self) -> Option { + if self.len() > 0 { + Some(self.0[0].clone()) + } else { + None + } + } +} + +#[cfg(not(feature = "alloc"))] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.to_option() + } +} + +#[cfg(feature = "alloc")] +impl VecM { + #[must_use] + pub fn into_option(mut self) -> Option { + self.0.drain(..).next() + } +} + +#[cfg(feature = "alloc")] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.into_option() + } +} + +impl TryFrom> for VecM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: VecM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&VecM> for Vec { + #[must_use] + fn from(v: &VecM) -> Self { + v.0.clone() + } +} + +impl AsRef> for VecM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for VecM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T]> for VecM { + type Error = Error; + + fn try_from(v: &[T]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[T]> for VecM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[T; N]> for VecM { + type Error = Error; + + fn try_from(v: [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [T; N] { + type Error = VecM; + + fn try_from(v: VecM) -> core::result::Result { + let s: [T; N] = v.0.try_into().map_err(|v: Vec| VecM::(v))?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T; N]> for VecM { + type Error = Error; + + fn try_from(v: &[T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [T; N]> for VecM { + type Error = Error; + + fn try_from(v: &'static [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for VecM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for VecM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: VecM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&VecM> for String { + type Error = Error; + + fn try_from(v: &VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for VecM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for VecM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a VecM> for &'a str { + type Error = Error; + + fn try_from(v: &'a VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + let mut vec = Vec::new(); + for _ in 0..len { + let t = T::read_xdr(r)?; + vec.push(t); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + for t in &self.0 { + t.write_xdr(w)?; + } + + Ok(()) + }) + } +} + +// BytesM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +impl core::fmt::Display for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +impl core::fmt::Debug for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "BytesM(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for BytesM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} + +impl Deref for BytesM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for BytesM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl BytesM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl BytesM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl BytesM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for BytesM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: BytesM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&BytesM> for Vec { + #[must_use] + fn from(v: &BytesM) -> Self { + v.0.clone() + } +} + +impl AsRef> for BytesM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for BytesM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for BytesM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = BytesM; + + fn try_from(v: BytesM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(BytesM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for BytesM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for BytesM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: BytesM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&BytesM> for String { + type Error = Error; + + fn try_from(v: &BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for BytesM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for BytesM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a BytesM> for &'a str { + type Error = Error; + + fn try_from(v: &'a BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for BytesM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(BytesM(vec)) + }) + } +} + +impl WriteXdr for BytesM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..pad_len(len as usize)])?; + + Ok(()) + }) + } +} + +// StringM ------------------------------------------------------------------------ + +/// A string type that contains arbitrary bytes. +/// +/// Convertible, fallibly, to/from a Rust UTF-8 String using +/// [`TryFrom`]/[`TryInto`]/[`StringM::to_utf8_string`]. +/// +/// Convertible, lossyly, to a Rust UTF-8 String using +/// [`StringM::to_utf8_string_lossy`]. +/// +/// Convertible to/from escaped printable-ASCII using +/// [`Display`]/[`ToString`]/[`FromStr`]. + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +impl core::fmt::Display for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + Ok(()) + } +} + +impl core::fmt::Debug for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "StringM(")?; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for StringM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?; + Ok(Self(b)) + } +} + +impl Deref for StringM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for StringM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl StringM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl StringM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl StringM { + #[cfg(feature = "alloc")] + pub fn to_utf8_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_utf8_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_utf8_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_utf8_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for StringM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: StringM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&StringM> for Vec { + #[must_use] + fn from(v: &StringM) -> Self { + v.0.clone() + } +} + +impl AsRef> for StringM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for StringM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for StringM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for StringM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = StringM; + + fn try_from(v: StringM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(StringM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for StringM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for StringM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: StringM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&StringM> for String { + type Error = Error; + + fn try_from(v: &StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for StringM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for StringM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a StringM> for &'a str { + type Error = Error; + + fn try_from(v: &'a StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for StringM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(StringM(vec)) + }) + } +} + +impl WriteXdr for StringM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +// Frame ------------------------------------------------------------------------ + +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Frame(pub T) +where + T: ReadXdr; + +impl ReadXdr for Frame +where + T: ReadXdr, +{ + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + // Read the frame header value that contains 1 flag-bit and a 33-bit length. + // - The 1 flag bit is 0 when there are more frames for the same record. + // - The 31-bit length is the length of the bytes within the frame that + // follow the frame header. + let header = u32::read_xdr(r)?; + // TODO: Use the length and cap the length we'll read from `r`. + let last_record = header >> 31 == 1; + if last_record { + // Read the record in the frame. + Ok(Self(T::read_xdr(r)?)) + } else { + // TODO: Support reading those additional frames for the same + // record. + Err(Error::Unsupported) + } + } +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + pub fn vec_u8_read_without_padding() { + let buf = Cursor::new(vec![0, 0, 0, 4, 2, 2, 2, 2]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_read_with_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0, 0]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2]); + } + + #[test] + pub fn vec_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn vec_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 3, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn vec_u8_write_without_padding() { + let mut buf = vec![]; + let v: VecM = vec![2, 2, 2, 2].try_into().unwrap(); + + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 4, 2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_write_with_padding() { + let mut buf = vec![]; + let v: VecM = vec![2].try_into().unwrap(); + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 1, 2, 0, 0, 0]); + } + + #[test] + pub fn arr_u8_read_without_padding() { + let buf = Cursor::new(vec![2, 2, 2, 2]); + let v = <[u8; 4]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_read_with_padding() { + let buf = Cursor::new(vec![2, 0, 0, 0]); + let v = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2]); + } + + #[test] + pub fn arr_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![2, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn arr_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![2, 3, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn arr_u8_write_without_padding() { + let mut buf = vec![]; + [2u8, 2, 2, 2] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_write_with_padding() { + let mut buf = vec![]; + [2u8] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 0, 0, 0]); + } +} + +#[cfg(all(test, feature = "std"))] +mod test { + use super::*; + + #[test] + fn into_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.into_option(), None); + } + + #[test] + fn into_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.into_option(), Some(1)); + } + + #[test] + fn to_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } + + #[test] + fn depth_limited_read_write_under_the_limit_success() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(4)); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::depth(4)); + let a_back: Option>> = ReadXdr::read_xdr(&mut dlr).unwrap(); + assert_eq!(a, a_back); + } + + #[test] + fn write_over_depth_limit_fail() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(3)); + let res = a.write_xdr(&mut buf); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn read_over_depth_limit_fail() { + let read_limits = Limits::depth(3); + let write_limits = Limits::depth(5); + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), write_limits); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), read_limits); + let res: Result>>> = ReadXdr::read_xdr(&mut dlr); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn length_limited_read_write_i32() { + // Exact limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u32() { + // Exact limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_i64() { + // Exact limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u64() { + // Exact limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bool() { + // Exact limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_option() { + // Exact limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_u8() { + // Exact limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + <[u8; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_type() { + // Exact limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(12)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(13)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(13)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(11)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(11)); + assert_eq!( + <[bool; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_vec() { + // Exact limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(16)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(17)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(17)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(15)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(15)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bytes() { + // Exact limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_string() { + // Exact limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } +} + +#[cfg(all(test, not(feature = "alloc")))] +mod test { + use super::VecM; + + #[test] + fn to_option_none() { + let v: VecM = (&[]).try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = (&[1]).try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } +} + +/// MessageType is an XDR Enum defines as: +/// +/// ```text +/// enum MessageType +/// { +/// ERROR_MSG, +/// HELLO, +/// DONT_HAVE, +/// +/// GET_PEERS, // gets a list of peers this guy knows about +/// PEERS, +/// +/// GET_TX_SET, // gets a particular txset by hash +/// TX_SET, +/// +/// GET_VALIDATIONS, // gets validations for a given ledger hash +/// VALIDATIONS, +/// +/// TRANSACTION, //pass on a tx you have heard about +/// JSON_TRANSACTION, +/// +/// // FBA +/// GET_FBA_QUORUMSET, +/// FBA_QUORUMSET, +/// FBA_MESSAGE +/// }; +/// ``` +/// +// enum +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[repr(i32)] +pub enum MessageType { + ErrorMsg = 0, + Hello = 1, + DontHave = 2, + GetPeers = 3, + Peers = 4, + GetTxSet = 5, + TxSet = 6, + GetValidations = 7, + Validations = 8, + Transaction = 9, + JsonTransaction = 10, + GetFbaQuorumset = 11, + FbaQuorumset = 12, + FbaMessage = 13, +} + + impl MessageType { + pub const VARIANTS: [MessageType; 14] = [ MessageType::ErrorMsg, +MessageType::Hello, +MessageType::DontHave, +MessageType::GetPeers, +MessageType::Peers, +MessageType::GetTxSet, +MessageType::TxSet, +MessageType::GetValidations, +MessageType::Validations, +MessageType::Transaction, +MessageType::JsonTransaction, +MessageType::GetFbaQuorumset, +MessageType::FbaQuorumset, +MessageType::FbaMessage, ]; + pub const VARIANTS_STR: [&'static str; 14] = [ "ErrorMsg", +"Hello", +"DontHave", +"GetPeers", +"Peers", +"GetTxSet", +"TxSet", +"GetValidations", +"Validations", +"Transaction", +"JsonTransaction", +"GetFbaQuorumset", +"FbaQuorumset", +"FbaMessage", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::ErrorMsg => "ErrorMsg", +Self::Hello => "Hello", +Self::DontHave => "DontHave", +Self::GetPeers => "GetPeers", +Self::Peers => "Peers", +Self::GetTxSet => "GetTxSet", +Self::TxSet => "TxSet", +Self::GetValidations => "GetValidations", +Self::Validations => "Validations", +Self::Transaction => "Transaction", +Self::JsonTransaction => "JsonTransaction", +Self::GetFbaQuorumset => "GetFbaQuorumset", +Self::FbaQuorumset => "FbaQuorumset", +Self::FbaMessage => "FbaMessage", + } + } + + #[must_use] + pub const fn variants() -> [MessageType; 14] { + Self::VARIANTS + } + } + + impl Name for MessageType { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for MessageType { + fn variants() -> slice::Iter<'static, MessageType> { + Self::VARIANTS.iter() + } + } + + impl Enum for MessageType {} + + impl fmt::Display for MessageType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } + + impl TryFrom for MessageType { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 0 => MessageType::ErrorMsg, +1 => MessageType::Hello, +2 => MessageType::DontHave, +3 => MessageType::GetPeers, +4 => MessageType::Peers, +5 => MessageType::GetTxSet, +6 => MessageType::TxSet, +7 => MessageType::GetValidations, +8 => MessageType::Validations, +9 => MessageType::Transaction, +10 => MessageType::JsonTransaction, +11 => MessageType::GetFbaQuorumset, +12 => MessageType::FbaQuorumset, +13 => MessageType::FbaMessage, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } + + impl From for i32 { + #[must_use] + fn from(e: MessageType) -> Self { + e as Self + } + } + + impl ReadXdr for MessageType { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } + + impl WriteXdr for MessageType { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } + +/// Color is an XDR Enum defines as: +/// +/// ```text +/// enum Color { +/// RED=0, +/// GREEN=1, +/// BLUE=2 +/// }; +/// ``` +/// +// enum +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[repr(i32)] +pub enum Color { + Red = 0, + Green = 1, + Blue = 2, +} + + impl Color { + pub const VARIANTS: [Color; 3] = [ Color::Red, +Color::Green, +Color::Blue, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "Red", +"Green", +"Blue", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red => "Red", +Self::Green => "Green", +Self::Blue => "Blue", + } + } + + #[must_use] + pub const fn variants() -> [Color; 3] { + Self::VARIANTS + } + } + + impl Name for Color { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Color { + fn variants() -> slice::Iter<'static, Color> { + Self::VARIANTS.iter() + } + } + + impl Enum for Color {} + + impl fmt::Display for Color { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } + + impl TryFrom for Color { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color::Red, +1 => Color::Green, +2 => Color::Blue, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } + + impl From for i32 { + #[must_use] + fn from(e: Color) -> Self { + e as Self + } + } + + impl ReadXdr for Color { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } + + impl WriteXdr for Color { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } + +/// Color2 is an XDR Enum defines as: +/// +/// ```text +/// enum Color2 { +/// RED2=RED, +/// GREEN2=1, +/// BLUE2=2 +/// }; +/// ``` +/// +// enum +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[repr(i32)] +pub enum Color2 { + Red2 = 0, + Green2 = 1, + Blue2 = 2, +} + + impl Color2 { + pub const VARIANTS: [Color2; 3] = [ Color2::Red2, +Color2::Green2, +Color2::Blue2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "Red2", +"Green2", +"Blue2", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red2 => "Red2", +Self::Green2 => "Green2", +Self::Blue2 => "Blue2", + } + } + + #[must_use] + pub const fn variants() -> [Color2; 3] { + Self::VARIANTS + } + } + + impl Name for Color2 { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Color2 { + fn variants() -> slice::Iter<'static, Color2> { + Self::VARIANTS.iter() + } + } + + impl Enum for Color2 {} + + impl fmt::Display for Color2 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } + + impl TryFrom for Color2 { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color2::Red2, +1 => Color2::Green2, +2 => Color2::Blue2, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } + + impl From for i32 { + #[must_use] + fn from(e: Color2) -> Self { + e as Self + } + } + + impl ReadXdr for Color2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } + + impl WriteXdr for Color2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum TypeVariant { + MessageType, +Color, +Color2, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, +TypeVariant::Color, +TypeVariant::Color2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", +"Color", +"Color2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType => "MessageType", +Self::Color => "Color", +Self::Color2 => "Color2", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } + } + + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "MessageType" => Ok(Self::MessageType), +"Color" => Ok(Self::Color), +"Color2" => Ok(Self::Color2), + _ => Err(Error::Invalid), + } + } + } + + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum Type { + MessageType(Box), +Color(Box), +Color2(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, +TypeVariant::Color, +TypeVariant::Color2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", +"Color", +"Color2", ]; + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::MessageType => r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))), +TypeVariant::Color => r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))), +TypeVariant::Color2 => r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))), + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t.0))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t.0))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t.0))))), + } + } + + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } + + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::MessageType => Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), + } + } + + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::MessageType(ref v) => v.as_ref(), +Self::Color(ref v) => v.as_ref(), +Self::Color2(ref v) => v.as_ref(), + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType(_) => "MessageType", +Self::Color(_) => "Color", +Self::Color2(_) => "Color2", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::MessageType(_) => TypeVariant::MessageType, +Self::Color(_) => TypeVariant::Color, +Self::Color2(_) => TypeVariant::Color2, + } + } + } + + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::MessageType(v) => v.write_xdr(w), +Self::Color(v) => v.write_xdr(w), +Self::Color2(v) => v.write_xdr(w), + } + } + } diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs new file mode 100644 index 000000000..1a3607fa2 --- /dev/null +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -0,0 +1,3292 @@ +// Module is generated from: +// spec/fixtures/generator/nesting.x + +#![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] + +/// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/nesting.x", "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a") +]; + +use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; + +#[cfg(feature = "std")] +use core::marker::PhantomData; + +// When feature alloc is turned off use static lifetime Box and Vec types. +#[cfg(not(feature = "alloc"))] +mod noalloc { + pub mod boxed { + pub type Box = &'static T; + } + pub mod vec { + pub type Vec = &'static [T]; + } +} +#[cfg(not(feature = "alloc"))] +use noalloc::{boxed::Box, vec::Vec}; + +// When feature std is turned off, but feature alloc is turned on import the +// alloc crate and use its Box and Vec types. +#[cfg(all(not(feature = "std"), feature = "alloc"))] +extern crate alloc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::{ + borrow::ToOwned, + boxed::Box, + string::{FromUtf8Error, String}, + vec::Vec, +}; +#[cfg(feature = "std")] +use std::string::FromUtf8Error; + +#[cfg(feature = "arbitrary")] +use arbitrary::Arbitrary; + +// TODO: Add support for read/write xdr fns when std not available. + +#[cfg(feature = "std")] +use std::{ + error, io, + io::{BufRead, BufReader, Cursor, Read, Write}, +}; + +/// Error contains all errors returned by functions in this crate. It can be +/// compared via `PartialEq`, however any contained IO errors will only be +/// compared on their `ErrorKind`. +#[derive(Debug)] +pub enum Error { + Invalid, + Unsupported, + LengthExceedsMax, + LengthMismatch, + NonZeroPadding, + Utf8Error(core::str::Utf8Error), + #[cfg(feature = "alloc")] + InvalidHex, + #[cfg(feature = "std")] + Io(io::Error), + DepthLimitExceeded, + #[cfg(feature = "serde_json")] + Json(serde_json::Error), + LengthLimitExceeded, +} + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Utf8Error(l), Self::Utf8Error(r)) => l == r, + // IO errors cannot be compared, but in the absence of any more + // meaningful way to compare the errors we compare the kind of error + // and ignore the embedded source error or OS error. The main use + // case for comparing errors outputted by the XDR library is for + // error case testing, and a lack of the ability to compare has a + // detrimental affect on failure testing, so this is a tradeoff. + #[cfg(feature = "std")] + (Self::Io(l), Self::Io(r)) => l.kind() == r.kind(), + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + #[must_use] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Io(e) => Some(e), + #[cfg(feature = "serde_json")] + Self::Json(e) => Some(e), + _ => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Invalid => write!(f, "xdr value invalid"), + Error::Unsupported => write!(f, "xdr value unsupported"), + Error::LengthExceedsMax => write!(f, "xdr value max length exceeded"), + Error::LengthMismatch => write!(f, "xdr value length does not match"), + Error::NonZeroPadding => write!(f, "xdr padding contains non-zero bytes"), + Error::Utf8Error(e) => write!(f, "{e}"), + #[cfg(feature = "alloc")] + Error::InvalidHex => write!(f, "hex invalid"), + #[cfg(feature = "std")] + Error::Io(e) => write!(f, "{e}"), + Error::DepthLimitExceeded => write!(f, "depth limit exceeded"), + #[cfg(feature = "serde_json")] + Error::Json(e) => write!(f, "{e}"), + Error::LengthLimitExceeded => write!(f, "length limit exceeded"), + } + } +} + +impl From for Error { + fn from(_: TryFromSliceError) -> Error { + Error::LengthMismatch + } +} + +impl From for Error { + #[must_use] + fn from(e: core::str::Utf8Error) -> Self { + Error::Utf8Error(e) + } +} + +#[cfg(feature = "alloc")] +impl From for Error { + #[must_use] + fn from(e: FromUtf8Error) -> Self { + Error::Utf8Error(e.utf8_error()) + } +} + +#[cfg(feature = "std")] +impl From for Error { + #[must_use] + fn from(e: io::Error) -> Self { + Error::Io(e) + } +} + +#[cfg(feature = "serde_json")] +impl From for Error { + #[must_use] + fn from(e: serde_json::Error) -> Self { + Error::Json(e) + } +} + +impl From for () { + fn from(_: Error) {} +} + +#[allow(dead_code)] +type Result = core::result::Result; + +/// Name defines types that assign a static name to their value, such as the +/// name given to an identifier in an XDR enum, or the name given to the case in +/// a union. +pub trait Name { + fn name(&self) -> &'static str; +} + +/// Discriminant defines types that may contain a one-of value determined +/// according to the discriminant, and exposes the value of the discriminant for +/// that type, such as in an XDR union. +pub trait Discriminant { + fn discriminant(&self) -> D; +} + +/// Iter defines types that have variants that can be iterated. +pub trait Variants { + fn variants() -> slice::Iter<'static, V> + where + V: Sized; +} + +// Enum defines a type that is represented as an XDR enumeration when encoded. +pub trait Enum: Name + Variants + Sized {} + +// Union defines a type that is represented as an XDR union when encoded. +pub trait Union: Name + Discriminant + Variants +where + D: Sized, +{ +} + +/// `Limits` contains the limits that a limited reader or writer will be +/// constrained to. +#[cfg(feature = "std")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Limits { + /// Defines the maximum depth for recursive calls in `Read/WriteXdr` to + /// prevent stack overflow. + /// + /// The depth limit is akin to limiting stack depth. Its purpose is to + /// prevent the program from hitting the maximum stack size allowed by Rust, + /// which would result in an unrecoverable `SIGABRT`. For more information + /// about Rust's stack size limit, refer to the [Rust + /// documentation](https://doc.rust-lang.org/std/thread/#stack-size). + pub depth: u32, + + /// Defines the maximum number of bytes that will be read or written. + pub len: usize, +} + +#[cfg(feature = "std")] +impl Limits { + #[must_use] + pub fn none() -> Self { + Self { + depth: u32::MAX, + len: usize::MAX, + } + } + + #[must_use] + pub fn depth(depth: u32) -> Self { + Limits { + depth, + ..Limits::none() + } + } + + #[must_use] + pub fn len(len: usize) -> Self { + Limits { + len, + ..Limits::none() + } + } +} + +/// `Limited` wraps an object and provides functions for enforcing limits. +/// +/// Intended for use with readers and writers and limiting their reads and +/// writes. +#[cfg(feature = "std")] +pub struct Limited { + pub inner: L, + pub(crate) limits: Limits, +} + +#[cfg(feature = "std")] +impl Limited { + /// Constructs a new `Limited`. + /// + /// - `inner`: The value being limited. + /// - `limits`: The limits to enforce. + pub fn new(inner: L, limits: Limits) -> Self { + Limited { inner, limits } + } + + /// Consume the given length from the internal remaining length limit. + /// + /// ### Errors + /// + /// If the length would consume more length than the remaining length limit + /// allows. + pub(crate) fn consume_len(&mut self, len: usize) -> Result<()> { + if let Some(len) = self.limits.len.checked_sub(len) { + self.limits.len = len; + Ok(()) + } else { + Err(Error::LengthLimitExceeded) + } + } + + /// Consumes a single depth for the duration of the given function. + /// + /// ### Errors + /// + /// If the depth limit is already exhausted. + pub(crate) fn with_limited_depth(&mut self, f: F) -> Result + where + F: FnOnce(&mut Self) -> Result, + { + if let Some(depth) = self.limits.depth.checked_sub(1) { + self.limits.depth = depth; + let res = f(self); + self.limits.depth = self.limits.depth.saturating_add(1); + res + } else { + Err(Error::DepthLimitExceeded) + } + } +} + +#[cfg(feature = "std")] +impl Read for Limited { + /// Forwards the read operation to the wrapped object. + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.inner.read(buf) + } +} + +#[cfg(feature = "std")] +impl BufRead for Limited { + /// Forwards the read operation to the wrapped object. + fn fill_buf(&mut self) -> std::io::Result<&[u8]> { + self.inner.fill_buf() + } + + /// Forwards the read operation to the wrapped object. + fn consume(&mut self, amt: usize) { + self.inner.consume(amt); + } +} + +#[cfg(feature = "std")] +impl Write for Limited { + /// Forwards the write operation to the wrapped object. + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.inner.write(buf) + } + + /// Forwards the flush operation to the wrapped object. + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } +} + +#[cfg(feature = "std")] +pub struct ReadXdrIter { + reader: Limited>, + _s: PhantomData, +} + +#[cfg(feature = "std")] +impl ReadXdrIter { + fn new(r: R, limits: Limits) -> Self { + Self { + reader: Limited { + inner: BufReader::new(r), + limits, + }, + _s: PhantomData, + } + } +} + +#[cfg(feature = "std")] +impl Iterator for ReadXdrIter { + type Item = Result; + + // Next reads the internal reader and XDR decodes it into the Self type. If + // the EOF is reached without reading any new bytes `None` is returned. If + // EOF is reached after reading some bytes a truncated entry is assumed an + // an `Error::Io` containing an `UnexpectedEof`. If any other IO error + // occurs it is returned. Iteration of this iterator stops naturally when + // `None` is returned, but not when a `Some(Err(...))` is returned. The + // caller is responsible for checking each Result. + fn next(&mut self) -> Option { + // Try to fill the buffer to see if the EOF has been reached or not. + // This happens to effectively peek to see if the stream has finished + // and there are no more items. It is necessary to do this because the + // xdr types in this crate heavily use the `std::io::Read::read_exact` + // method that doesn't distinguish between an EOF at the beginning of a + // read and an EOF after a partial fill of a read_exact. + match self.reader.fill_buf() { + // If the reader has no more data and is unable to fill any new data + // into its internal buf, then the EOF has been reached. + Ok([]) => return None, + // If an error occurs filling the buffer, treat that as an error and stop. + Err(e) => return Some(Err(Error::Io(e))), + // If there is data in the buf available for reading, continue. + Ok([..]) => (), + }; + // Read the buf into the type. + let r = self.reader.with_limited_depth(|dlr| S::read_xdr(dlr)); + match r { + Ok(s) => Some(Ok(s)), + Err(e) => Some(Err(e)), + } + } +} + +pub trait ReadXdr +where + Self: Sized, +{ + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_to_end`] when the intent is for all bytes in the + /// read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result; + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_to_end(r: &mut Limited) -> Result { + let s = Self::read_xdr(r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64_to_end(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_into_to_end`] when the intent is for all bytes + /// in the read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr_into(&mut self, r: &mut Limited) -> Result<()> { + *self = Self::read_xdr(r)?; + Ok(()) + } + + /// Read the XDR into the existing value, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_into_to_end(&mut self, r: &mut Limited) -> Result<()> { + Self::read_xdr_into(self, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(()) + } else { + Err(Error::Invalid) + } + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_iter(r: &mut Limited) -> ReadXdrIter<&mut R, Self> { + ReadXdrIter::new(&mut r.inner, r.limits.clone()) + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + #[cfg(feature = "base64")] + fn read_xdr_base64_iter( + r: &mut Limited, + ) -> ReadXdrIter, Self> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + ReadXdrIter::new(dec, r.limits.clone()) + } + + /// Construct the type from the XDR bytes. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "std")] + fn from_xdr(bytes: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(&mut cursor)?; + Ok(t) + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn from_xdr_base64(b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } +} + +pub trait WriteXdr { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()>; + + #[cfg(feature = "std")] + fn to_xdr(&self, limits: Limits) -> Result> { + let mut cursor = Limited::new(Cursor::new(vec![]), limits); + self.write_xdr(&mut cursor)?; + let bytes = cursor.inner.into_inner(); + Ok(bytes) + } + + #[cfg(feature = "base64")] + fn to_xdr_base64(&self, limits: Limits) -> Result { + let mut enc = Limited::new( + base64::write::EncoderStringWriter::new(base64::STANDARD), + limits, + ); + self.write_xdr(&mut enc)?; + let b64 = enc.inner.into_inner(); + Ok(b64) + } +} + +/// `Pad_len` returns the number of bytes to pad an XDR value of the given +/// length to make the final serialized size a multiple of 4. +#[cfg(feature = "std")] +fn pad_len(len: usize) -> usize { + (4 - (len % 4)) % 4 +} + +impl ReadXdr for i32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for i64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for f32 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f32 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for f64 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f64 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for bool { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + let b = i == 1; + Ok(b) + }) + } +} + +impl WriteXdr for bool { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i = u32::from(*self); // true = 1, false = 0 + i.write_xdr(w) + }) + } +} + +impl ReadXdr for Option { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + match i { + 0 => Ok(None), + 1 => { + let t = T::read_xdr(r)?; + Ok(Some(t)) + } + _ => Err(Error::Invalid), + } + }) + } +} + +impl WriteXdr for Option { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + if let Some(t) = self { + 1u32.write_xdr(w)?; + t.write_xdr(w)?; + } else { + 0u32.write_xdr(w)?; + } + Ok(()) + }) + } +} + +impl ReadXdr for Box { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| Ok(Box::new(T::read_xdr(r)?))) + } +} + +impl WriteXdr for Box { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| T::write_xdr(self, w)) + } +} + +impl ReadXdr for () { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + Ok(()) + } +} + +impl WriteXdr for () { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + Ok(()) + } +} + +impl ReadXdr for [u8; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + r.consume_len(N)?; + let padding = pad_len(N); + r.consume_len(padding)?; + let mut arr = [0u8; N]; + r.read_exact(&mut arr)?; + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + Ok(arr) + }) + } +} + +impl WriteXdr for [u8; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + w.consume_len(N)?; + let padding = pad_len(N); + w.consume_len(padding)?; + w.write_all(self)?; + w.write_all(&[0u8; 3][..padding])?; + Ok(()) + }) + } +} + +impl ReadXdr for [T; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let mut vec = Vec::with_capacity(N); + for _ in 0..N { + let t = T::read_xdr(r)?; + vec.push(t); + } + let arr: [T; N] = vec.try_into().unwrap_or_else(|_: Vec| unreachable!()); + Ok(arr) + }) + } +} + +impl WriteXdr for [T; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + for t in self { + t.write_xdr(w)?; + } + Ok(()) + }) + } +} + +// VecM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec) +where + T: 'static; + +impl Deref for VecM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for VecM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl VecM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl VecM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl VecM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl VecM { + #[must_use] + pub fn to_option(&self) -> Option { + if self.len() > 0 { + Some(self.0[0].clone()) + } else { + None + } + } +} + +#[cfg(not(feature = "alloc"))] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.to_option() + } +} + +#[cfg(feature = "alloc")] +impl VecM { + #[must_use] + pub fn into_option(mut self) -> Option { + self.0.drain(..).next() + } +} + +#[cfg(feature = "alloc")] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.into_option() + } +} + +impl TryFrom> for VecM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: VecM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&VecM> for Vec { + #[must_use] + fn from(v: &VecM) -> Self { + v.0.clone() + } +} + +impl AsRef> for VecM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for VecM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T]> for VecM { + type Error = Error; + + fn try_from(v: &[T]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[T]> for VecM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[T; N]> for VecM { + type Error = Error; + + fn try_from(v: [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [T; N] { + type Error = VecM; + + fn try_from(v: VecM) -> core::result::Result { + let s: [T; N] = v.0.try_into().map_err(|v: Vec| VecM::(v))?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T; N]> for VecM { + type Error = Error; + + fn try_from(v: &[T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [T; N]> for VecM { + type Error = Error; + + fn try_from(v: &'static [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for VecM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for VecM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: VecM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&VecM> for String { + type Error = Error; + + fn try_from(v: &VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for VecM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for VecM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a VecM> for &'a str { + type Error = Error; + + fn try_from(v: &'a VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + let mut vec = Vec::new(); + for _ in 0..len { + let t = T::read_xdr(r)?; + vec.push(t); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + for t in &self.0 { + t.write_xdr(w)?; + } + + Ok(()) + }) + } +} + +// BytesM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +impl core::fmt::Display for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +impl core::fmt::Debug for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "BytesM(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for BytesM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} + +impl Deref for BytesM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for BytesM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl BytesM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl BytesM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl BytesM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for BytesM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: BytesM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&BytesM> for Vec { + #[must_use] + fn from(v: &BytesM) -> Self { + v.0.clone() + } +} + +impl AsRef> for BytesM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for BytesM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for BytesM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = BytesM; + + fn try_from(v: BytesM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(BytesM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for BytesM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for BytesM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: BytesM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&BytesM> for String { + type Error = Error; + + fn try_from(v: &BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for BytesM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for BytesM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a BytesM> for &'a str { + type Error = Error; + + fn try_from(v: &'a BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for BytesM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(BytesM(vec)) + }) + } +} + +impl WriteXdr for BytesM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..pad_len(len as usize)])?; + + Ok(()) + }) + } +} + +// StringM ------------------------------------------------------------------------ + +/// A string type that contains arbitrary bytes. +/// +/// Convertible, fallibly, to/from a Rust UTF-8 String using +/// [`TryFrom`]/[`TryInto`]/[`StringM::to_utf8_string`]. +/// +/// Convertible, lossyly, to a Rust UTF-8 String using +/// [`StringM::to_utf8_string_lossy`]. +/// +/// Convertible to/from escaped printable-ASCII using +/// [`Display`]/[`ToString`]/[`FromStr`]. + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +impl core::fmt::Display for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + Ok(()) + } +} + +impl core::fmt::Debug for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "StringM(")?; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for StringM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?; + Ok(Self(b)) + } +} + +impl Deref for StringM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for StringM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl StringM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl StringM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl StringM { + #[cfg(feature = "alloc")] + pub fn to_utf8_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_utf8_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_utf8_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_utf8_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for StringM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: StringM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&StringM> for Vec { + #[must_use] + fn from(v: &StringM) -> Self { + v.0.clone() + } +} + +impl AsRef> for StringM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for StringM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for StringM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for StringM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = StringM; + + fn try_from(v: StringM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(StringM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for StringM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for StringM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: StringM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&StringM> for String { + type Error = Error; + + fn try_from(v: &StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for StringM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for StringM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a StringM> for &'a str { + type Error = Error; + + fn try_from(v: &'a StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for StringM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(StringM(vec)) + }) + } +} + +impl WriteXdr for StringM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +// Frame ------------------------------------------------------------------------ + +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Frame(pub T) +where + T: ReadXdr; + +impl ReadXdr for Frame +where + T: ReadXdr, +{ + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + // Read the frame header value that contains 1 flag-bit and a 33-bit length. + // - The 1 flag bit is 0 when there are more frames for the same record. + // - The 31-bit length is the length of the bytes within the frame that + // follow the frame header. + let header = u32::read_xdr(r)?; + // TODO: Use the length and cap the length we'll read from `r`. + let last_record = header >> 31 == 1; + if last_record { + // Read the record in the frame. + Ok(Self(T::read_xdr(r)?)) + } else { + // TODO: Support reading those additional frames for the same + // record. + Err(Error::Unsupported) + } + } +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + pub fn vec_u8_read_without_padding() { + let buf = Cursor::new(vec![0, 0, 0, 4, 2, 2, 2, 2]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_read_with_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0, 0]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2]); + } + + #[test] + pub fn vec_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn vec_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 3, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn vec_u8_write_without_padding() { + let mut buf = vec![]; + let v: VecM = vec![2, 2, 2, 2].try_into().unwrap(); + + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 4, 2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_write_with_padding() { + let mut buf = vec![]; + let v: VecM = vec![2].try_into().unwrap(); + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 1, 2, 0, 0, 0]); + } + + #[test] + pub fn arr_u8_read_without_padding() { + let buf = Cursor::new(vec![2, 2, 2, 2]); + let v = <[u8; 4]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_read_with_padding() { + let buf = Cursor::new(vec![2, 0, 0, 0]); + let v = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2]); + } + + #[test] + pub fn arr_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![2, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn arr_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![2, 3, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn arr_u8_write_without_padding() { + let mut buf = vec![]; + [2u8, 2, 2, 2] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_write_with_padding() { + let mut buf = vec![]; + [2u8] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 0, 0, 0]); + } +} + +#[cfg(all(test, feature = "std"))] +mod test { + use super::*; + + #[test] + fn into_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.into_option(), None); + } + + #[test] + fn into_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.into_option(), Some(1)); + } + + #[test] + fn to_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } + + #[test] + fn depth_limited_read_write_under_the_limit_success() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(4)); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::depth(4)); + let a_back: Option>> = ReadXdr::read_xdr(&mut dlr).unwrap(); + assert_eq!(a, a_back); + } + + #[test] + fn write_over_depth_limit_fail() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(3)); + let res = a.write_xdr(&mut buf); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn read_over_depth_limit_fail() { + let read_limits = Limits::depth(3); + let write_limits = Limits::depth(5); + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), write_limits); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), read_limits); + let res: Result>>> = ReadXdr::read_xdr(&mut dlr); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn length_limited_read_write_i32() { + // Exact limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u32() { + // Exact limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_i64() { + // Exact limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u64() { + // Exact limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bool() { + // Exact limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_option() { + // Exact limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_u8() { + // Exact limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + <[u8; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_type() { + // Exact limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(12)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(13)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(13)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(11)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(11)); + assert_eq!( + <[bool; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_vec() { + // Exact limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(16)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(17)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(17)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(15)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(15)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bytes() { + // Exact limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_string() { + // Exact limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } +} + +#[cfg(all(test, not(feature = "alloc")))] +mod test { + use super::VecM; + + #[test] + fn to_option_none() { + let v: VecM = (&[]).try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = (&[1]).try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } +} + +/// UnionKey is an XDR Enum defines as: +/// +/// ```text +/// enum UnionKey { +/// ONE = 1, +/// TWO = 2, +/// OFFER = 3 +/// }; +/// ``` +/// +// enum +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[repr(i32)] +pub enum UnionKey { + One = 1, + Two = 2, + Offer = 3, +} + + impl UnionKey { + pub const VARIANTS: [UnionKey; 3] = [ UnionKey::One, +UnionKey::Two, +UnionKey::Offer, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "One", +"Two", +"Offer", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One => "One", +Self::Two => "Two", +Self::Offer => "Offer", + } + } + + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } + } + + impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } + + impl Enum for UnionKey {} + + impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } + + impl TryFrom for UnionKey { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 1 => UnionKey::One, +2 => UnionKey::Two, +3 => UnionKey::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } + + impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } + } + + impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } + + impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } + +/// Foo is an XDR Typedef defines as: +/// +/// ```text +/// typedef int Foo; +/// ``` +/// +pub type Foo = i32; + +/// MyUnionOne is an XDR NestedStruct defines as: +/// +/// ```text +/// struct { +/// int someInt; +/// } +/// ``` +/// +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct MyUnionOne { + pub some_int: i32, +} + +impl ReadXdr for MyUnionOne { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + some_int: i32::read_xdr(r)?, + }) + }) + } +} + +impl WriteXdr for MyUnionOne { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; + Ok(()) + }) + } +} + +/// MyUnionTwo is an XDR NestedStruct defines as: +/// +/// ```text +/// struct { +/// int someInt; +/// Foo foo; +/// } +/// ``` +/// +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct MyUnionTwo { + pub some_int: i32, + pub foo: i32, +} + + impl ReadXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + some_int: i32::read_xdr(r)?, +foo: i32::read_xdr(r)?, + }) + }) + } + } + + impl WriteXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; +self.foo.write_xdr(w)?; + Ok(()) + }) + } + } + +/// MyUnion is an XDR Union defines as: +/// +/// ```text +/// union MyUnion switch (UnionKey type) +/// { +/// case ONE: +/// struct { +/// int someInt; +/// } one; +/// +/// case TWO: +/// struct { +/// int someInt; +/// Foo foo; +/// } two; +/// +/// case OFFER: +/// void; +/// }; +/// ``` +/// +// union with discriminant UnionKey +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[allow(clippy::large_enum_variant)] +pub enum MyUnion { + One(MyUnionOne), + Two(MyUnionTwo), + Offer, +} + + impl MyUnion { + pub const VARIANTS: [UnionKey; 3] = [ + UnionKey::One, +UnionKey::Two, +UnionKey::Offer, + ]; + pub const VARIANTS_STR: [&'static str; 3] = [ + "One", +"Two", +"Offer", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One(_) => "One", +Self::Two(_) => "Two", +Self::Offer => "Offer", + } + } + + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::One(_) => UnionKey::One, +Self::Two(_) => UnionKey::Two, +Self::Offer => UnionKey::Offer, + } + } + + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } + } + + impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } + } + + impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } + + impl Union for MyUnion {} + + impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), +UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), +UnionKey::Offer => Self::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } + + impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::One(v) => v.write_xdr(w)?, +Self::Two(v) => v.write_xdr(w)?, +Self::Offer => ().write_xdr(w)?, + }; + Ok(()) + }) + } + } + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum TypeVariant { + UnionKey, +Foo, +MyUnion, +MyUnionOne, +MyUnionTwo, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, +TypeVariant::Foo, +TypeVariant::MyUnion, +TypeVariant::MyUnionOne, +TypeVariant::MyUnionTwo, ]; + pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", +"Foo", +"MyUnion", +"MyUnionOne", +"MyUnionTwo", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey => "UnionKey", +Self::Foo => "Foo", +Self::MyUnion => "MyUnion", +Self::MyUnionOne => "MyUnionOne", +Self::MyUnionTwo => "MyUnionTwo", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } + } + + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "UnionKey" => Ok(Self::UnionKey), +"Foo" => Ok(Self::Foo), +"MyUnion" => Ok(Self::MyUnion), +"MyUnionOne" => Ok(Self::MyUnionOne), +"MyUnionTwo" => Ok(Self::MyUnionTwo), + _ => Err(Error::Invalid), + } + } + } + + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum Type { + UnionKey(Box), +Foo(Box), +MyUnion(Box), +MyUnionOne(Box), +MyUnionTwo(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, +TypeVariant::Foo, +TypeVariant::MyUnion, +TypeVariant::MyUnionOne, +TypeVariant::MyUnionTwo, ]; + pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", +"Foo", +"MyUnion", +"MyUnionOne", +"MyUnionTwo", ]; + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), +TypeVariant::Foo => r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))), +TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), +TypeVariant::MyUnionOne => r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))), +TypeVariant::MyUnionTwo => r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))), + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t.0))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0))))), + } + } + + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } + + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), + } + } + + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::UnionKey(ref v) => v.as_ref(), +Self::Foo(ref v) => v.as_ref(), +Self::MyUnion(ref v) => v.as_ref(), +Self::MyUnionOne(ref v) => v.as_ref(), +Self::MyUnionTwo(ref v) => v.as_ref(), + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey(_) => "UnionKey", +Self::Foo(_) => "Foo", +Self::MyUnion(_) => "MyUnion", +Self::MyUnionOne(_) => "MyUnionOne", +Self::MyUnionTwo(_) => "MyUnionTwo", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::UnionKey(_) => TypeVariant::UnionKey, +Self::Foo(_) => TypeVariant::Foo, +Self::MyUnion(_) => TypeVariant::MyUnion, +Self::MyUnionOne(_) => TypeVariant::MyUnionOne, +Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, + } + } + } + + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::UnionKey(v) => v.write_xdr(w), +Self::Foo(v) => v.write_xdr(w), +Self::MyUnion(v) => v.write_xdr(w), +Self::MyUnionOne(v) => v.write_xdr(w), +Self::MyUnionTwo(v) => v.write_xdr(w), + } + } + } diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs new file mode 100644 index 000000000..3ef88298f --- /dev/null +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -0,0 +1,2975 @@ +// Module is generated from: +// spec/fixtures/generator/optional.x + +#![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] + +/// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/optional.x", "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7") +]; + +use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; + +#[cfg(feature = "std")] +use core::marker::PhantomData; + +// When feature alloc is turned off use static lifetime Box and Vec types. +#[cfg(not(feature = "alloc"))] +mod noalloc { + pub mod boxed { + pub type Box = &'static T; + } + pub mod vec { + pub type Vec = &'static [T]; + } +} +#[cfg(not(feature = "alloc"))] +use noalloc::{boxed::Box, vec::Vec}; + +// When feature std is turned off, but feature alloc is turned on import the +// alloc crate and use its Box and Vec types. +#[cfg(all(not(feature = "std"), feature = "alloc"))] +extern crate alloc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::{ + borrow::ToOwned, + boxed::Box, + string::{FromUtf8Error, String}, + vec::Vec, +}; +#[cfg(feature = "std")] +use std::string::FromUtf8Error; + +#[cfg(feature = "arbitrary")] +use arbitrary::Arbitrary; + +// TODO: Add support for read/write xdr fns when std not available. + +#[cfg(feature = "std")] +use std::{ + error, io, + io::{BufRead, BufReader, Cursor, Read, Write}, +}; + +/// Error contains all errors returned by functions in this crate. It can be +/// compared via `PartialEq`, however any contained IO errors will only be +/// compared on their `ErrorKind`. +#[derive(Debug)] +pub enum Error { + Invalid, + Unsupported, + LengthExceedsMax, + LengthMismatch, + NonZeroPadding, + Utf8Error(core::str::Utf8Error), + #[cfg(feature = "alloc")] + InvalidHex, + #[cfg(feature = "std")] + Io(io::Error), + DepthLimitExceeded, + #[cfg(feature = "serde_json")] + Json(serde_json::Error), + LengthLimitExceeded, +} + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Utf8Error(l), Self::Utf8Error(r)) => l == r, + // IO errors cannot be compared, but in the absence of any more + // meaningful way to compare the errors we compare the kind of error + // and ignore the embedded source error or OS error. The main use + // case for comparing errors outputted by the XDR library is for + // error case testing, and a lack of the ability to compare has a + // detrimental affect on failure testing, so this is a tradeoff. + #[cfg(feature = "std")] + (Self::Io(l), Self::Io(r)) => l.kind() == r.kind(), + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + #[must_use] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Io(e) => Some(e), + #[cfg(feature = "serde_json")] + Self::Json(e) => Some(e), + _ => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Invalid => write!(f, "xdr value invalid"), + Error::Unsupported => write!(f, "xdr value unsupported"), + Error::LengthExceedsMax => write!(f, "xdr value max length exceeded"), + Error::LengthMismatch => write!(f, "xdr value length does not match"), + Error::NonZeroPadding => write!(f, "xdr padding contains non-zero bytes"), + Error::Utf8Error(e) => write!(f, "{e}"), + #[cfg(feature = "alloc")] + Error::InvalidHex => write!(f, "hex invalid"), + #[cfg(feature = "std")] + Error::Io(e) => write!(f, "{e}"), + Error::DepthLimitExceeded => write!(f, "depth limit exceeded"), + #[cfg(feature = "serde_json")] + Error::Json(e) => write!(f, "{e}"), + Error::LengthLimitExceeded => write!(f, "length limit exceeded"), + } + } +} + +impl From for Error { + fn from(_: TryFromSliceError) -> Error { + Error::LengthMismatch + } +} + +impl From for Error { + #[must_use] + fn from(e: core::str::Utf8Error) -> Self { + Error::Utf8Error(e) + } +} + +#[cfg(feature = "alloc")] +impl From for Error { + #[must_use] + fn from(e: FromUtf8Error) -> Self { + Error::Utf8Error(e.utf8_error()) + } +} + +#[cfg(feature = "std")] +impl From for Error { + #[must_use] + fn from(e: io::Error) -> Self { + Error::Io(e) + } +} + +#[cfg(feature = "serde_json")] +impl From for Error { + #[must_use] + fn from(e: serde_json::Error) -> Self { + Error::Json(e) + } +} + +impl From for () { + fn from(_: Error) {} +} + +#[allow(dead_code)] +type Result = core::result::Result; + +/// Name defines types that assign a static name to their value, such as the +/// name given to an identifier in an XDR enum, or the name given to the case in +/// a union. +pub trait Name { + fn name(&self) -> &'static str; +} + +/// Discriminant defines types that may contain a one-of value determined +/// according to the discriminant, and exposes the value of the discriminant for +/// that type, such as in an XDR union. +pub trait Discriminant { + fn discriminant(&self) -> D; +} + +/// Iter defines types that have variants that can be iterated. +pub trait Variants { + fn variants() -> slice::Iter<'static, V> + where + V: Sized; +} + +// Enum defines a type that is represented as an XDR enumeration when encoded. +pub trait Enum: Name + Variants + Sized {} + +// Union defines a type that is represented as an XDR union when encoded. +pub trait Union: Name + Discriminant + Variants +where + D: Sized, +{ +} + +/// `Limits` contains the limits that a limited reader or writer will be +/// constrained to. +#[cfg(feature = "std")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Limits { + /// Defines the maximum depth for recursive calls in `Read/WriteXdr` to + /// prevent stack overflow. + /// + /// The depth limit is akin to limiting stack depth. Its purpose is to + /// prevent the program from hitting the maximum stack size allowed by Rust, + /// which would result in an unrecoverable `SIGABRT`. For more information + /// about Rust's stack size limit, refer to the [Rust + /// documentation](https://doc.rust-lang.org/std/thread/#stack-size). + pub depth: u32, + + /// Defines the maximum number of bytes that will be read or written. + pub len: usize, +} + +#[cfg(feature = "std")] +impl Limits { + #[must_use] + pub fn none() -> Self { + Self { + depth: u32::MAX, + len: usize::MAX, + } + } + + #[must_use] + pub fn depth(depth: u32) -> Self { + Limits { + depth, + ..Limits::none() + } + } + + #[must_use] + pub fn len(len: usize) -> Self { + Limits { + len, + ..Limits::none() + } + } +} + +/// `Limited` wraps an object and provides functions for enforcing limits. +/// +/// Intended for use with readers and writers and limiting their reads and +/// writes. +#[cfg(feature = "std")] +pub struct Limited { + pub inner: L, + pub(crate) limits: Limits, +} + +#[cfg(feature = "std")] +impl Limited { + /// Constructs a new `Limited`. + /// + /// - `inner`: The value being limited. + /// - `limits`: The limits to enforce. + pub fn new(inner: L, limits: Limits) -> Self { + Limited { inner, limits } + } + + /// Consume the given length from the internal remaining length limit. + /// + /// ### Errors + /// + /// If the length would consume more length than the remaining length limit + /// allows. + pub(crate) fn consume_len(&mut self, len: usize) -> Result<()> { + if let Some(len) = self.limits.len.checked_sub(len) { + self.limits.len = len; + Ok(()) + } else { + Err(Error::LengthLimitExceeded) + } + } + + /// Consumes a single depth for the duration of the given function. + /// + /// ### Errors + /// + /// If the depth limit is already exhausted. + pub(crate) fn with_limited_depth(&mut self, f: F) -> Result + where + F: FnOnce(&mut Self) -> Result, + { + if let Some(depth) = self.limits.depth.checked_sub(1) { + self.limits.depth = depth; + let res = f(self); + self.limits.depth = self.limits.depth.saturating_add(1); + res + } else { + Err(Error::DepthLimitExceeded) + } + } +} + +#[cfg(feature = "std")] +impl Read for Limited { + /// Forwards the read operation to the wrapped object. + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.inner.read(buf) + } +} + +#[cfg(feature = "std")] +impl BufRead for Limited { + /// Forwards the read operation to the wrapped object. + fn fill_buf(&mut self) -> std::io::Result<&[u8]> { + self.inner.fill_buf() + } + + /// Forwards the read operation to the wrapped object. + fn consume(&mut self, amt: usize) { + self.inner.consume(amt); + } +} + +#[cfg(feature = "std")] +impl Write for Limited { + /// Forwards the write operation to the wrapped object. + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.inner.write(buf) + } + + /// Forwards the flush operation to the wrapped object. + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } +} + +#[cfg(feature = "std")] +pub struct ReadXdrIter { + reader: Limited>, + _s: PhantomData, +} + +#[cfg(feature = "std")] +impl ReadXdrIter { + fn new(r: R, limits: Limits) -> Self { + Self { + reader: Limited { + inner: BufReader::new(r), + limits, + }, + _s: PhantomData, + } + } +} + +#[cfg(feature = "std")] +impl Iterator for ReadXdrIter { + type Item = Result; + + // Next reads the internal reader and XDR decodes it into the Self type. If + // the EOF is reached without reading any new bytes `None` is returned. If + // EOF is reached after reading some bytes a truncated entry is assumed an + // an `Error::Io` containing an `UnexpectedEof`. If any other IO error + // occurs it is returned. Iteration of this iterator stops naturally when + // `None` is returned, but not when a `Some(Err(...))` is returned. The + // caller is responsible for checking each Result. + fn next(&mut self) -> Option { + // Try to fill the buffer to see if the EOF has been reached or not. + // This happens to effectively peek to see if the stream has finished + // and there are no more items. It is necessary to do this because the + // xdr types in this crate heavily use the `std::io::Read::read_exact` + // method that doesn't distinguish between an EOF at the beginning of a + // read and an EOF after a partial fill of a read_exact. + match self.reader.fill_buf() { + // If the reader has no more data and is unable to fill any new data + // into its internal buf, then the EOF has been reached. + Ok([]) => return None, + // If an error occurs filling the buffer, treat that as an error and stop. + Err(e) => return Some(Err(Error::Io(e))), + // If there is data in the buf available for reading, continue. + Ok([..]) => (), + }; + // Read the buf into the type. + let r = self.reader.with_limited_depth(|dlr| S::read_xdr(dlr)); + match r { + Ok(s) => Some(Ok(s)), + Err(e) => Some(Err(e)), + } + } +} + +pub trait ReadXdr +where + Self: Sized, +{ + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_to_end`] when the intent is for all bytes in the + /// read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result; + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_to_end(r: &mut Limited) -> Result { + let s = Self::read_xdr(r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64_to_end(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_into_to_end`] when the intent is for all bytes + /// in the read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr_into(&mut self, r: &mut Limited) -> Result<()> { + *self = Self::read_xdr(r)?; + Ok(()) + } + + /// Read the XDR into the existing value, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_into_to_end(&mut self, r: &mut Limited) -> Result<()> { + Self::read_xdr_into(self, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(()) + } else { + Err(Error::Invalid) + } + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_iter(r: &mut Limited) -> ReadXdrIter<&mut R, Self> { + ReadXdrIter::new(&mut r.inner, r.limits.clone()) + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + #[cfg(feature = "base64")] + fn read_xdr_base64_iter( + r: &mut Limited, + ) -> ReadXdrIter, Self> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + ReadXdrIter::new(dec, r.limits.clone()) + } + + /// Construct the type from the XDR bytes. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "std")] + fn from_xdr(bytes: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(&mut cursor)?; + Ok(t) + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn from_xdr_base64(b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } +} + +pub trait WriteXdr { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()>; + + #[cfg(feature = "std")] + fn to_xdr(&self, limits: Limits) -> Result> { + let mut cursor = Limited::new(Cursor::new(vec![]), limits); + self.write_xdr(&mut cursor)?; + let bytes = cursor.inner.into_inner(); + Ok(bytes) + } + + #[cfg(feature = "base64")] + fn to_xdr_base64(&self, limits: Limits) -> Result { + let mut enc = Limited::new( + base64::write::EncoderStringWriter::new(base64::STANDARD), + limits, + ); + self.write_xdr(&mut enc)?; + let b64 = enc.inner.into_inner(); + Ok(b64) + } +} + +/// `Pad_len` returns the number of bytes to pad an XDR value of the given +/// length to make the final serialized size a multiple of 4. +#[cfg(feature = "std")] +fn pad_len(len: usize) -> usize { + (4 - (len % 4)) % 4 +} + +impl ReadXdr for i32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for i64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for f32 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f32 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for f64 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f64 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for bool { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + let b = i == 1; + Ok(b) + }) + } +} + +impl WriteXdr for bool { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i = u32::from(*self); // true = 1, false = 0 + i.write_xdr(w) + }) + } +} + +impl ReadXdr for Option { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + match i { + 0 => Ok(None), + 1 => { + let t = T::read_xdr(r)?; + Ok(Some(t)) + } + _ => Err(Error::Invalid), + } + }) + } +} + +impl WriteXdr for Option { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + if let Some(t) = self { + 1u32.write_xdr(w)?; + t.write_xdr(w)?; + } else { + 0u32.write_xdr(w)?; + } + Ok(()) + }) + } +} + +impl ReadXdr for Box { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| Ok(Box::new(T::read_xdr(r)?))) + } +} + +impl WriteXdr for Box { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| T::write_xdr(self, w)) + } +} + +impl ReadXdr for () { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + Ok(()) + } +} + +impl WriteXdr for () { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + Ok(()) + } +} + +impl ReadXdr for [u8; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + r.consume_len(N)?; + let padding = pad_len(N); + r.consume_len(padding)?; + let mut arr = [0u8; N]; + r.read_exact(&mut arr)?; + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + Ok(arr) + }) + } +} + +impl WriteXdr for [u8; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + w.consume_len(N)?; + let padding = pad_len(N); + w.consume_len(padding)?; + w.write_all(self)?; + w.write_all(&[0u8; 3][..padding])?; + Ok(()) + }) + } +} + +impl ReadXdr for [T; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let mut vec = Vec::with_capacity(N); + for _ in 0..N { + let t = T::read_xdr(r)?; + vec.push(t); + } + let arr: [T; N] = vec.try_into().unwrap_or_else(|_: Vec| unreachable!()); + Ok(arr) + }) + } +} + +impl WriteXdr for [T; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + for t in self { + t.write_xdr(w)?; + } + Ok(()) + }) + } +} + +// VecM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec) +where + T: 'static; + +impl Deref for VecM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for VecM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl VecM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl VecM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl VecM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl VecM { + #[must_use] + pub fn to_option(&self) -> Option { + if self.len() > 0 { + Some(self.0[0].clone()) + } else { + None + } + } +} + +#[cfg(not(feature = "alloc"))] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.to_option() + } +} + +#[cfg(feature = "alloc")] +impl VecM { + #[must_use] + pub fn into_option(mut self) -> Option { + self.0.drain(..).next() + } +} + +#[cfg(feature = "alloc")] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.into_option() + } +} + +impl TryFrom> for VecM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: VecM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&VecM> for Vec { + #[must_use] + fn from(v: &VecM) -> Self { + v.0.clone() + } +} + +impl AsRef> for VecM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for VecM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T]> for VecM { + type Error = Error; + + fn try_from(v: &[T]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[T]> for VecM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[T; N]> for VecM { + type Error = Error; + + fn try_from(v: [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [T; N] { + type Error = VecM; + + fn try_from(v: VecM) -> core::result::Result { + let s: [T; N] = v.0.try_into().map_err(|v: Vec| VecM::(v))?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T; N]> for VecM { + type Error = Error; + + fn try_from(v: &[T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [T; N]> for VecM { + type Error = Error; + + fn try_from(v: &'static [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for VecM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for VecM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: VecM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&VecM> for String { + type Error = Error; + + fn try_from(v: &VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for VecM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for VecM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a VecM> for &'a str { + type Error = Error; + + fn try_from(v: &'a VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + let mut vec = Vec::new(); + for _ in 0..len { + let t = T::read_xdr(r)?; + vec.push(t); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + for t in &self.0 { + t.write_xdr(w)?; + } + + Ok(()) + }) + } +} + +// BytesM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +impl core::fmt::Display for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +impl core::fmt::Debug for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "BytesM(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for BytesM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} + +impl Deref for BytesM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for BytesM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl BytesM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl BytesM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl BytesM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for BytesM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: BytesM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&BytesM> for Vec { + #[must_use] + fn from(v: &BytesM) -> Self { + v.0.clone() + } +} + +impl AsRef> for BytesM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for BytesM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for BytesM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = BytesM; + + fn try_from(v: BytesM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(BytesM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for BytesM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for BytesM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: BytesM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&BytesM> for String { + type Error = Error; + + fn try_from(v: &BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for BytesM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for BytesM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a BytesM> for &'a str { + type Error = Error; + + fn try_from(v: &'a BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for BytesM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(BytesM(vec)) + }) + } +} + +impl WriteXdr for BytesM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..pad_len(len as usize)])?; + + Ok(()) + }) + } +} + +// StringM ------------------------------------------------------------------------ + +/// A string type that contains arbitrary bytes. +/// +/// Convertible, fallibly, to/from a Rust UTF-8 String using +/// [`TryFrom`]/[`TryInto`]/[`StringM::to_utf8_string`]. +/// +/// Convertible, lossyly, to a Rust UTF-8 String using +/// [`StringM::to_utf8_string_lossy`]. +/// +/// Convertible to/from escaped printable-ASCII using +/// [`Display`]/[`ToString`]/[`FromStr`]. + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +impl core::fmt::Display for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + Ok(()) + } +} + +impl core::fmt::Debug for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "StringM(")?; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for StringM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?; + Ok(Self(b)) + } +} + +impl Deref for StringM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for StringM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl StringM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl StringM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl StringM { + #[cfg(feature = "alloc")] + pub fn to_utf8_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_utf8_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_utf8_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_utf8_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for StringM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: StringM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&StringM> for Vec { + #[must_use] + fn from(v: &StringM) -> Self { + v.0.clone() + } +} + +impl AsRef> for StringM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for StringM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for StringM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for StringM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = StringM; + + fn try_from(v: StringM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(StringM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for StringM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for StringM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: StringM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&StringM> for String { + type Error = Error; + + fn try_from(v: &StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for StringM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for StringM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a StringM> for &'a str { + type Error = Error; + + fn try_from(v: &'a StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for StringM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(StringM(vec)) + }) + } +} + +impl WriteXdr for StringM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +// Frame ------------------------------------------------------------------------ + +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Frame(pub T) +where + T: ReadXdr; + +impl ReadXdr for Frame +where + T: ReadXdr, +{ + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + // Read the frame header value that contains 1 flag-bit and a 33-bit length. + // - The 1 flag bit is 0 when there are more frames for the same record. + // - The 31-bit length is the length of the bytes within the frame that + // follow the frame header. + let header = u32::read_xdr(r)?; + // TODO: Use the length and cap the length we'll read from `r`. + let last_record = header >> 31 == 1; + if last_record { + // Read the record in the frame. + Ok(Self(T::read_xdr(r)?)) + } else { + // TODO: Support reading those additional frames for the same + // record. + Err(Error::Unsupported) + } + } +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + pub fn vec_u8_read_without_padding() { + let buf = Cursor::new(vec![0, 0, 0, 4, 2, 2, 2, 2]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_read_with_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0, 0]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2]); + } + + #[test] + pub fn vec_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn vec_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 3, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn vec_u8_write_without_padding() { + let mut buf = vec![]; + let v: VecM = vec![2, 2, 2, 2].try_into().unwrap(); + + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 4, 2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_write_with_padding() { + let mut buf = vec![]; + let v: VecM = vec![2].try_into().unwrap(); + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 1, 2, 0, 0, 0]); + } + + #[test] + pub fn arr_u8_read_without_padding() { + let buf = Cursor::new(vec![2, 2, 2, 2]); + let v = <[u8; 4]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_read_with_padding() { + let buf = Cursor::new(vec![2, 0, 0, 0]); + let v = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2]); + } + + #[test] + pub fn arr_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![2, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn arr_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![2, 3, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn arr_u8_write_without_padding() { + let mut buf = vec![]; + [2u8, 2, 2, 2] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_write_with_padding() { + let mut buf = vec![]; + [2u8] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 0, 0, 0]); + } +} + +#[cfg(all(test, feature = "std"))] +mod test { + use super::*; + + #[test] + fn into_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.into_option(), None); + } + + #[test] + fn into_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.into_option(), Some(1)); + } + + #[test] + fn to_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } + + #[test] + fn depth_limited_read_write_under_the_limit_success() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(4)); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::depth(4)); + let a_back: Option>> = ReadXdr::read_xdr(&mut dlr).unwrap(); + assert_eq!(a, a_back); + } + + #[test] + fn write_over_depth_limit_fail() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(3)); + let res = a.write_xdr(&mut buf); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn read_over_depth_limit_fail() { + let read_limits = Limits::depth(3); + let write_limits = Limits::depth(5); + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), write_limits); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), read_limits); + let res: Result>>> = ReadXdr::read_xdr(&mut dlr); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn length_limited_read_write_i32() { + // Exact limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u32() { + // Exact limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_i64() { + // Exact limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u64() { + // Exact limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bool() { + // Exact limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_option() { + // Exact limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_u8() { + // Exact limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + <[u8; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_type() { + // Exact limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(12)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(13)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(13)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(11)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(11)); + assert_eq!( + <[bool; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_vec() { + // Exact limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(16)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(17)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(17)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(15)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(15)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bytes() { + // Exact limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_string() { + // Exact limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } +} + +#[cfg(all(test, not(feature = "alloc")))] +mod test { + use super::VecM; + + #[test] + fn to_option_none() { + let v: VecM = (&[]).try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = (&[1]).try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } +} + +/// Arr is an XDR Typedef defines as: +/// +/// ```text +/// typedef int Arr[2]; +/// ``` +/// +pub type Arr = [i32; 2]; + +/// HasOptions is an XDR Struct defines as: +/// +/// ```text +/// struct HasOptions +/// { +/// int* firstOption; +/// int *secondOption; +/// Arr *thirdOption; +/// }; +/// ``` +/// +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +pub struct HasOptions { + pub first_option: Option, + pub second_option: Option, + pub third_option: Option, +} + + impl ReadXdr for HasOptions { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + first_option: Option::::read_xdr(r)?, +second_option: Option::::read_xdr(r)?, +third_option: Option::::read_xdr(r)?, + }) + }) + } + } + + impl WriteXdr for HasOptions { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.first_option.write_xdr(w)?; +self.second_option.write_xdr(w)?; +self.third_option.write_xdr(w)?; + Ok(()) + }) + } + } + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum TypeVariant { + Arr, +HasOptions, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, +TypeVariant::HasOptions, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", +"HasOptions", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr => "Arr", +Self::HasOptions => "HasOptions", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + } + + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Arr" => Ok(Self::Arr), +"HasOptions" => Ok(Self::HasOptions), + _ => Err(Error::Invalid), + } + } + } + + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum Type { + Arr(Box), +HasOptions(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, +TypeVariant::HasOptions, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", +"HasOptions", ]; + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Arr => r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))), +TypeVariant::HasOptions => r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))), + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t.0))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t.0))))), + } + } + + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } + + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), +TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), + } + } + + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Arr(ref v) => v.as_ref(), +Self::HasOptions(ref v) => v.as_ref(), + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr(_) => "Arr", +Self::HasOptions(_) => "HasOptions", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Arr(_) => TypeVariant::Arr, +Self::HasOptions(_) => TypeVariant::HasOptions, + } + } + } + + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Arr(v) => v.write_xdr(w), +Self::HasOptions(v) => v.write_xdr(w), + } + } + } diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs new file mode 100644 index 000000000..5d9aaaa54 --- /dev/null +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -0,0 +1,2983 @@ +// Module is generated from: +// spec/fixtures/generator/struct.x + +#![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] + +/// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/struct.x", "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a") +]; + +use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; + +#[cfg(feature = "std")] +use core::marker::PhantomData; + +// When feature alloc is turned off use static lifetime Box and Vec types. +#[cfg(not(feature = "alloc"))] +mod noalloc { + pub mod boxed { + pub type Box = &'static T; + } + pub mod vec { + pub type Vec = &'static [T]; + } +} +#[cfg(not(feature = "alloc"))] +use noalloc::{boxed::Box, vec::Vec}; + +// When feature std is turned off, but feature alloc is turned on import the +// alloc crate and use its Box and Vec types. +#[cfg(all(not(feature = "std"), feature = "alloc"))] +extern crate alloc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::{ + borrow::ToOwned, + boxed::Box, + string::{FromUtf8Error, String}, + vec::Vec, +}; +#[cfg(feature = "std")] +use std::string::FromUtf8Error; + +#[cfg(feature = "arbitrary")] +use arbitrary::Arbitrary; + +// TODO: Add support for read/write xdr fns when std not available. + +#[cfg(feature = "std")] +use std::{ + error, io, + io::{BufRead, BufReader, Cursor, Read, Write}, +}; + +/// Error contains all errors returned by functions in this crate. It can be +/// compared via `PartialEq`, however any contained IO errors will only be +/// compared on their `ErrorKind`. +#[derive(Debug)] +pub enum Error { + Invalid, + Unsupported, + LengthExceedsMax, + LengthMismatch, + NonZeroPadding, + Utf8Error(core::str::Utf8Error), + #[cfg(feature = "alloc")] + InvalidHex, + #[cfg(feature = "std")] + Io(io::Error), + DepthLimitExceeded, + #[cfg(feature = "serde_json")] + Json(serde_json::Error), + LengthLimitExceeded, +} + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Utf8Error(l), Self::Utf8Error(r)) => l == r, + // IO errors cannot be compared, but in the absence of any more + // meaningful way to compare the errors we compare the kind of error + // and ignore the embedded source error or OS error. The main use + // case for comparing errors outputted by the XDR library is for + // error case testing, and a lack of the ability to compare has a + // detrimental affect on failure testing, so this is a tradeoff. + #[cfg(feature = "std")] + (Self::Io(l), Self::Io(r)) => l.kind() == r.kind(), + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + #[must_use] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Io(e) => Some(e), + #[cfg(feature = "serde_json")] + Self::Json(e) => Some(e), + _ => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Invalid => write!(f, "xdr value invalid"), + Error::Unsupported => write!(f, "xdr value unsupported"), + Error::LengthExceedsMax => write!(f, "xdr value max length exceeded"), + Error::LengthMismatch => write!(f, "xdr value length does not match"), + Error::NonZeroPadding => write!(f, "xdr padding contains non-zero bytes"), + Error::Utf8Error(e) => write!(f, "{e}"), + #[cfg(feature = "alloc")] + Error::InvalidHex => write!(f, "hex invalid"), + #[cfg(feature = "std")] + Error::Io(e) => write!(f, "{e}"), + Error::DepthLimitExceeded => write!(f, "depth limit exceeded"), + #[cfg(feature = "serde_json")] + Error::Json(e) => write!(f, "{e}"), + Error::LengthLimitExceeded => write!(f, "length limit exceeded"), + } + } +} + +impl From for Error { + fn from(_: TryFromSliceError) -> Error { + Error::LengthMismatch + } +} + +impl From for Error { + #[must_use] + fn from(e: core::str::Utf8Error) -> Self { + Error::Utf8Error(e) + } +} + +#[cfg(feature = "alloc")] +impl From for Error { + #[must_use] + fn from(e: FromUtf8Error) -> Self { + Error::Utf8Error(e.utf8_error()) + } +} + +#[cfg(feature = "std")] +impl From for Error { + #[must_use] + fn from(e: io::Error) -> Self { + Error::Io(e) + } +} + +#[cfg(feature = "serde_json")] +impl From for Error { + #[must_use] + fn from(e: serde_json::Error) -> Self { + Error::Json(e) + } +} + +impl From for () { + fn from(_: Error) {} +} + +#[allow(dead_code)] +type Result = core::result::Result; + +/// Name defines types that assign a static name to their value, such as the +/// name given to an identifier in an XDR enum, or the name given to the case in +/// a union. +pub trait Name { + fn name(&self) -> &'static str; +} + +/// Discriminant defines types that may contain a one-of value determined +/// according to the discriminant, and exposes the value of the discriminant for +/// that type, such as in an XDR union. +pub trait Discriminant { + fn discriminant(&self) -> D; +} + +/// Iter defines types that have variants that can be iterated. +pub trait Variants { + fn variants() -> slice::Iter<'static, V> + where + V: Sized; +} + +// Enum defines a type that is represented as an XDR enumeration when encoded. +pub trait Enum: Name + Variants + Sized {} + +// Union defines a type that is represented as an XDR union when encoded. +pub trait Union: Name + Discriminant + Variants +where + D: Sized, +{ +} + +/// `Limits` contains the limits that a limited reader or writer will be +/// constrained to. +#[cfg(feature = "std")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Limits { + /// Defines the maximum depth for recursive calls in `Read/WriteXdr` to + /// prevent stack overflow. + /// + /// The depth limit is akin to limiting stack depth. Its purpose is to + /// prevent the program from hitting the maximum stack size allowed by Rust, + /// which would result in an unrecoverable `SIGABRT`. For more information + /// about Rust's stack size limit, refer to the [Rust + /// documentation](https://doc.rust-lang.org/std/thread/#stack-size). + pub depth: u32, + + /// Defines the maximum number of bytes that will be read or written. + pub len: usize, +} + +#[cfg(feature = "std")] +impl Limits { + #[must_use] + pub fn none() -> Self { + Self { + depth: u32::MAX, + len: usize::MAX, + } + } + + #[must_use] + pub fn depth(depth: u32) -> Self { + Limits { + depth, + ..Limits::none() + } + } + + #[must_use] + pub fn len(len: usize) -> Self { + Limits { + len, + ..Limits::none() + } + } +} + +/// `Limited` wraps an object and provides functions for enforcing limits. +/// +/// Intended for use with readers and writers and limiting their reads and +/// writes. +#[cfg(feature = "std")] +pub struct Limited { + pub inner: L, + pub(crate) limits: Limits, +} + +#[cfg(feature = "std")] +impl Limited { + /// Constructs a new `Limited`. + /// + /// - `inner`: The value being limited. + /// - `limits`: The limits to enforce. + pub fn new(inner: L, limits: Limits) -> Self { + Limited { inner, limits } + } + + /// Consume the given length from the internal remaining length limit. + /// + /// ### Errors + /// + /// If the length would consume more length than the remaining length limit + /// allows. + pub(crate) fn consume_len(&mut self, len: usize) -> Result<()> { + if let Some(len) = self.limits.len.checked_sub(len) { + self.limits.len = len; + Ok(()) + } else { + Err(Error::LengthLimitExceeded) + } + } + + /// Consumes a single depth for the duration of the given function. + /// + /// ### Errors + /// + /// If the depth limit is already exhausted. + pub(crate) fn with_limited_depth(&mut self, f: F) -> Result + where + F: FnOnce(&mut Self) -> Result, + { + if let Some(depth) = self.limits.depth.checked_sub(1) { + self.limits.depth = depth; + let res = f(self); + self.limits.depth = self.limits.depth.saturating_add(1); + res + } else { + Err(Error::DepthLimitExceeded) + } + } +} + +#[cfg(feature = "std")] +impl Read for Limited { + /// Forwards the read operation to the wrapped object. + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.inner.read(buf) + } +} + +#[cfg(feature = "std")] +impl BufRead for Limited { + /// Forwards the read operation to the wrapped object. + fn fill_buf(&mut self) -> std::io::Result<&[u8]> { + self.inner.fill_buf() + } + + /// Forwards the read operation to the wrapped object. + fn consume(&mut self, amt: usize) { + self.inner.consume(amt); + } +} + +#[cfg(feature = "std")] +impl Write for Limited { + /// Forwards the write operation to the wrapped object. + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.inner.write(buf) + } + + /// Forwards the flush operation to the wrapped object. + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } +} + +#[cfg(feature = "std")] +pub struct ReadXdrIter { + reader: Limited>, + _s: PhantomData, +} + +#[cfg(feature = "std")] +impl ReadXdrIter { + fn new(r: R, limits: Limits) -> Self { + Self { + reader: Limited { + inner: BufReader::new(r), + limits, + }, + _s: PhantomData, + } + } +} + +#[cfg(feature = "std")] +impl Iterator for ReadXdrIter { + type Item = Result; + + // Next reads the internal reader and XDR decodes it into the Self type. If + // the EOF is reached without reading any new bytes `None` is returned. If + // EOF is reached after reading some bytes a truncated entry is assumed an + // an `Error::Io` containing an `UnexpectedEof`. If any other IO error + // occurs it is returned. Iteration of this iterator stops naturally when + // `None` is returned, but not when a `Some(Err(...))` is returned. The + // caller is responsible for checking each Result. + fn next(&mut self) -> Option { + // Try to fill the buffer to see if the EOF has been reached or not. + // This happens to effectively peek to see if the stream has finished + // and there are no more items. It is necessary to do this because the + // xdr types in this crate heavily use the `std::io::Read::read_exact` + // method that doesn't distinguish between an EOF at the beginning of a + // read and an EOF after a partial fill of a read_exact. + match self.reader.fill_buf() { + // If the reader has no more data and is unable to fill any new data + // into its internal buf, then the EOF has been reached. + Ok([]) => return None, + // If an error occurs filling the buffer, treat that as an error and stop. + Err(e) => return Some(Err(Error::Io(e))), + // If there is data in the buf available for reading, continue. + Ok([..]) => (), + }; + // Read the buf into the type. + let r = self.reader.with_limited_depth(|dlr| S::read_xdr(dlr)); + match r { + Ok(s) => Some(Ok(s)), + Err(e) => Some(Err(e)), + } + } +} + +pub trait ReadXdr +where + Self: Sized, +{ + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_to_end`] when the intent is for all bytes in the + /// read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result; + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_to_end(r: &mut Limited) -> Result { + let s = Self::read_xdr(r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64_to_end(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_into_to_end`] when the intent is for all bytes + /// in the read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr_into(&mut self, r: &mut Limited) -> Result<()> { + *self = Self::read_xdr(r)?; + Ok(()) + } + + /// Read the XDR into the existing value, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_into_to_end(&mut self, r: &mut Limited) -> Result<()> { + Self::read_xdr_into(self, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(()) + } else { + Err(Error::Invalid) + } + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_iter(r: &mut Limited) -> ReadXdrIter<&mut R, Self> { + ReadXdrIter::new(&mut r.inner, r.limits.clone()) + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + #[cfg(feature = "base64")] + fn read_xdr_base64_iter( + r: &mut Limited, + ) -> ReadXdrIter, Self> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + ReadXdrIter::new(dec, r.limits.clone()) + } + + /// Construct the type from the XDR bytes. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "std")] + fn from_xdr(bytes: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(&mut cursor)?; + Ok(t) + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn from_xdr_base64(b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } +} + +pub trait WriteXdr { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()>; + + #[cfg(feature = "std")] + fn to_xdr(&self, limits: Limits) -> Result> { + let mut cursor = Limited::new(Cursor::new(vec![]), limits); + self.write_xdr(&mut cursor)?; + let bytes = cursor.inner.into_inner(); + Ok(bytes) + } + + #[cfg(feature = "base64")] + fn to_xdr_base64(&self, limits: Limits) -> Result { + let mut enc = Limited::new( + base64::write::EncoderStringWriter::new(base64::STANDARD), + limits, + ); + self.write_xdr(&mut enc)?; + let b64 = enc.inner.into_inner(); + Ok(b64) + } +} + +/// `Pad_len` returns the number of bytes to pad an XDR value of the given +/// length to make the final serialized size a multiple of 4. +#[cfg(feature = "std")] +fn pad_len(len: usize) -> usize { + (4 - (len % 4)) % 4 +} + +impl ReadXdr for i32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for i64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for f32 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f32 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for f64 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f64 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for bool { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + let b = i == 1; + Ok(b) + }) + } +} + +impl WriteXdr for bool { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i = u32::from(*self); // true = 1, false = 0 + i.write_xdr(w) + }) + } +} + +impl ReadXdr for Option { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + match i { + 0 => Ok(None), + 1 => { + let t = T::read_xdr(r)?; + Ok(Some(t)) + } + _ => Err(Error::Invalid), + } + }) + } +} + +impl WriteXdr for Option { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + if let Some(t) = self { + 1u32.write_xdr(w)?; + t.write_xdr(w)?; + } else { + 0u32.write_xdr(w)?; + } + Ok(()) + }) + } +} + +impl ReadXdr for Box { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| Ok(Box::new(T::read_xdr(r)?))) + } +} + +impl WriteXdr for Box { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| T::write_xdr(self, w)) + } +} + +impl ReadXdr for () { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + Ok(()) + } +} + +impl WriteXdr for () { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + Ok(()) + } +} + +impl ReadXdr for [u8; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + r.consume_len(N)?; + let padding = pad_len(N); + r.consume_len(padding)?; + let mut arr = [0u8; N]; + r.read_exact(&mut arr)?; + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + Ok(arr) + }) + } +} + +impl WriteXdr for [u8; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + w.consume_len(N)?; + let padding = pad_len(N); + w.consume_len(padding)?; + w.write_all(self)?; + w.write_all(&[0u8; 3][..padding])?; + Ok(()) + }) + } +} + +impl ReadXdr for [T; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let mut vec = Vec::with_capacity(N); + for _ in 0..N { + let t = T::read_xdr(r)?; + vec.push(t); + } + let arr: [T; N] = vec.try_into().unwrap_or_else(|_: Vec| unreachable!()); + Ok(arr) + }) + } +} + +impl WriteXdr for [T; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + for t in self { + t.write_xdr(w)?; + } + Ok(()) + }) + } +} + +// VecM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec) +where + T: 'static; + +impl Deref for VecM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for VecM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl VecM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl VecM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl VecM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl VecM { + #[must_use] + pub fn to_option(&self) -> Option { + if self.len() > 0 { + Some(self.0[0].clone()) + } else { + None + } + } +} + +#[cfg(not(feature = "alloc"))] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.to_option() + } +} + +#[cfg(feature = "alloc")] +impl VecM { + #[must_use] + pub fn into_option(mut self) -> Option { + self.0.drain(..).next() + } +} + +#[cfg(feature = "alloc")] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.into_option() + } +} + +impl TryFrom> for VecM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: VecM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&VecM> for Vec { + #[must_use] + fn from(v: &VecM) -> Self { + v.0.clone() + } +} + +impl AsRef> for VecM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for VecM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T]> for VecM { + type Error = Error; + + fn try_from(v: &[T]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[T]> for VecM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[T; N]> for VecM { + type Error = Error; + + fn try_from(v: [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [T; N] { + type Error = VecM; + + fn try_from(v: VecM) -> core::result::Result { + let s: [T; N] = v.0.try_into().map_err(|v: Vec| VecM::(v))?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T; N]> for VecM { + type Error = Error; + + fn try_from(v: &[T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [T; N]> for VecM { + type Error = Error; + + fn try_from(v: &'static [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for VecM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for VecM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: VecM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&VecM> for String { + type Error = Error; + + fn try_from(v: &VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for VecM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for VecM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a VecM> for &'a str { + type Error = Error; + + fn try_from(v: &'a VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + let mut vec = Vec::new(); + for _ in 0..len { + let t = T::read_xdr(r)?; + vec.push(t); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + for t in &self.0 { + t.write_xdr(w)?; + } + + Ok(()) + }) + } +} + +// BytesM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +impl core::fmt::Display for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +impl core::fmt::Debug for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "BytesM(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for BytesM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} + +impl Deref for BytesM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for BytesM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl BytesM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl BytesM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl BytesM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for BytesM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: BytesM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&BytesM> for Vec { + #[must_use] + fn from(v: &BytesM) -> Self { + v.0.clone() + } +} + +impl AsRef> for BytesM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for BytesM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for BytesM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = BytesM; + + fn try_from(v: BytesM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(BytesM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for BytesM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for BytesM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: BytesM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&BytesM> for String { + type Error = Error; + + fn try_from(v: &BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for BytesM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for BytesM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a BytesM> for &'a str { + type Error = Error; + + fn try_from(v: &'a BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for BytesM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(BytesM(vec)) + }) + } +} + +impl WriteXdr for BytesM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..pad_len(len as usize)])?; + + Ok(()) + }) + } +} + +// StringM ------------------------------------------------------------------------ + +/// A string type that contains arbitrary bytes. +/// +/// Convertible, fallibly, to/from a Rust UTF-8 String using +/// [`TryFrom`]/[`TryInto`]/[`StringM::to_utf8_string`]. +/// +/// Convertible, lossyly, to a Rust UTF-8 String using +/// [`StringM::to_utf8_string_lossy`]. +/// +/// Convertible to/from escaped printable-ASCII using +/// [`Display`]/[`ToString`]/[`FromStr`]. + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +impl core::fmt::Display for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + Ok(()) + } +} + +impl core::fmt::Debug for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "StringM(")?; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for StringM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?; + Ok(Self(b)) + } +} + +impl Deref for StringM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for StringM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl StringM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl StringM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl StringM { + #[cfg(feature = "alloc")] + pub fn to_utf8_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_utf8_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_utf8_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_utf8_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for StringM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: StringM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&StringM> for Vec { + #[must_use] + fn from(v: &StringM) -> Self { + v.0.clone() + } +} + +impl AsRef> for StringM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for StringM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for StringM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for StringM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = StringM; + + fn try_from(v: StringM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(StringM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for StringM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for StringM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: StringM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&StringM> for String { + type Error = Error; + + fn try_from(v: &StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for StringM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for StringM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a StringM> for &'a str { + type Error = Error; + + fn try_from(v: &'a StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for StringM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(StringM(vec)) + }) + } +} + +impl WriteXdr for StringM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +// Frame ------------------------------------------------------------------------ + +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Frame(pub T) +where + T: ReadXdr; + +impl ReadXdr for Frame +where + T: ReadXdr, +{ + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + // Read the frame header value that contains 1 flag-bit and a 33-bit length. + // - The 1 flag bit is 0 when there are more frames for the same record. + // - The 31-bit length is the length of the bytes within the frame that + // follow the frame header. + let header = u32::read_xdr(r)?; + // TODO: Use the length and cap the length we'll read from `r`. + let last_record = header >> 31 == 1; + if last_record { + // Read the record in the frame. + Ok(Self(T::read_xdr(r)?)) + } else { + // TODO: Support reading those additional frames for the same + // record. + Err(Error::Unsupported) + } + } +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + pub fn vec_u8_read_without_padding() { + let buf = Cursor::new(vec![0, 0, 0, 4, 2, 2, 2, 2]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_read_with_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0, 0]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2]); + } + + #[test] + pub fn vec_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn vec_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 3, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn vec_u8_write_without_padding() { + let mut buf = vec![]; + let v: VecM = vec![2, 2, 2, 2].try_into().unwrap(); + + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 4, 2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_write_with_padding() { + let mut buf = vec![]; + let v: VecM = vec![2].try_into().unwrap(); + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 1, 2, 0, 0, 0]); + } + + #[test] + pub fn arr_u8_read_without_padding() { + let buf = Cursor::new(vec![2, 2, 2, 2]); + let v = <[u8; 4]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_read_with_padding() { + let buf = Cursor::new(vec![2, 0, 0, 0]); + let v = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2]); + } + + #[test] + pub fn arr_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![2, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn arr_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![2, 3, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn arr_u8_write_without_padding() { + let mut buf = vec![]; + [2u8, 2, 2, 2] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_write_with_padding() { + let mut buf = vec![]; + [2u8] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 0, 0, 0]); + } +} + +#[cfg(all(test, feature = "std"))] +mod test { + use super::*; + + #[test] + fn into_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.into_option(), None); + } + + #[test] + fn into_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.into_option(), Some(1)); + } + + #[test] + fn to_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } + + #[test] + fn depth_limited_read_write_under_the_limit_success() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(4)); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::depth(4)); + let a_back: Option>> = ReadXdr::read_xdr(&mut dlr).unwrap(); + assert_eq!(a, a_back); + } + + #[test] + fn write_over_depth_limit_fail() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(3)); + let res = a.write_xdr(&mut buf); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn read_over_depth_limit_fail() { + let read_limits = Limits::depth(3); + let write_limits = Limits::depth(5); + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), write_limits); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), read_limits); + let res: Result>>> = ReadXdr::read_xdr(&mut dlr); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn length_limited_read_write_i32() { + // Exact limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u32() { + // Exact limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_i64() { + // Exact limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u64() { + // Exact limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bool() { + // Exact limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_option() { + // Exact limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_u8() { + // Exact limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + <[u8; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_type() { + // Exact limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(12)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(13)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(13)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(11)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(11)); + assert_eq!( + <[bool; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_vec() { + // Exact limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(16)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(17)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(17)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(15)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(15)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bytes() { + // Exact limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_string() { + // Exact limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } +} + +#[cfg(all(test, not(feature = "alloc")))] +mod test { + use super::VecM; + + #[test] + fn to_option_none() { + let v: VecM = (&[]).try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = (&[1]).try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } +} + +/// Int64 is an XDR Typedef defines as: +/// +/// ```text +/// typedef hyper int64; +/// ``` +/// +pub type Int64 = i64; + +/// MyStruct is an XDR Struct defines as: +/// +/// ```text +/// struct MyStruct +/// { +/// int someInt; +/// int64 aBigInt; +/// opaque someOpaque[10]; +/// string someString<>; +/// string maxString<100>; +/// }; +/// ``` +/// +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +pub struct MyStruct { + pub some_int: i32, + pub a_big_int: i64, + pub some_opaque: [u8; 10], + pub some_string: StringM, + pub max_string: StringM::<100>, +} + + impl ReadXdr for MyStruct { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + some_int: i32::read_xdr(r)?, +a_big_int: i64::read_xdr(r)?, +some_opaque: <[u8; 10]>::read_xdr(r)?, +some_string: StringM::read_xdr(r)?, +max_string: StringM::<100>::read_xdr(r)?, + }) + }) + } + } + + impl WriteXdr for MyStruct { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; +self.a_big_int.write_xdr(w)?; +self.some_opaque.write_xdr(w)?; +self.some_string.write_xdr(w)?; +self.max_string.write_xdr(w)?; + Ok(()) + }) + } + } + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum TypeVariant { + Int64, +MyStruct, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, +TypeVariant::MyStruct, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", +"MyStruct", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64 => "Int64", +Self::MyStruct => "MyStruct", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + } + + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Int64" => Ok(Self::Int64), +"MyStruct" => Ok(Self::MyStruct), + _ => Err(Error::Invalid), + } + } + } + + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum Type { + Int64(Box), +MyStruct(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, +TypeVariant::MyStruct, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", +"MyStruct", ]; + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Int64 => r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))), +TypeVariant::MyStruct => r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))), + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t.0))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t.0))))), + } + } + + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } + + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), + } + } + + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Int64(ref v) => v.as_ref(), +Self::MyStruct(ref v) => v.as_ref(), + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64(_) => "Int64", +Self::MyStruct(_) => "MyStruct", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Int64(_) => TypeVariant::Int64, +Self::MyStruct(_) => TypeVariant::MyStruct, + } + } + } + + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Int64(v) => v.write_xdr(w), +Self::MyStruct(v) => v.write_xdr(w), + } + } + } diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs new file mode 100644 index 000000000..663e7ab6d --- /dev/null +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -0,0 +1,4911 @@ +// Module is generated from: +// spec/fixtures/generator/test.x + +#![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] + +/// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/test.x", "d29a98a6a3b9bf533a3e6712d928e0bed655e0f462ac4dae810c65d52ca9af41") +]; + +use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; + +#[cfg(feature = "std")] +use core::marker::PhantomData; + +// When feature alloc is turned off use static lifetime Box and Vec types. +#[cfg(not(feature = "alloc"))] +mod noalloc { + pub mod boxed { + pub type Box = &'static T; + } + pub mod vec { + pub type Vec = &'static [T]; + } +} +#[cfg(not(feature = "alloc"))] +use noalloc::{boxed::Box, vec::Vec}; + +// When feature std is turned off, but feature alloc is turned on import the +// alloc crate and use its Box and Vec types. +#[cfg(all(not(feature = "std"), feature = "alloc"))] +extern crate alloc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::{ + borrow::ToOwned, + boxed::Box, + string::{FromUtf8Error, String}, + vec::Vec, +}; +#[cfg(feature = "std")] +use std::string::FromUtf8Error; + +#[cfg(feature = "arbitrary")] +use arbitrary::Arbitrary; + +// TODO: Add support for read/write xdr fns when std not available. + +#[cfg(feature = "std")] +use std::{ + error, io, + io::{BufRead, BufReader, Cursor, Read, Write}, +}; + +/// Error contains all errors returned by functions in this crate. It can be +/// compared via `PartialEq`, however any contained IO errors will only be +/// compared on their `ErrorKind`. +#[derive(Debug)] +pub enum Error { + Invalid, + Unsupported, + LengthExceedsMax, + LengthMismatch, + NonZeroPadding, + Utf8Error(core::str::Utf8Error), + #[cfg(feature = "alloc")] + InvalidHex, + #[cfg(feature = "std")] + Io(io::Error), + DepthLimitExceeded, + #[cfg(feature = "serde_json")] + Json(serde_json::Error), + LengthLimitExceeded, +} + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Utf8Error(l), Self::Utf8Error(r)) => l == r, + // IO errors cannot be compared, but in the absence of any more + // meaningful way to compare the errors we compare the kind of error + // and ignore the embedded source error or OS error. The main use + // case for comparing errors outputted by the XDR library is for + // error case testing, and a lack of the ability to compare has a + // detrimental affect on failure testing, so this is a tradeoff. + #[cfg(feature = "std")] + (Self::Io(l), Self::Io(r)) => l.kind() == r.kind(), + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + #[must_use] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Io(e) => Some(e), + #[cfg(feature = "serde_json")] + Self::Json(e) => Some(e), + _ => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Invalid => write!(f, "xdr value invalid"), + Error::Unsupported => write!(f, "xdr value unsupported"), + Error::LengthExceedsMax => write!(f, "xdr value max length exceeded"), + Error::LengthMismatch => write!(f, "xdr value length does not match"), + Error::NonZeroPadding => write!(f, "xdr padding contains non-zero bytes"), + Error::Utf8Error(e) => write!(f, "{e}"), + #[cfg(feature = "alloc")] + Error::InvalidHex => write!(f, "hex invalid"), + #[cfg(feature = "std")] + Error::Io(e) => write!(f, "{e}"), + Error::DepthLimitExceeded => write!(f, "depth limit exceeded"), + #[cfg(feature = "serde_json")] + Error::Json(e) => write!(f, "{e}"), + Error::LengthLimitExceeded => write!(f, "length limit exceeded"), + } + } +} + +impl From for Error { + fn from(_: TryFromSliceError) -> Error { + Error::LengthMismatch + } +} + +impl From for Error { + #[must_use] + fn from(e: core::str::Utf8Error) -> Self { + Error::Utf8Error(e) + } +} + +#[cfg(feature = "alloc")] +impl From for Error { + #[must_use] + fn from(e: FromUtf8Error) -> Self { + Error::Utf8Error(e.utf8_error()) + } +} + +#[cfg(feature = "std")] +impl From for Error { + #[must_use] + fn from(e: io::Error) -> Self { + Error::Io(e) + } +} + +#[cfg(feature = "serde_json")] +impl From for Error { + #[must_use] + fn from(e: serde_json::Error) -> Self { + Error::Json(e) + } +} + +impl From for () { + fn from(_: Error) {} +} + +#[allow(dead_code)] +type Result = core::result::Result; + +/// Name defines types that assign a static name to their value, such as the +/// name given to an identifier in an XDR enum, or the name given to the case in +/// a union. +pub trait Name { + fn name(&self) -> &'static str; +} + +/// Discriminant defines types that may contain a one-of value determined +/// according to the discriminant, and exposes the value of the discriminant for +/// that type, such as in an XDR union. +pub trait Discriminant { + fn discriminant(&self) -> D; +} + +/// Iter defines types that have variants that can be iterated. +pub trait Variants { + fn variants() -> slice::Iter<'static, V> + where + V: Sized; +} + +// Enum defines a type that is represented as an XDR enumeration when encoded. +pub trait Enum: Name + Variants + Sized {} + +// Union defines a type that is represented as an XDR union when encoded. +pub trait Union: Name + Discriminant + Variants +where + D: Sized, +{ +} + +/// `Limits` contains the limits that a limited reader or writer will be +/// constrained to. +#[cfg(feature = "std")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Limits { + /// Defines the maximum depth for recursive calls in `Read/WriteXdr` to + /// prevent stack overflow. + /// + /// The depth limit is akin to limiting stack depth. Its purpose is to + /// prevent the program from hitting the maximum stack size allowed by Rust, + /// which would result in an unrecoverable `SIGABRT`. For more information + /// about Rust's stack size limit, refer to the [Rust + /// documentation](https://doc.rust-lang.org/std/thread/#stack-size). + pub depth: u32, + + /// Defines the maximum number of bytes that will be read or written. + pub len: usize, +} + +#[cfg(feature = "std")] +impl Limits { + #[must_use] + pub fn none() -> Self { + Self { + depth: u32::MAX, + len: usize::MAX, + } + } + + #[must_use] + pub fn depth(depth: u32) -> Self { + Limits { + depth, + ..Limits::none() + } + } + + #[must_use] + pub fn len(len: usize) -> Self { + Limits { + len, + ..Limits::none() + } + } +} + +/// `Limited` wraps an object and provides functions for enforcing limits. +/// +/// Intended for use with readers and writers and limiting their reads and +/// writes. +#[cfg(feature = "std")] +pub struct Limited { + pub inner: L, + pub(crate) limits: Limits, +} + +#[cfg(feature = "std")] +impl Limited { + /// Constructs a new `Limited`. + /// + /// - `inner`: The value being limited. + /// - `limits`: The limits to enforce. + pub fn new(inner: L, limits: Limits) -> Self { + Limited { inner, limits } + } + + /// Consume the given length from the internal remaining length limit. + /// + /// ### Errors + /// + /// If the length would consume more length than the remaining length limit + /// allows. + pub(crate) fn consume_len(&mut self, len: usize) -> Result<()> { + if let Some(len) = self.limits.len.checked_sub(len) { + self.limits.len = len; + Ok(()) + } else { + Err(Error::LengthLimitExceeded) + } + } + + /// Consumes a single depth for the duration of the given function. + /// + /// ### Errors + /// + /// If the depth limit is already exhausted. + pub(crate) fn with_limited_depth(&mut self, f: F) -> Result + where + F: FnOnce(&mut Self) -> Result, + { + if let Some(depth) = self.limits.depth.checked_sub(1) { + self.limits.depth = depth; + let res = f(self); + self.limits.depth = self.limits.depth.saturating_add(1); + res + } else { + Err(Error::DepthLimitExceeded) + } + } +} + +#[cfg(feature = "std")] +impl Read for Limited { + /// Forwards the read operation to the wrapped object. + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.inner.read(buf) + } +} + +#[cfg(feature = "std")] +impl BufRead for Limited { + /// Forwards the read operation to the wrapped object. + fn fill_buf(&mut self) -> std::io::Result<&[u8]> { + self.inner.fill_buf() + } + + /// Forwards the read operation to the wrapped object. + fn consume(&mut self, amt: usize) { + self.inner.consume(amt); + } +} + +#[cfg(feature = "std")] +impl Write for Limited { + /// Forwards the write operation to the wrapped object. + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.inner.write(buf) + } + + /// Forwards the flush operation to the wrapped object. + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } +} + +#[cfg(feature = "std")] +pub struct ReadXdrIter { + reader: Limited>, + _s: PhantomData, +} + +#[cfg(feature = "std")] +impl ReadXdrIter { + fn new(r: R, limits: Limits) -> Self { + Self { + reader: Limited { + inner: BufReader::new(r), + limits, + }, + _s: PhantomData, + } + } +} + +#[cfg(feature = "std")] +impl Iterator for ReadXdrIter { + type Item = Result; + + // Next reads the internal reader and XDR decodes it into the Self type. If + // the EOF is reached without reading any new bytes `None` is returned. If + // EOF is reached after reading some bytes a truncated entry is assumed an + // an `Error::Io` containing an `UnexpectedEof`. If any other IO error + // occurs it is returned. Iteration of this iterator stops naturally when + // `None` is returned, but not when a `Some(Err(...))` is returned. The + // caller is responsible for checking each Result. + fn next(&mut self) -> Option { + // Try to fill the buffer to see if the EOF has been reached or not. + // This happens to effectively peek to see if the stream has finished + // and there are no more items. It is necessary to do this because the + // xdr types in this crate heavily use the `std::io::Read::read_exact` + // method that doesn't distinguish between an EOF at the beginning of a + // read and an EOF after a partial fill of a read_exact. + match self.reader.fill_buf() { + // If the reader has no more data and is unable to fill any new data + // into its internal buf, then the EOF has been reached. + Ok([]) => return None, + // If an error occurs filling the buffer, treat that as an error and stop. + Err(e) => return Some(Err(Error::Io(e))), + // If there is data in the buf available for reading, continue. + Ok([..]) => (), + }; + // Read the buf into the type. + let r = self.reader.with_limited_depth(|dlr| S::read_xdr(dlr)); + match r { + Ok(s) => Some(Ok(s)), + Err(e) => Some(Err(e)), + } + } +} + +pub trait ReadXdr +where + Self: Sized, +{ + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_to_end`] when the intent is for all bytes in the + /// read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result; + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_to_end(r: &mut Limited) -> Result { + let s = Self::read_xdr(r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64_to_end(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_into_to_end`] when the intent is for all bytes + /// in the read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr_into(&mut self, r: &mut Limited) -> Result<()> { + *self = Self::read_xdr(r)?; + Ok(()) + } + + /// Read the XDR into the existing value, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_into_to_end(&mut self, r: &mut Limited) -> Result<()> { + Self::read_xdr_into(self, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(()) + } else { + Err(Error::Invalid) + } + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_iter(r: &mut Limited) -> ReadXdrIter<&mut R, Self> { + ReadXdrIter::new(&mut r.inner, r.limits.clone()) + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + #[cfg(feature = "base64")] + fn read_xdr_base64_iter( + r: &mut Limited, + ) -> ReadXdrIter, Self> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + ReadXdrIter::new(dec, r.limits.clone()) + } + + /// Construct the type from the XDR bytes. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "std")] + fn from_xdr(bytes: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(&mut cursor)?; + Ok(t) + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn from_xdr_base64(b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } +} + +pub trait WriteXdr { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()>; + + #[cfg(feature = "std")] + fn to_xdr(&self, limits: Limits) -> Result> { + let mut cursor = Limited::new(Cursor::new(vec![]), limits); + self.write_xdr(&mut cursor)?; + let bytes = cursor.inner.into_inner(); + Ok(bytes) + } + + #[cfg(feature = "base64")] + fn to_xdr_base64(&self, limits: Limits) -> Result { + let mut enc = Limited::new( + base64::write::EncoderStringWriter::new(base64::STANDARD), + limits, + ); + self.write_xdr(&mut enc)?; + let b64 = enc.inner.into_inner(); + Ok(b64) + } +} + +/// `Pad_len` returns the number of bytes to pad an XDR value of the given +/// length to make the final serialized size a multiple of 4. +#[cfg(feature = "std")] +fn pad_len(len: usize) -> usize { + (4 - (len % 4)) % 4 +} + +impl ReadXdr for i32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for i64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for f32 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f32 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for f64 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f64 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for bool { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + let b = i == 1; + Ok(b) + }) + } +} + +impl WriteXdr for bool { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i = u32::from(*self); // true = 1, false = 0 + i.write_xdr(w) + }) + } +} + +impl ReadXdr for Option { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + match i { + 0 => Ok(None), + 1 => { + let t = T::read_xdr(r)?; + Ok(Some(t)) + } + _ => Err(Error::Invalid), + } + }) + } +} + +impl WriteXdr for Option { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + if let Some(t) = self { + 1u32.write_xdr(w)?; + t.write_xdr(w)?; + } else { + 0u32.write_xdr(w)?; + } + Ok(()) + }) + } +} + +impl ReadXdr for Box { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| Ok(Box::new(T::read_xdr(r)?))) + } +} + +impl WriteXdr for Box { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| T::write_xdr(self, w)) + } +} + +impl ReadXdr for () { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + Ok(()) + } +} + +impl WriteXdr for () { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + Ok(()) + } +} + +impl ReadXdr for [u8; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + r.consume_len(N)?; + let padding = pad_len(N); + r.consume_len(padding)?; + let mut arr = [0u8; N]; + r.read_exact(&mut arr)?; + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + Ok(arr) + }) + } +} + +impl WriteXdr for [u8; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + w.consume_len(N)?; + let padding = pad_len(N); + w.consume_len(padding)?; + w.write_all(self)?; + w.write_all(&[0u8; 3][..padding])?; + Ok(()) + }) + } +} + +impl ReadXdr for [T; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let mut vec = Vec::with_capacity(N); + for _ in 0..N { + let t = T::read_xdr(r)?; + vec.push(t); + } + let arr: [T; N] = vec.try_into().unwrap_or_else(|_: Vec| unreachable!()); + Ok(arr) + }) + } +} + +impl WriteXdr for [T; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + for t in self { + t.write_xdr(w)?; + } + Ok(()) + }) + } +} + +// VecM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec) +where + T: 'static; + +impl Deref for VecM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for VecM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl VecM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl VecM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl VecM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl VecM { + #[must_use] + pub fn to_option(&self) -> Option { + if self.len() > 0 { + Some(self.0[0].clone()) + } else { + None + } + } +} + +#[cfg(not(feature = "alloc"))] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.to_option() + } +} + +#[cfg(feature = "alloc")] +impl VecM { + #[must_use] + pub fn into_option(mut self) -> Option { + self.0.drain(..).next() + } +} + +#[cfg(feature = "alloc")] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.into_option() + } +} + +impl TryFrom> for VecM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: VecM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&VecM> for Vec { + #[must_use] + fn from(v: &VecM) -> Self { + v.0.clone() + } +} + +impl AsRef> for VecM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for VecM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T]> for VecM { + type Error = Error; + + fn try_from(v: &[T]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[T]> for VecM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[T; N]> for VecM { + type Error = Error; + + fn try_from(v: [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [T; N] { + type Error = VecM; + + fn try_from(v: VecM) -> core::result::Result { + let s: [T; N] = v.0.try_into().map_err(|v: Vec| VecM::(v))?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T; N]> for VecM { + type Error = Error; + + fn try_from(v: &[T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [T; N]> for VecM { + type Error = Error; + + fn try_from(v: &'static [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for VecM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for VecM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: VecM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&VecM> for String { + type Error = Error; + + fn try_from(v: &VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for VecM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for VecM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a VecM> for &'a str { + type Error = Error; + + fn try_from(v: &'a VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + let mut vec = Vec::new(); + for _ in 0..len { + let t = T::read_xdr(r)?; + vec.push(t); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + for t in &self.0 { + t.write_xdr(w)?; + } + + Ok(()) + }) + } +} + +// BytesM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +impl core::fmt::Display for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +impl core::fmt::Debug for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "BytesM(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for BytesM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} + +impl Deref for BytesM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for BytesM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl BytesM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl BytesM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl BytesM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for BytesM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: BytesM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&BytesM> for Vec { + #[must_use] + fn from(v: &BytesM) -> Self { + v.0.clone() + } +} + +impl AsRef> for BytesM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for BytesM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for BytesM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = BytesM; + + fn try_from(v: BytesM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(BytesM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for BytesM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for BytesM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: BytesM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&BytesM> for String { + type Error = Error; + + fn try_from(v: &BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for BytesM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for BytesM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a BytesM> for &'a str { + type Error = Error; + + fn try_from(v: &'a BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for BytesM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(BytesM(vec)) + }) + } +} + +impl WriteXdr for BytesM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..pad_len(len as usize)])?; + + Ok(()) + }) + } +} + +// StringM ------------------------------------------------------------------------ + +/// A string type that contains arbitrary bytes. +/// +/// Convertible, fallibly, to/from a Rust UTF-8 String using +/// [`TryFrom`]/[`TryInto`]/[`StringM::to_utf8_string`]. +/// +/// Convertible, lossyly, to a Rust UTF-8 String using +/// [`StringM::to_utf8_string_lossy`]. +/// +/// Convertible to/from escaped printable-ASCII using +/// [`Display`]/[`ToString`]/[`FromStr`]. + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +impl core::fmt::Display for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + Ok(()) + } +} + +impl core::fmt::Debug for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "StringM(")?; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for StringM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?; + Ok(Self(b)) + } +} + +impl Deref for StringM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for StringM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl StringM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl StringM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl StringM { + #[cfg(feature = "alloc")] + pub fn to_utf8_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_utf8_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_utf8_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_utf8_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for StringM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: StringM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&StringM> for Vec { + #[must_use] + fn from(v: &StringM) -> Self { + v.0.clone() + } +} + +impl AsRef> for StringM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for StringM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for StringM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for StringM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = StringM; + + fn try_from(v: StringM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(StringM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for StringM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for StringM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: StringM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&StringM> for String { + type Error = Error; + + fn try_from(v: &StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for StringM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for StringM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a StringM> for &'a str { + type Error = Error; + + fn try_from(v: &'a StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for StringM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(StringM(vec)) + }) + } +} + +impl WriteXdr for StringM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +// Frame ------------------------------------------------------------------------ + +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Frame(pub T) +where + T: ReadXdr; + +impl ReadXdr for Frame +where + T: ReadXdr, +{ + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + // Read the frame header value that contains 1 flag-bit and a 33-bit length. + // - The 1 flag bit is 0 when there are more frames for the same record. + // - The 31-bit length is the length of the bytes within the frame that + // follow the frame header. + let header = u32::read_xdr(r)?; + // TODO: Use the length and cap the length we'll read from `r`. + let last_record = header >> 31 == 1; + if last_record { + // Read the record in the frame. + Ok(Self(T::read_xdr(r)?)) + } else { + // TODO: Support reading those additional frames for the same + // record. + Err(Error::Unsupported) + } + } +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + pub fn vec_u8_read_without_padding() { + let buf = Cursor::new(vec![0, 0, 0, 4, 2, 2, 2, 2]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_read_with_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0, 0]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2]); + } + + #[test] + pub fn vec_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn vec_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 3, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn vec_u8_write_without_padding() { + let mut buf = vec![]; + let v: VecM = vec![2, 2, 2, 2].try_into().unwrap(); + + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 4, 2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_write_with_padding() { + let mut buf = vec![]; + let v: VecM = vec![2].try_into().unwrap(); + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 1, 2, 0, 0, 0]); + } + + #[test] + pub fn arr_u8_read_without_padding() { + let buf = Cursor::new(vec![2, 2, 2, 2]); + let v = <[u8; 4]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_read_with_padding() { + let buf = Cursor::new(vec![2, 0, 0, 0]); + let v = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2]); + } + + #[test] + pub fn arr_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![2, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn arr_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![2, 3, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn arr_u8_write_without_padding() { + let mut buf = vec![]; + [2u8, 2, 2, 2] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_write_with_padding() { + let mut buf = vec![]; + [2u8] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 0, 0, 0]); + } +} + +#[cfg(all(test, feature = "std"))] +mod test { + use super::*; + + #[test] + fn into_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.into_option(), None); + } + + #[test] + fn into_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.into_option(), Some(1)); + } + + #[test] + fn to_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } + + #[test] + fn depth_limited_read_write_under_the_limit_success() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(4)); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::depth(4)); + let a_back: Option>> = ReadXdr::read_xdr(&mut dlr).unwrap(); + assert_eq!(a, a_back); + } + + #[test] + fn write_over_depth_limit_fail() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(3)); + let res = a.write_xdr(&mut buf); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn read_over_depth_limit_fail() { + let read_limits = Limits::depth(3); + let write_limits = Limits::depth(5); + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), write_limits); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), read_limits); + let res: Result>>> = ReadXdr::read_xdr(&mut dlr); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn length_limited_read_write_i32() { + // Exact limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u32() { + // Exact limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_i64() { + // Exact limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u64() { + // Exact limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bool() { + // Exact limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_option() { + // Exact limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_u8() { + // Exact limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + <[u8; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_type() { + // Exact limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(12)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(13)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(13)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(11)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(11)); + assert_eq!( + <[bool; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_vec() { + // Exact limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(16)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(17)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(17)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(15)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(15)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bytes() { + // Exact limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_string() { + // Exact limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } +} + +#[cfg(all(test, not(feature = "alloc")))] +mod test { + use super::VecM; + + #[test] + fn to_option_none() { + let v: VecM = (&[]).try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = (&[1]).try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } +} + +/// Uint512 is an XDR Typedef defines as: +/// +/// ```text +/// typedef opaque uint512[64]; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Uint512(pub [u8; 64]); + +impl core::fmt::Debug for Uint512 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let v = &self.0; + write!(f, "Uint512(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} +impl core::fmt::Display for Uint512 { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let v = &self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for Uint512 { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} +impl From for [u8; 64] { + #[must_use] + fn from(x: Uint512) -> Self { + x.0 + } +} + +impl From<[u8; 64]> for Uint512 { + #[must_use] + fn from(x: [u8; 64]) -> Self { + Uint512(x) + } +} + +impl AsRef<[u8; 64]> for Uint512 { + #[must_use] + fn as_ref(&self) -> &[u8; 64] { + &self.0 + } +} + +impl ReadXdr for Uint512 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = <[u8; 64]>::read_xdr(r)?; + let v = Uint512(i); + Ok(v) + }) + } +} + +impl WriteXdr for Uint512 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +impl Uint512 { + #[must_use] + pub fn as_slice(&self) -> &[u8] { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for Uint512 { + type Error = Error; + fn try_from(x: Vec) -> Result { + x.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for Uint512 { + type Error = Error; + fn try_from(x: &Vec) -> Result { + x.as_slice().try_into() + } +} + +impl TryFrom<&[u8]> for Uint512 { + type Error = Error; + fn try_from(x: &[u8]) -> Result { + Ok(Uint512(x.try_into()?)) + } +} + +impl AsRef<[u8]> for Uint512 { + #[must_use] + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +/// Uint513 is an XDR Typedef defines as: +/// +/// ```text +/// typedef opaque uint513<64>; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[derive(Default)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct Uint513(pub BytesM::<64>); + +impl From for BytesM::<64> { + #[must_use] + fn from(x: Uint513) -> Self { + x.0 + } +} + +impl From> for Uint513 { + #[must_use] + fn from(x: BytesM::<64>) -> Self { + Uint513(x) + } +} + +impl AsRef> for Uint513 { + #[must_use] + fn as_ref(&self) -> &BytesM::<64> { + &self.0 + } +} + +impl ReadXdr for Uint513 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = BytesM::<64>::read_xdr(r)?; + let v = Uint513(i); + Ok(v) + }) + } +} + +impl WriteXdr for Uint513 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +impl Deref for Uint513 { + type Target = BytesM::<64>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Vec { + #[must_use] + fn from(x: Uint513) -> Self { + x.0.0 + } +} + +impl TryFrom> for Uint513 { + type Error = Error; + fn try_from(x: Vec) -> Result { + Ok(Uint513(x.try_into()?)) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for Uint513 { + type Error = Error; + fn try_from(x: &Vec) -> Result { + Ok(Uint513(x.try_into()?)) + } +} + +impl AsRef> for Uint513 { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0.0 + } +} + +impl AsRef<[u8]> for Uint513 { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + &self.0.0 + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.0 + } +} + +/// Uint514 is an XDR Typedef defines as: +/// +/// ```text +/// typedef opaque uint514<>; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[derive(Default)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct Uint514(pub BytesM); + +impl From for BytesM { + #[must_use] + fn from(x: Uint514) -> Self { + x.0 + } +} + +impl From for Uint514 { + #[must_use] + fn from(x: BytesM) -> Self { + Uint514(x) + } +} + +impl AsRef for Uint514 { + #[must_use] + fn as_ref(&self) -> &BytesM { + &self.0 + } +} + +impl ReadXdr for Uint514 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = BytesM::read_xdr(r)?; + let v = Uint514(i); + Ok(v) + }) + } +} + +impl WriteXdr for Uint514 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +impl Deref for Uint514 { + type Target = BytesM; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Vec { + #[must_use] + fn from(x: Uint514) -> Self { + x.0.0 + } +} + +impl TryFrom> for Uint514 { + type Error = Error; + fn try_from(x: Vec) -> Result { + Ok(Uint514(x.try_into()?)) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for Uint514 { + type Error = Error; + fn try_from(x: &Vec) -> Result { + Ok(Uint514(x.try_into()?)) + } +} + +impl AsRef> for Uint514 { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0.0 + } +} + +impl AsRef<[u8]> for Uint514 { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + &self.0.0 + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.0 + } +} + +/// Str is an XDR Typedef defines as: +/// +/// ```text +/// typedef string str<64>; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[derive(Default)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct Str(pub StringM::<64>); + +impl From for StringM::<64> { + #[must_use] + fn from(x: Str) -> Self { + x.0 + } +} + +impl From> for Str { + #[must_use] + fn from(x: StringM::<64>) -> Self { + Str(x) + } +} + +impl AsRef> for Str { + #[must_use] + fn as_ref(&self) -> &StringM::<64> { + &self.0 + } +} + +impl ReadXdr for Str { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = StringM::<64>::read_xdr(r)?; + let v = Str(i); + Ok(v) + }) + } +} + +impl WriteXdr for Str { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +impl Deref for Str { + type Target = StringM::<64>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Vec { + #[must_use] + fn from(x: Str) -> Self { + x.0.0 + } +} + +impl TryFrom> for Str { + type Error = Error; + fn try_from(x: Vec) -> Result { + Ok(Str(x.try_into()?)) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for Str { + type Error = Error; + fn try_from(x: &Vec) -> Result { + Ok(Str(x.try_into()?)) + } +} + +impl AsRef> for Str { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0.0 + } +} + +impl AsRef<[u8]> for Str { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + &self.0.0 + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.0 + } +} + +/// Str2 is an XDR Typedef defines as: +/// +/// ```text +/// typedef string str2<>; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[derive(Default)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct Str2(pub StringM); + +impl From for StringM { + #[must_use] + fn from(x: Str2) -> Self { + x.0 + } +} + +impl From for Str2 { + #[must_use] + fn from(x: StringM) -> Self { + Str2(x) + } +} + +impl AsRef for Str2 { + #[must_use] + fn as_ref(&self) -> &StringM { + &self.0 + } +} + +impl ReadXdr for Str2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = StringM::read_xdr(r)?; + let v = Str2(i); + Ok(v) + }) + } +} + +impl WriteXdr for Str2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +impl Deref for Str2 { + type Target = StringM; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Vec { + #[must_use] + fn from(x: Str2) -> Self { + x.0.0 + } +} + +impl TryFrom> for Str2 { + type Error = Error; + fn try_from(x: Vec) -> Result { + Ok(Str2(x.try_into()?)) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for Str2 { + type Error = Error; + fn try_from(x: &Vec) -> Result { + Ok(Str2(x.try_into()?)) + } +} + +impl AsRef> for Str2 { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0.0 + } +} + +impl AsRef<[u8]> for Str2 { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + &self.0.0 + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.0 + } +} + +/// Hash is an XDR Typedef defines as: +/// +/// ```text +/// typedef opaque Hash[32]; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Hash(pub [u8; 32]); + +impl core::fmt::Debug for Hash { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let v = &self.0; + write!(f, "Hash(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} +impl core::fmt::Display for Hash { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let v = &self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for Hash { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} +impl From for [u8; 32] { + #[must_use] + fn from(x: Hash) -> Self { + x.0 + } +} + +impl From<[u8; 32]> for Hash { + #[must_use] + fn from(x: [u8; 32]) -> Self { + Hash(x) + } +} + +impl AsRef<[u8; 32]> for Hash { + #[must_use] + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + +impl ReadXdr for Hash { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = <[u8; 32]>::read_xdr(r)?; + let v = Hash(i); + Ok(v) + }) + } +} + +impl WriteXdr for Hash { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +impl Hash { + #[must_use] + pub fn as_slice(&self) -> &[u8] { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for Hash { + type Error = Error; + fn try_from(x: Vec) -> Result { + x.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for Hash { + type Error = Error; + fn try_from(x: &Vec) -> Result { + x.as_slice().try_into() + } +} + +impl TryFrom<&[u8]> for Hash { + type Error = Error; + fn try_from(x: &[u8]) -> Result { + Ok(Hash(x.try_into()?)) + } +} + +impl AsRef<[u8]> for Hash { + #[must_use] + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +/// Hashes1 is an XDR Typedef defines as: +/// +/// ```text +/// typedef Hash Hashes1[12]; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct Hashes1(pub [Hash; 12]); + +impl From for [Hash; 12] { + #[must_use] + fn from(x: Hashes1) -> Self { + x.0 + } +} + +impl From<[Hash; 12]> for Hashes1 { + #[must_use] + fn from(x: [Hash; 12]) -> Self { + Hashes1(x) + } +} + +impl AsRef<[Hash; 12]> for Hashes1 { + #[must_use] + fn as_ref(&self) -> &[Hash; 12] { + &self.0 + } +} + +impl ReadXdr for Hashes1 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = <[Hash; 12]>::read_xdr(r)?; + let v = Hashes1(i); + Ok(v) + }) + } +} + +impl WriteXdr for Hashes1 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +impl Hashes1 { + #[must_use] + pub fn as_slice(&self) -> &[Hash] { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for Hashes1 { + type Error = Error; + fn try_from(x: Vec) -> Result { + x.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for Hashes1 { + type Error = Error; + fn try_from(x: &Vec) -> Result { + x.as_slice().try_into() + } +} + +impl TryFrom<&[Hash]> for Hashes1 { + type Error = Error; + fn try_from(x: &[Hash]) -> Result { + Ok(Hashes1(x.try_into()?)) + } +} + +impl AsRef<[Hash]> for Hashes1 { + #[must_use] + fn as_ref(&self) -> &[Hash] { + &self.0 + } +} + +/// Hashes2 is an XDR Typedef defines as: +/// +/// ```text +/// typedef Hash Hashes2<12>; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[derive(Default)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct Hashes2(pub VecM::); + +impl From for VecM:: { + #[must_use] + fn from(x: Hashes2) -> Self { + x.0 + } +} + +impl From> for Hashes2 { + #[must_use] + fn from(x: VecM::) -> Self { + Hashes2(x) + } +} + +impl AsRef> for Hashes2 { + #[must_use] + fn as_ref(&self) -> &VecM:: { + &self.0 + } +} + +impl ReadXdr for Hashes2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = VecM::::read_xdr(r)?; + let v = Hashes2(i); + Ok(v) + }) + } +} + +impl WriteXdr for Hashes2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +impl Deref for Hashes2 { + type Target = VecM::; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Vec { + #[must_use] + fn from(x: Hashes2) -> Self { + x.0.0 + } +} + +impl TryFrom> for Hashes2 { + type Error = Error; + fn try_from(x: Vec) -> Result { + Ok(Hashes2(x.try_into()?)) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for Hashes2 { + type Error = Error; + fn try_from(x: &Vec) -> Result { + Ok(Hashes2(x.try_into()?)) + } +} + +impl AsRef> for Hashes2 { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0.0 + } +} + +impl AsRef<[Hash]> for Hashes2 { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[Hash] { + &self.0.0 + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[Hash] { + self.0.0 + } +} + +/// Hashes3 is an XDR Typedef defines as: +/// +/// ```text +/// typedef Hash Hashes3<>; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[derive(Default)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct Hashes3(pub VecM::); + +impl From for VecM:: { + #[must_use] + fn from(x: Hashes3) -> Self { + x.0 + } +} + +impl From> for Hashes3 { + #[must_use] + fn from(x: VecM::) -> Self { + Hashes3(x) + } +} + +impl AsRef> for Hashes3 { + #[must_use] + fn as_ref(&self) -> &VecM:: { + &self.0 + } +} + +impl ReadXdr for Hashes3 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = VecM::::read_xdr(r)?; + let v = Hashes3(i); + Ok(v) + }) + } +} + +impl WriteXdr for Hashes3 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +impl Deref for Hashes3 { + type Target = VecM::; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl From for Vec { + #[must_use] + fn from(x: Hashes3) -> Self { + x.0.0 + } +} + +impl TryFrom> for Hashes3 { + type Error = Error; + fn try_from(x: Vec) -> Result { + Ok(Hashes3(x.try_into()?)) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for Hashes3 { + type Error = Error; + fn try_from(x: &Vec) -> Result { + Ok(Hashes3(x.try_into()?)) + } +} + +impl AsRef> for Hashes3 { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0.0 + } +} + +impl AsRef<[Hash]> for Hashes3 { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[Hash] { + &self.0.0 + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[Hash] { + self.0.0 + } +} + +/// OptHash1 is an XDR Typedef defines as: +/// +/// ```text +/// typedef Hash *optHash1; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct OptHash1(pub Option); + +impl From for Option { + #[must_use] + fn from(x: OptHash1) -> Self { + x.0 + } +} + +impl From> for OptHash1 { + #[must_use] + fn from(x: Option) -> Self { + OptHash1(x) + } +} + +impl AsRef> for OptHash1 { + #[must_use] + fn as_ref(&self) -> &Option { + &self.0 + } +} + +impl ReadXdr for OptHash1 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = Option::::read_xdr(r)?; + let v = OptHash1(i); + Ok(v) + }) + } +} + +impl WriteXdr for OptHash1 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +/// OptHash2 is an XDR Typedef defines as: +/// +/// ```text +/// typedef Hash* optHash2; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct OptHash2(pub Option); + +impl From for Option { + #[must_use] + fn from(x: OptHash2) -> Self { + x.0 + } +} + +impl From> for OptHash2 { + #[must_use] + fn from(x: Option) -> Self { + OptHash2(x) + } +} + +impl AsRef> for OptHash2 { + #[must_use] + fn as_ref(&self) -> &Option { + &self.0 + } +} + +impl ReadXdr for OptHash2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = Option::::read_xdr(r)?; + let v = OptHash2(i); + Ok(v) + }) + } +} + +impl WriteXdr for OptHash2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + +/// Int1 is an XDR Typedef defines as: +/// +/// ```text +/// typedef int int1; +/// ``` +/// +pub type Int1 = i32; + +/// Int2 is an XDR Typedef defines as: +/// +/// ```text +/// typedef hyper int2; +/// ``` +/// +pub type Int2 = i64; + +/// Int3 is an XDR Typedef defines as: +/// +/// ```text +/// typedef unsigned int int3; +/// ``` +/// +pub type Int3 = u32; + +/// Int4 is an XDR Typedef defines as: +/// +/// ```text +/// typedef unsigned hyper int4; +/// ``` +/// +pub type Int4 = u64; + +/// MyStruct is an XDR Struct defines as: +/// +/// ```text +/// struct MyStruct +/// { +/// uint512 field1; +/// optHash1 field2; +/// int1 field3; +/// unsigned int field4; +/// float field5; +/// double field6; +/// bool field7; +/// }; +/// ``` +/// +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +pub struct MyStruct { + pub field1: Uint512, + pub field2: OptHash1, + pub field3: i32, + pub field4: u32, + pub field5: f32, + pub field6: f64, + pub field7: bool, +} + + impl ReadXdr for MyStruct { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + field1: Uint512::read_xdr(r)?, +field2: OptHash1::read_xdr(r)?, +field3: i32::read_xdr(r)?, +field4: u32::read_xdr(r)?, +field5: f32::read_xdr(r)?, +field6: f64::read_xdr(r)?, +field7: bool::read_xdr(r)?, + }) + }) + } + } + + impl WriteXdr for MyStruct { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.field1.write_xdr(w)?; +self.field2.write_xdr(w)?; +self.field3.write_xdr(w)?; +self.field4.write_xdr(w)?; +self.field5.write_xdr(w)?; +self.field6.write_xdr(w)?; +self.field7.write_xdr(w)?; + Ok(()) + }) + } + } + +/// LotsOfMyStructs is an XDR Struct defines as: +/// +/// ```text +/// struct LotsOfMyStructs +/// { +/// MyStruct members<>; +/// }; +/// ``` +/// +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +pub struct LotsOfMyStructs { + pub members: VecM::, +} + +impl ReadXdr for LotsOfMyStructs { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + members: VecM::::read_xdr(r)?, + }) + }) + } +} + +impl WriteXdr for LotsOfMyStructs { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.members.write_xdr(w)?; + Ok(()) + }) + } +} + +/// HasStuff is an XDR Struct defines as: +/// +/// ```text +/// struct HasStuff +/// { +/// LotsOfMyStructs data; +/// }; +/// ``` +/// +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct HasStuff { + pub data: LotsOfMyStructs, +} + +impl ReadXdr for HasStuff { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + data: LotsOfMyStructs::read_xdr(r)?, + }) + }) + } +} + +impl WriteXdr for HasStuff { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.data.write_xdr(w)?; + Ok(()) + }) + } +} + +/// Color is an XDR Enum defines as: +/// +/// ```text +/// enum Color { +/// RED, +/// BLUE = 5, +/// GREEN +/// }; +/// ``` +/// +// enum +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[repr(i32)] +pub enum Color { + Red = 0, + Blue = 5, + Green = 6, +} + + impl Color { + pub const VARIANTS: [Color; 3] = [ Color::Red, +Color::Blue, +Color::Green, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "Red", +"Blue", +"Green", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red => "Red", +Self::Blue => "Blue", +Self::Green => "Green", + } + } + + #[must_use] + pub const fn variants() -> [Color; 3] { + Self::VARIANTS + } + } + + impl Name for Color { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Color { + fn variants() -> slice::Iter<'static, Color> { + Self::VARIANTS.iter() + } + } + + impl Enum for Color {} + + impl fmt::Display for Color { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } + + impl TryFrom for Color { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color::Red, +5 => Color::Blue, +6 => Color::Green, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } + + impl From for i32 { + #[must_use] + fn from(e: Color) -> Self { + e as Self + } + } + + impl ReadXdr for Color { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } + + impl WriteXdr for Color { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } + +/// Foo is an XDR Const defines as: +/// +/// ```text +/// const FOO = 1244; +/// ``` +/// +pub const FOO: u64 = 1244; + +/// Bar is an XDR Const defines as: +/// +/// ```text +/// const BAR = FOO; +/// ``` +/// +pub const BAR: u64 = FOO; + +/// NesterNestedEnum is an XDR NestedEnum defines as: +/// +/// ```text +/// enum { +/// BLAH_1, +/// BLAH_2 +/// } +/// ``` +/// +// enum +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[repr(i32)] +pub enum NesterNestedEnum { + 1 = 0, + 2 = 1, +} + + impl NesterNestedEnum { + pub const VARIANTS: [NesterNestedEnum; 2] = [ NesterNestedEnum::1, +NesterNestedEnum::2, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "1", +"2", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::1 => "1", +Self::2 => "2", + } + } + + #[must_use] + pub const fn variants() -> [NesterNestedEnum; 2] { + Self::VARIANTS + } + } + + impl Name for NesterNestedEnum { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for NesterNestedEnum { + fn variants() -> slice::Iter<'static, NesterNestedEnum> { + Self::VARIANTS.iter() + } + } + + impl Enum for NesterNestedEnum {} + + impl fmt::Display for NesterNestedEnum { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } + + impl TryFrom for NesterNestedEnum { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 0 => NesterNestedEnum::1, +1 => NesterNestedEnum::2, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } + + impl From for i32 { + #[must_use] + fn from(e: NesterNestedEnum) -> Self { + e as Self + } + } + + impl ReadXdr for NesterNestedEnum { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } + + impl WriteXdr for NesterNestedEnum { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } + +/// NesterNestedStruct is an XDR NestedStruct defines as: +/// +/// ```text +/// struct { +/// int blah; +/// } +/// ``` +/// +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct NesterNestedStruct { + pub blah: i32, +} + +impl ReadXdr for NesterNestedStruct { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + blah: i32::read_xdr(r)?, + }) + }) + } +} + +impl WriteXdr for NesterNestedStruct { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.blah.write_xdr(w)?; + Ok(()) + }) + } +} + +/// NesterNestedUnion is an XDR NestedUnion defines as: +/// +/// ```text +/// union switch (Color color) { +/// case RED: +/// void; +/// default: +/// int blah2; +/// } +/// ``` +/// +// union with discriminant Color +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[allow(clippy::large_enum_variant)] +pub enum NesterNestedUnion { + Red, +} + +impl NesterNestedUnion { + pub const VARIANTS: [Color; 1] = [ + Color::Red, + ]; + pub const VARIANTS_STR: [&'static str; 1] = [ + "Red", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red => "Red", + } + } + + #[must_use] + pub const fn discriminant(&self) -> Color { + #[allow(clippy::match_same_arms)] + match self { + Self::Red => Color::Red, + } + } + + #[must_use] + pub const fn variants() -> [Color; 1] { + Self::VARIANTS + } +} + +impl Name for NesterNestedUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Discriminant for NesterNestedUnion { + #[must_use] + fn discriminant(&self) -> Color { + Self::discriminant(self) + } +} + +impl Variants for NesterNestedUnion { + fn variants() -> slice::Iter<'static, Color> { + Self::VARIANTS.iter() + } +} + +impl Union for NesterNestedUnion {} + +impl ReadXdr for NesterNestedUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: Color = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + Color::Red => Self::Red, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} + +impl WriteXdr for NesterNestedUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::Red => ().write_xdr(w)?, + }; + Ok(()) + }) + } +} + +/// Nester is an XDR Struct defines as: +/// +/// ```text +/// struct Nester +/// { +/// enum { +/// BLAH_1, +/// BLAH_2 +/// } nestedEnum; +/// +/// struct { +/// int blah; +/// } nestedStruct; +/// +/// union switch (Color color) { +/// case RED: +/// void; +/// default: +/// int blah2; +/// } nestedUnion; +/// +/// +/// }; +/// ``` +/// +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Nester { + pub nested_enum: NesterNestedEnum, + pub nested_struct: NesterNestedStruct, + pub nested_union: NesterNestedUnion, +} + + impl ReadXdr for Nester { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + nested_enum: NesterNestedEnum::read_xdr(r)?, +nested_struct: NesterNestedStruct::read_xdr(r)?, +nested_union: NesterNestedUnion::read_xdr(r)?, + }) + }) + } + } + + impl WriteXdr for Nester { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.nested_enum.write_xdr(w)?; +self.nested_struct.write_xdr(w)?; +self.nested_union.write_xdr(w)?; + Ok(()) + }) + } + } + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum TypeVariant { + Uint512, +Uint513, +Uint514, +Str, +Str2, +Hash, +Hashes1, +Hashes2, +Hashes3, +OptHash1, +OptHash2, +Int1, +Int2, +Int3, +Int4, +MyStruct, +LotsOfMyStructs, +HasStuff, +Color, +Nester, +NesterNestedEnum, +NesterNestedStruct, +NesterNestedUnion, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 23] = [ TypeVariant::Uint512, +TypeVariant::Uint513, +TypeVariant::Uint514, +TypeVariant::Str, +TypeVariant::Str2, +TypeVariant::Hash, +TypeVariant::Hashes1, +TypeVariant::Hashes2, +TypeVariant::Hashes3, +TypeVariant::OptHash1, +TypeVariant::OptHash2, +TypeVariant::Int1, +TypeVariant::Int2, +TypeVariant::Int3, +TypeVariant::Int4, +TypeVariant::MyStruct, +TypeVariant::LotsOfMyStructs, +TypeVariant::HasStuff, +TypeVariant::Color, +TypeVariant::Nester, +TypeVariant::NesterNestedEnum, +TypeVariant::NesterNestedStruct, +TypeVariant::NesterNestedUnion, ]; + pub const VARIANTS_STR: [&'static str; 23] = [ "Uint512", +"Uint513", +"Uint514", +"Str", +"Str2", +"Hash", +"Hashes1", +"Hashes2", +"Hashes3", +"OptHash1", +"OptHash2", +"Int1", +"Int2", +"Int3", +"Int4", +"MyStruct", +"LotsOfMyStructs", +"HasStuff", +"Color", +"Nester", +"NesterNestedEnum", +"NesterNestedStruct", +"NesterNestedUnion", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Uint512 => "Uint512", +Self::Uint513 => "Uint513", +Self::Uint514 => "Uint514", +Self::Str => "Str", +Self::Str2 => "Str2", +Self::Hash => "Hash", +Self::Hashes1 => "Hashes1", +Self::Hashes2 => "Hashes2", +Self::Hashes3 => "Hashes3", +Self::OptHash1 => "OptHash1", +Self::OptHash2 => "OptHash2", +Self::Int1 => "Int1", +Self::Int2 => "Int2", +Self::Int3 => "Int3", +Self::Int4 => "Int4", +Self::MyStruct => "MyStruct", +Self::LotsOfMyStructs => "LotsOfMyStructs", +Self::HasStuff => "HasStuff", +Self::Color => "Color", +Self::Nester => "Nester", +Self::NesterNestedEnum => "NesterNestedEnum", +Self::NesterNestedStruct => "NesterNestedStruct", +Self::NesterNestedUnion => "NesterNestedUnion", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 23] { + Self::VARIANTS + } + } + + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Uint512" => Ok(Self::Uint512), +"Uint513" => Ok(Self::Uint513), +"Uint514" => Ok(Self::Uint514), +"Str" => Ok(Self::Str), +"Str2" => Ok(Self::Str2), +"Hash" => Ok(Self::Hash), +"Hashes1" => Ok(Self::Hashes1), +"Hashes2" => Ok(Self::Hashes2), +"Hashes3" => Ok(Self::Hashes3), +"OptHash1" => Ok(Self::OptHash1), +"OptHash2" => Ok(Self::OptHash2), +"Int1" => Ok(Self::Int1), +"Int2" => Ok(Self::Int2), +"Int3" => Ok(Self::Int3), +"Int4" => Ok(Self::Int4), +"MyStruct" => Ok(Self::MyStruct), +"LotsOfMyStructs" => Ok(Self::LotsOfMyStructs), +"HasStuff" => Ok(Self::HasStuff), +"Color" => Ok(Self::Color), +"Nester" => Ok(Self::Nester), +"NesterNestedEnum" => Ok(Self::NesterNestedEnum), +"NesterNestedStruct" => Ok(Self::NesterNestedStruct), +"NesterNestedUnion" => Ok(Self::NesterNestedUnion), + _ => Err(Error::Invalid), + } + } + } + + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum Type { + Uint512(Box), +Uint513(Box), +Uint514(Box), +Str(Box), +Str2(Box), +Hash(Box), +Hashes1(Box), +Hashes2(Box), +Hashes3(Box), +OptHash1(Box), +OptHash2(Box), +Int1(Box), +Int2(Box), +Int3(Box), +Int4(Box), +MyStruct(Box), +LotsOfMyStructs(Box), +HasStuff(Box), +Color(Box), +Nester(Box), +NesterNestedEnum(Box), +NesterNestedStruct(Box), +NesterNestedUnion(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 23] = [ TypeVariant::Uint512, +TypeVariant::Uint513, +TypeVariant::Uint514, +TypeVariant::Str, +TypeVariant::Str2, +TypeVariant::Hash, +TypeVariant::Hashes1, +TypeVariant::Hashes2, +TypeVariant::Hashes3, +TypeVariant::OptHash1, +TypeVariant::OptHash2, +TypeVariant::Int1, +TypeVariant::Int2, +TypeVariant::Int3, +TypeVariant::Int4, +TypeVariant::MyStruct, +TypeVariant::LotsOfMyStructs, +TypeVariant::HasStuff, +TypeVariant::Color, +TypeVariant::Nester, +TypeVariant::NesterNestedEnum, +TypeVariant::NesterNestedStruct, +TypeVariant::NesterNestedUnion, ]; + pub const VARIANTS_STR: [&'static str; 23] = [ "Uint512", +"Uint513", +"Uint514", +"Str", +"Str2", +"Hash", +"Hashes1", +"Hashes2", +"Hashes3", +"OptHash1", +"OptHash2", +"Int1", +"Int2", +"Int3", +"Int4", +"MyStruct", +"LotsOfMyStructs", +"HasStuff", +"Color", +"Nester", +"NesterNestedEnum", +"NesterNestedStruct", +"NesterNestedUnion", ]; + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Uint512 => r.with_limited_depth(|r| Ok(Self::Uint512(Box::new(Uint512::read_xdr(r)?)))), +TypeVariant::Uint513 => r.with_limited_depth(|r| Ok(Self::Uint513(Box::new(Uint513::read_xdr(r)?)))), +TypeVariant::Uint514 => r.with_limited_depth(|r| Ok(Self::Uint514(Box::new(Uint514::read_xdr(r)?)))), +TypeVariant::Str => r.with_limited_depth(|r| Ok(Self::Str(Box::new(Str::read_xdr(r)?)))), +TypeVariant::Str2 => r.with_limited_depth(|r| Ok(Self::Str2(Box::new(Str2::read_xdr(r)?)))), +TypeVariant::Hash => r.with_limited_depth(|r| Ok(Self::Hash(Box::new(Hash::read_xdr(r)?)))), +TypeVariant::Hashes1 => r.with_limited_depth(|r| Ok(Self::Hashes1(Box::new(Hashes1::read_xdr(r)?)))), +TypeVariant::Hashes2 => r.with_limited_depth(|r| Ok(Self::Hashes2(Box::new(Hashes2::read_xdr(r)?)))), +TypeVariant::Hashes3 => r.with_limited_depth(|r| Ok(Self::Hashes3(Box::new(Hashes3::read_xdr(r)?)))), +TypeVariant::OptHash1 => r.with_limited_depth(|r| Ok(Self::OptHash1(Box::new(OptHash1::read_xdr(r)?)))), +TypeVariant::OptHash2 => r.with_limited_depth(|r| Ok(Self::OptHash2(Box::new(OptHash2::read_xdr(r)?)))), +TypeVariant::Int1 => r.with_limited_depth(|r| Ok(Self::Int1(Box::new(Int1::read_xdr(r)?)))), +TypeVariant::Int2 => r.with_limited_depth(|r| Ok(Self::Int2(Box::new(Int2::read_xdr(r)?)))), +TypeVariant::Int3 => r.with_limited_depth(|r| Ok(Self::Int3(Box::new(Int3::read_xdr(r)?)))), +TypeVariant::Int4 => r.with_limited_depth(|r| Ok(Self::Int4(Box::new(Int4::read_xdr(r)?)))), +TypeVariant::MyStruct => r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))), +TypeVariant::LotsOfMyStructs => r.with_limited_depth(|r| Ok(Self::LotsOfMyStructs(Box::new(LotsOfMyStructs::read_xdr(r)?)))), +TypeVariant::HasStuff => r.with_limited_depth(|r| Ok(Self::HasStuff(Box::new(HasStuff::read_xdr(r)?)))), +TypeVariant::Color => r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))), +TypeVariant::Nester => r.with_limited_depth(|r| Ok(Self::Nester(Box::new(Nester::read_xdr(r)?)))), +TypeVariant::NesterNestedEnum => r.with_limited_depth(|r| Ok(Self::NesterNestedEnum(Box::new(NesterNestedEnum::read_xdr(r)?)))), +TypeVariant::NesterNestedStruct => r.with_limited_depth(|r| Ok(Self::NesterNestedStruct(Box::new(NesterNestedStruct::read_xdr(r)?)))), +TypeVariant::NesterNestedUnion => r.with_limited_depth(|r| Ok(Self::NesterNestedUnion(Box::new(NesterNestedUnion::read_xdr(r)?)))), + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Uint512 => Box::new(ReadXdrIter::<_, Uint512>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Uint512(Box::new(t))))), +TypeVariant::Uint513 => Box::new(ReadXdrIter::<_, Uint513>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Uint513(Box::new(t))))), +TypeVariant::Uint514 => Box::new(ReadXdrIter::<_, Uint514>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Uint514(Box::new(t))))), +TypeVariant::Str => Box::new(ReadXdrIter::<_, Str>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Str(Box::new(t))))), +TypeVariant::Str2 => Box::new(ReadXdrIter::<_, Str2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Str2(Box::new(t))))), +TypeVariant::Hash => Box::new(ReadXdrIter::<_, Hash>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Hash(Box::new(t))))), +TypeVariant::Hashes1 => Box::new(ReadXdrIter::<_, Hashes1>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Hashes1(Box::new(t))))), +TypeVariant::Hashes2 => Box::new(ReadXdrIter::<_, Hashes2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Hashes2(Box::new(t))))), +TypeVariant::Hashes3 => Box::new(ReadXdrIter::<_, Hashes3>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Hashes3(Box::new(t))))), +TypeVariant::OptHash1 => Box::new(ReadXdrIter::<_, OptHash1>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::OptHash1(Box::new(t))))), +TypeVariant::OptHash2 => Box::new(ReadXdrIter::<_, OptHash2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::OptHash2(Box::new(t))))), +TypeVariant::Int1 => Box::new(ReadXdrIter::<_, Int1>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int1(Box::new(t))))), +TypeVariant::Int2 => Box::new(ReadXdrIter::<_, Int2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int2(Box::new(t))))), +TypeVariant::Int3 => Box::new(ReadXdrIter::<_, Int3>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int3(Box::new(t))))), +TypeVariant::Int4 => Box::new(ReadXdrIter::<_, Int4>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int4(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), +TypeVariant::LotsOfMyStructs => Box::new(ReadXdrIter::<_, LotsOfMyStructs>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::LotsOfMyStructs(Box::new(t))))), +TypeVariant::HasStuff => Box::new(ReadXdrIter::<_, HasStuff>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasStuff(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Nester => Box::new(ReadXdrIter::<_, Nester>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Nester(Box::new(t))))), +TypeVariant::NesterNestedEnum => Box::new(ReadXdrIter::<_, NesterNestedEnum>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::NesterNestedEnum(Box::new(t))))), +TypeVariant::NesterNestedStruct => Box::new(ReadXdrIter::<_, NesterNestedStruct>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::NesterNestedStruct(Box::new(t))))), +TypeVariant::NesterNestedUnion => Box::new(ReadXdrIter::<_, NesterNestedUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::NesterNestedUnion(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Uint512 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Uint512(Box::new(t.0))))), +TypeVariant::Uint513 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Uint513(Box::new(t.0))))), +TypeVariant::Uint514 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Uint514(Box::new(t.0))))), +TypeVariant::Str => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Str(Box::new(t.0))))), +TypeVariant::Str2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Str2(Box::new(t.0))))), +TypeVariant::Hash => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Hash(Box::new(t.0))))), +TypeVariant::Hashes1 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Hashes1(Box::new(t.0))))), +TypeVariant::Hashes2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Hashes2(Box::new(t.0))))), +TypeVariant::Hashes3 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Hashes3(Box::new(t.0))))), +TypeVariant::OptHash1 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::OptHash1(Box::new(t.0))))), +TypeVariant::OptHash2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::OptHash2(Box::new(t.0))))), +TypeVariant::Int1 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int1(Box::new(t.0))))), +TypeVariant::Int2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int2(Box::new(t.0))))), +TypeVariant::Int3 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int3(Box::new(t.0))))), +TypeVariant::Int4 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int4(Box::new(t.0))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t.0))))), +TypeVariant::LotsOfMyStructs => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::LotsOfMyStructs(Box::new(t.0))))), +TypeVariant::HasStuff => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasStuff(Box::new(t.0))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t.0))))), +TypeVariant::Nester => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Nester(Box::new(t.0))))), +TypeVariant::NesterNestedEnum => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::NesterNestedEnum(Box::new(t.0))))), +TypeVariant::NesterNestedStruct => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::NesterNestedStruct(Box::new(t.0))))), +TypeVariant::NesterNestedUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::NesterNestedUnion(Box::new(t.0))))), + } + } + + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Uint512 => Box::new(ReadXdrIter::<_, Uint512>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Uint512(Box::new(t))))), +TypeVariant::Uint513 => Box::new(ReadXdrIter::<_, Uint513>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Uint513(Box::new(t))))), +TypeVariant::Uint514 => Box::new(ReadXdrIter::<_, Uint514>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Uint514(Box::new(t))))), +TypeVariant::Str => Box::new(ReadXdrIter::<_, Str>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Str(Box::new(t))))), +TypeVariant::Str2 => Box::new(ReadXdrIter::<_, Str2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Str2(Box::new(t))))), +TypeVariant::Hash => Box::new(ReadXdrIter::<_, Hash>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Hash(Box::new(t))))), +TypeVariant::Hashes1 => Box::new(ReadXdrIter::<_, Hashes1>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Hashes1(Box::new(t))))), +TypeVariant::Hashes2 => Box::new(ReadXdrIter::<_, Hashes2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Hashes2(Box::new(t))))), +TypeVariant::Hashes3 => Box::new(ReadXdrIter::<_, Hashes3>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Hashes3(Box::new(t))))), +TypeVariant::OptHash1 => Box::new(ReadXdrIter::<_, OptHash1>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::OptHash1(Box::new(t))))), +TypeVariant::OptHash2 => Box::new(ReadXdrIter::<_, OptHash2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::OptHash2(Box::new(t))))), +TypeVariant::Int1 => Box::new(ReadXdrIter::<_, Int1>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int1(Box::new(t))))), +TypeVariant::Int2 => Box::new(ReadXdrIter::<_, Int2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int2(Box::new(t))))), +TypeVariant::Int3 => Box::new(ReadXdrIter::<_, Int3>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int3(Box::new(t))))), +TypeVariant::Int4 => Box::new(ReadXdrIter::<_, Int4>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int4(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), +TypeVariant::LotsOfMyStructs => Box::new(ReadXdrIter::<_, LotsOfMyStructs>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::LotsOfMyStructs(Box::new(t))))), +TypeVariant::HasStuff => Box::new(ReadXdrIter::<_, HasStuff>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::HasStuff(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Nester => Box::new(ReadXdrIter::<_, Nester>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Nester(Box::new(t))))), +TypeVariant::NesterNestedEnum => Box::new(ReadXdrIter::<_, NesterNestedEnum>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::NesterNestedEnum(Box::new(t))))), +TypeVariant::NesterNestedStruct => Box::new(ReadXdrIter::<_, NesterNestedStruct>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::NesterNestedStruct(Box::new(t))))), +TypeVariant::NesterNestedUnion => Box::new(ReadXdrIter::<_, NesterNestedUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::NesterNestedUnion(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } + + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Uint512 => Ok(Self::Uint512(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Uint513 => Ok(Self::Uint513(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Uint514 => Ok(Self::Uint514(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Str => Ok(Self::Str(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Str2 => Ok(Self::Str2(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Hash => Ok(Self::Hash(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Hashes1 => Ok(Self::Hashes1(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Hashes2 => Ok(Self::Hashes2(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Hashes3 => Ok(Self::Hashes3(Box::new(serde_json::from_reader(r)?))), +TypeVariant::OptHash1 => Ok(Self::OptHash1(Box::new(serde_json::from_reader(r)?))), +TypeVariant::OptHash2 => Ok(Self::OptHash2(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Int1 => Ok(Self::Int1(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Int2 => Ok(Self::Int2(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Int3 => Ok(Self::Int3(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Int4 => Ok(Self::Int4(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), +TypeVariant::LotsOfMyStructs => Ok(Self::LotsOfMyStructs(Box::new(serde_json::from_reader(r)?))), +TypeVariant::HasStuff => Ok(Self::HasStuff(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Nester => Ok(Self::Nester(Box::new(serde_json::from_reader(r)?))), +TypeVariant::NesterNestedEnum => Ok(Self::NesterNestedEnum(Box::new(serde_json::from_reader(r)?))), +TypeVariant::NesterNestedStruct => Ok(Self::NesterNestedStruct(Box::new(serde_json::from_reader(r)?))), +TypeVariant::NesterNestedUnion => Ok(Self::NesterNestedUnion(Box::new(serde_json::from_reader(r)?))), + } + } + + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Uint512(ref v) => v.as_ref(), +Self::Uint513(ref v) => v.as_ref(), +Self::Uint514(ref v) => v.as_ref(), +Self::Str(ref v) => v.as_ref(), +Self::Str2(ref v) => v.as_ref(), +Self::Hash(ref v) => v.as_ref(), +Self::Hashes1(ref v) => v.as_ref(), +Self::Hashes2(ref v) => v.as_ref(), +Self::Hashes3(ref v) => v.as_ref(), +Self::OptHash1(ref v) => v.as_ref(), +Self::OptHash2(ref v) => v.as_ref(), +Self::Int1(ref v) => v.as_ref(), +Self::Int2(ref v) => v.as_ref(), +Self::Int3(ref v) => v.as_ref(), +Self::Int4(ref v) => v.as_ref(), +Self::MyStruct(ref v) => v.as_ref(), +Self::LotsOfMyStructs(ref v) => v.as_ref(), +Self::HasStuff(ref v) => v.as_ref(), +Self::Color(ref v) => v.as_ref(), +Self::Nester(ref v) => v.as_ref(), +Self::NesterNestedEnum(ref v) => v.as_ref(), +Self::NesterNestedStruct(ref v) => v.as_ref(), +Self::NesterNestedUnion(ref v) => v.as_ref(), + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Uint512(_) => "Uint512", +Self::Uint513(_) => "Uint513", +Self::Uint514(_) => "Uint514", +Self::Str(_) => "Str", +Self::Str2(_) => "Str2", +Self::Hash(_) => "Hash", +Self::Hashes1(_) => "Hashes1", +Self::Hashes2(_) => "Hashes2", +Self::Hashes3(_) => "Hashes3", +Self::OptHash1(_) => "OptHash1", +Self::OptHash2(_) => "OptHash2", +Self::Int1(_) => "Int1", +Self::Int2(_) => "Int2", +Self::Int3(_) => "Int3", +Self::Int4(_) => "Int4", +Self::MyStruct(_) => "MyStruct", +Self::LotsOfMyStructs(_) => "LotsOfMyStructs", +Self::HasStuff(_) => "HasStuff", +Self::Color(_) => "Color", +Self::Nester(_) => "Nester", +Self::NesterNestedEnum(_) => "NesterNestedEnum", +Self::NesterNestedStruct(_) => "NesterNestedStruct", +Self::NesterNestedUnion(_) => "NesterNestedUnion", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 23] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Uint512(_) => TypeVariant::Uint512, +Self::Uint513(_) => TypeVariant::Uint513, +Self::Uint514(_) => TypeVariant::Uint514, +Self::Str(_) => TypeVariant::Str, +Self::Str2(_) => TypeVariant::Str2, +Self::Hash(_) => TypeVariant::Hash, +Self::Hashes1(_) => TypeVariant::Hashes1, +Self::Hashes2(_) => TypeVariant::Hashes2, +Self::Hashes3(_) => TypeVariant::Hashes3, +Self::OptHash1(_) => TypeVariant::OptHash1, +Self::OptHash2(_) => TypeVariant::OptHash2, +Self::Int1(_) => TypeVariant::Int1, +Self::Int2(_) => TypeVariant::Int2, +Self::Int3(_) => TypeVariant::Int3, +Self::Int4(_) => TypeVariant::Int4, +Self::MyStruct(_) => TypeVariant::MyStruct, +Self::LotsOfMyStructs(_) => TypeVariant::LotsOfMyStructs, +Self::HasStuff(_) => TypeVariant::HasStuff, +Self::Color(_) => TypeVariant::Color, +Self::Nester(_) => TypeVariant::Nester, +Self::NesterNestedEnum(_) => TypeVariant::NesterNestedEnum, +Self::NesterNestedStruct(_) => TypeVariant::NesterNestedStruct, +Self::NesterNestedUnion(_) => TypeVariant::NesterNestedUnion, + } + } + } + + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Uint512(v) => v.write_xdr(w), +Self::Uint513(v) => v.write_xdr(w), +Self::Uint514(v) => v.write_xdr(w), +Self::Str(v) => v.write_xdr(w), +Self::Str2(v) => v.write_xdr(w), +Self::Hash(v) => v.write_xdr(w), +Self::Hashes1(v) => v.write_xdr(w), +Self::Hashes2(v) => v.write_xdr(w), +Self::Hashes3(v) => v.write_xdr(w), +Self::OptHash1(v) => v.write_xdr(w), +Self::OptHash2(v) => v.write_xdr(w), +Self::Int1(v) => v.write_xdr(w), +Self::Int2(v) => v.write_xdr(w), +Self::Int3(v) => v.write_xdr(w), +Self::Int4(v) => v.write_xdr(w), +Self::MyStruct(v) => v.write_xdr(w), +Self::LotsOfMyStructs(v) => v.write_xdr(w), +Self::HasStuff(v) => v.write_xdr(w), +Self::Color(v) => v.write_xdr(w), +Self::Nester(v) => v.write_xdr(w), +Self::NesterNestedEnum(v) => v.write_xdr(w), +Self::NesterNestedStruct(v) => v.write_xdr(w), +Self::NesterNestedUnion(v) => v.write_xdr(w), + } + } + } diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs new file mode 100644 index 000000000..314534ca0 --- /dev/null +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -0,0 +1,3382 @@ +// Module is generated from: +// spec/fixtures/generator/union.x + +#![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] + +/// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/union.x", "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41") +]; + +use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; + +#[cfg(feature = "std")] +use core::marker::PhantomData; + +// When feature alloc is turned off use static lifetime Box and Vec types. +#[cfg(not(feature = "alloc"))] +mod noalloc { + pub mod boxed { + pub type Box = &'static T; + } + pub mod vec { + pub type Vec = &'static [T]; + } +} +#[cfg(not(feature = "alloc"))] +use noalloc::{boxed::Box, vec::Vec}; + +// When feature std is turned off, but feature alloc is turned on import the +// alloc crate and use its Box and Vec types. +#[cfg(all(not(feature = "std"), feature = "alloc"))] +extern crate alloc; +#[cfg(all(not(feature = "std"), feature = "alloc"))] +use alloc::{ + borrow::ToOwned, + boxed::Box, + string::{FromUtf8Error, String}, + vec::Vec, +}; +#[cfg(feature = "std")] +use std::string::FromUtf8Error; + +#[cfg(feature = "arbitrary")] +use arbitrary::Arbitrary; + +// TODO: Add support for read/write xdr fns when std not available. + +#[cfg(feature = "std")] +use std::{ + error, io, + io::{BufRead, BufReader, Cursor, Read, Write}, +}; + +/// Error contains all errors returned by functions in this crate. It can be +/// compared via `PartialEq`, however any contained IO errors will only be +/// compared on their `ErrorKind`. +#[derive(Debug)] +pub enum Error { + Invalid, + Unsupported, + LengthExceedsMax, + LengthMismatch, + NonZeroPadding, + Utf8Error(core::str::Utf8Error), + #[cfg(feature = "alloc")] + InvalidHex, + #[cfg(feature = "std")] + Io(io::Error), + DepthLimitExceeded, + #[cfg(feature = "serde_json")] + Json(serde_json::Error), + LengthLimitExceeded, +} + +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Utf8Error(l), Self::Utf8Error(r)) => l == r, + // IO errors cannot be compared, but in the absence of any more + // meaningful way to compare the errors we compare the kind of error + // and ignore the embedded source error or OS error. The main use + // case for comparing errors outputted by the XDR library is for + // error case testing, and a lack of the ability to compare has a + // detrimental affect on failure testing, so this is a tradeoff. + #[cfg(feature = "std")] + (Self::Io(l), Self::Io(r)) => l.kind() == r.kind(), + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + #[must_use] + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Io(e) => Some(e), + #[cfg(feature = "serde_json")] + Self::Json(e) => Some(e), + _ => None, + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::Invalid => write!(f, "xdr value invalid"), + Error::Unsupported => write!(f, "xdr value unsupported"), + Error::LengthExceedsMax => write!(f, "xdr value max length exceeded"), + Error::LengthMismatch => write!(f, "xdr value length does not match"), + Error::NonZeroPadding => write!(f, "xdr padding contains non-zero bytes"), + Error::Utf8Error(e) => write!(f, "{e}"), + #[cfg(feature = "alloc")] + Error::InvalidHex => write!(f, "hex invalid"), + #[cfg(feature = "std")] + Error::Io(e) => write!(f, "{e}"), + Error::DepthLimitExceeded => write!(f, "depth limit exceeded"), + #[cfg(feature = "serde_json")] + Error::Json(e) => write!(f, "{e}"), + Error::LengthLimitExceeded => write!(f, "length limit exceeded"), + } + } +} + +impl From for Error { + fn from(_: TryFromSliceError) -> Error { + Error::LengthMismatch + } +} + +impl From for Error { + #[must_use] + fn from(e: core::str::Utf8Error) -> Self { + Error::Utf8Error(e) + } +} + +#[cfg(feature = "alloc")] +impl From for Error { + #[must_use] + fn from(e: FromUtf8Error) -> Self { + Error::Utf8Error(e.utf8_error()) + } +} + +#[cfg(feature = "std")] +impl From for Error { + #[must_use] + fn from(e: io::Error) -> Self { + Error::Io(e) + } +} + +#[cfg(feature = "serde_json")] +impl From for Error { + #[must_use] + fn from(e: serde_json::Error) -> Self { + Error::Json(e) + } +} + +impl From for () { + fn from(_: Error) {} +} + +#[allow(dead_code)] +type Result = core::result::Result; + +/// Name defines types that assign a static name to their value, such as the +/// name given to an identifier in an XDR enum, or the name given to the case in +/// a union. +pub trait Name { + fn name(&self) -> &'static str; +} + +/// Discriminant defines types that may contain a one-of value determined +/// according to the discriminant, and exposes the value of the discriminant for +/// that type, such as in an XDR union. +pub trait Discriminant { + fn discriminant(&self) -> D; +} + +/// Iter defines types that have variants that can be iterated. +pub trait Variants { + fn variants() -> slice::Iter<'static, V> + where + V: Sized; +} + +// Enum defines a type that is represented as an XDR enumeration when encoded. +pub trait Enum: Name + Variants + Sized {} + +// Union defines a type that is represented as an XDR union when encoded. +pub trait Union: Name + Discriminant + Variants +where + D: Sized, +{ +} + +/// `Limits` contains the limits that a limited reader or writer will be +/// constrained to. +#[cfg(feature = "std")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Limits { + /// Defines the maximum depth for recursive calls in `Read/WriteXdr` to + /// prevent stack overflow. + /// + /// The depth limit is akin to limiting stack depth. Its purpose is to + /// prevent the program from hitting the maximum stack size allowed by Rust, + /// which would result in an unrecoverable `SIGABRT`. For more information + /// about Rust's stack size limit, refer to the [Rust + /// documentation](https://doc.rust-lang.org/std/thread/#stack-size). + pub depth: u32, + + /// Defines the maximum number of bytes that will be read or written. + pub len: usize, +} + +#[cfg(feature = "std")] +impl Limits { + #[must_use] + pub fn none() -> Self { + Self { + depth: u32::MAX, + len: usize::MAX, + } + } + + #[must_use] + pub fn depth(depth: u32) -> Self { + Limits { + depth, + ..Limits::none() + } + } + + #[must_use] + pub fn len(len: usize) -> Self { + Limits { + len, + ..Limits::none() + } + } +} + +/// `Limited` wraps an object and provides functions for enforcing limits. +/// +/// Intended for use with readers and writers and limiting their reads and +/// writes. +#[cfg(feature = "std")] +pub struct Limited { + pub inner: L, + pub(crate) limits: Limits, +} + +#[cfg(feature = "std")] +impl Limited { + /// Constructs a new `Limited`. + /// + /// - `inner`: The value being limited. + /// - `limits`: The limits to enforce. + pub fn new(inner: L, limits: Limits) -> Self { + Limited { inner, limits } + } + + /// Consume the given length from the internal remaining length limit. + /// + /// ### Errors + /// + /// If the length would consume more length than the remaining length limit + /// allows. + pub(crate) fn consume_len(&mut self, len: usize) -> Result<()> { + if let Some(len) = self.limits.len.checked_sub(len) { + self.limits.len = len; + Ok(()) + } else { + Err(Error::LengthLimitExceeded) + } + } + + /// Consumes a single depth for the duration of the given function. + /// + /// ### Errors + /// + /// If the depth limit is already exhausted. + pub(crate) fn with_limited_depth(&mut self, f: F) -> Result + where + F: FnOnce(&mut Self) -> Result, + { + if let Some(depth) = self.limits.depth.checked_sub(1) { + self.limits.depth = depth; + let res = f(self); + self.limits.depth = self.limits.depth.saturating_add(1); + res + } else { + Err(Error::DepthLimitExceeded) + } + } +} + +#[cfg(feature = "std")] +impl Read for Limited { + /// Forwards the read operation to the wrapped object. + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.inner.read(buf) + } +} + +#[cfg(feature = "std")] +impl BufRead for Limited { + /// Forwards the read operation to the wrapped object. + fn fill_buf(&mut self) -> std::io::Result<&[u8]> { + self.inner.fill_buf() + } + + /// Forwards the read operation to the wrapped object. + fn consume(&mut self, amt: usize) { + self.inner.consume(amt); + } +} + +#[cfg(feature = "std")] +impl Write for Limited { + /// Forwards the write operation to the wrapped object. + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.inner.write(buf) + } + + /// Forwards the flush operation to the wrapped object. + fn flush(&mut self) -> std::io::Result<()> { + self.inner.flush() + } +} + +#[cfg(feature = "std")] +pub struct ReadXdrIter { + reader: Limited>, + _s: PhantomData, +} + +#[cfg(feature = "std")] +impl ReadXdrIter { + fn new(r: R, limits: Limits) -> Self { + Self { + reader: Limited { + inner: BufReader::new(r), + limits, + }, + _s: PhantomData, + } + } +} + +#[cfg(feature = "std")] +impl Iterator for ReadXdrIter { + type Item = Result; + + // Next reads the internal reader and XDR decodes it into the Self type. If + // the EOF is reached without reading any new bytes `None` is returned. If + // EOF is reached after reading some bytes a truncated entry is assumed an + // an `Error::Io` containing an `UnexpectedEof`. If any other IO error + // occurs it is returned. Iteration of this iterator stops naturally when + // `None` is returned, but not when a `Some(Err(...))` is returned. The + // caller is responsible for checking each Result. + fn next(&mut self) -> Option { + // Try to fill the buffer to see if the EOF has been reached or not. + // This happens to effectively peek to see if the stream has finished + // and there are no more items. It is necessary to do this because the + // xdr types in this crate heavily use the `std::io::Read::read_exact` + // method that doesn't distinguish between an EOF at the beginning of a + // read and an EOF after a partial fill of a read_exact. + match self.reader.fill_buf() { + // If the reader has no more data and is unable to fill any new data + // into its internal buf, then the EOF has been reached. + Ok([]) => return None, + // If an error occurs filling the buffer, treat that as an error and stop. + Err(e) => return Some(Err(Error::Io(e))), + // If there is data in the buf available for reading, continue. + Ok([..]) => (), + }; + // Read the buf into the type. + let r = self.reader.with_limited_depth(|dlr| S::read_xdr(dlr)); + match r { + Ok(s) => Some(Ok(s)), + Err(e) => Some(Err(e)), + } + } +} + +pub trait ReadXdr +where + Self: Sized, +{ + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_to_end`] when the intent is for all bytes in the + /// read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result; + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_to_end(r: &mut Limited) -> Result { + let s = Self::read_xdr(r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn read_xdr_base64_to_end(r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } + + /// Read the XDR and construct the type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type. Any residual bytes remain in the read implementation. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + /// + /// Use [`ReadXdR: Read_xdr_into_to_end`] when the intent is for all bytes + /// in the read implementation to be consumed by the read. + #[cfg(feature = "std")] + fn read_xdr_into(&mut self, r: &mut Limited) -> Result<()> { + *self = Self::read_xdr(r)?; + Ok(()) + } + + /// Read the XDR into the existing value, and consider it an error if the + /// read does not completely consume the read implementation. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_into_to_end(&mut self, r: &mut Limited) -> Result<()> { + Self::read_xdr_into(self, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(()) + } else { + Err(Error::Invalid) + } + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + /// + /// Read bytes from the given read implementation, decoding the bytes as + /// XDR, and construct the type implementing this interface from those + /// bytes. + /// + /// Just enough bytes are read from the read implementation to construct the + /// type, and then confirm that no further bytes remain. To confirm no + /// further bytes remain additional bytes are attempted to be read from the + /// read implementation. If it is possible to read any residual bytes from + /// the read implementation an error is returned. The read implementation + /// may not be exhaustively read if there are residual bytes, and it is + /// considered undefined how many residual bytes or how much of the residual + /// buffer are consumed in this case. + /// + /// All implementations should continue if the read implementation returns + /// [`ErrorKind::Interrupted`](std::io::ErrorKind::Interrupted). + #[cfg(feature = "std")] + fn read_xdr_iter(r: &mut Limited) -> ReadXdrIter<&mut R, Self> { + ReadXdrIter::new(&mut r.inner, r.limits.clone()) + } + + /// Create an iterator that reads the read implementation as a stream of + /// values that are read into the implementing type. + #[cfg(feature = "base64")] + fn read_xdr_base64_iter( + r: &mut Limited, + ) -> ReadXdrIter, Self> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + ReadXdrIter::new(dec, r.limits.clone()) + } + + /// Construct the type from the XDR bytes. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "std")] + fn from_xdr(bytes: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(&mut cursor)?; + Ok(t) + } + + /// Construct the type from the XDR bytes base64 encoded. + /// + /// An error is returned if the bytes are not completely consumed by the + /// deserialization. + #[cfg(feature = "base64")] + fn from_xdr_base64(b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(&mut dec)?; + Ok(t) + } +} + +pub trait WriteXdr { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()>; + + #[cfg(feature = "std")] + fn to_xdr(&self, limits: Limits) -> Result> { + let mut cursor = Limited::new(Cursor::new(vec![]), limits); + self.write_xdr(&mut cursor)?; + let bytes = cursor.inner.into_inner(); + Ok(bytes) + } + + #[cfg(feature = "base64")] + fn to_xdr_base64(&self, limits: Limits) -> Result { + let mut enc = Limited::new( + base64::write::EncoderStringWriter::new(base64::STANDARD), + limits, + ); + self.write_xdr(&mut enc)?; + let b64 = enc.inner.into_inner(); + Ok(b64) + } +} + +/// `Pad_len` returns the number of bytes to pad an XDR value of the given +/// length to make the final serialized size a multiple of 4. +#[cfg(feature = "std")] +fn pad_len(len: usize) -> usize { + (4 - (len % 4)) % 4 +} + +impl ReadXdr for i32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u32 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 4]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u32::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u32 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 4] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for i64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(i64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for i64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for u64 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + let mut b = [0u8; 8]; + r.with_limited_depth(|r| { + r.consume_len(b.len())?; + r.read_exact(&mut b)?; + Ok(u64::from_be_bytes(b)) + }) + } +} + +impl WriteXdr for u64 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + let b: [u8; 8] = self.to_be_bytes(); + w.with_limited_depth(|w| { + w.consume_len(b.len())?; + Ok(w.write_all(&b)?) + }) + } +} + +impl ReadXdr for f32 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f32 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for f64 { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + todo!() + } +} + +impl WriteXdr for f64 { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + todo!() + } +} + +impl ReadXdr for bool { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + let b = i == 1; + Ok(b) + }) + } +} + +impl WriteXdr for bool { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i = u32::from(*self); // true = 1, false = 0 + i.write_xdr(w) + }) + } +} + +impl ReadXdr for Option { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = u32::read_xdr(r)?; + match i { + 0 => Ok(None), + 1 => { + let t = T::read_xdr(r)?; + Ok(Some(t)) + } + _ => Err(Error::Invalid), + } + }) + } +} + +impl WriteXdr for Option { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + if let Some(t) = self { + 1u32.write_xdr(w)?; + t.write_xdr(w)?; + } else { + 0u32.write_xdr(w)?; + } + Ok(()) + }) + } +} + +impl ReadXdr for Box { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| Ok(Box::new(T::read_xdr(r)?))) + } +} + +impl WriteXdr for Box { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| T::write_xdr(self, w)) + } +} + +impl ReadXdr for () { + #[cfg(feature = "std")] + fn read_xdr(_r: &mut Limited) -> Result { + Ok(()) + } +} + +impl WriteXdr for () { + #[cfg(feature = "std")] + fn write_xdr(&self, _w: &mut Limited) -> Result<()> { + Ok(()) + } +} + +impl ReadXdr for [u8; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + r.consume_len(N)?; + let padding = pad_len(N); + r.consume_len(padding)?; + let mut arr = [0u8; N]; + r.read_exact(&mut arr)?; + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + Ok(arr) + }) + } +} + +impl WriteXdr for [u8; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + w.consume_len(N)?; + let padding = pad_len(N); + w.consume_len(padding)?; + w.write_all(self)?; + w.write_all(&[0u8; 3][..padding])?; + Ok(()) + }) + } +} + +impl ReadXdr for [T; N] { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let mut vec = Vec::with_capacity(N); + for _ in 0..N { + let t = T::read_xdr(r)?; + vec.push(t); + } + let arr: [T; N] = vec.try_into().unwrap_or_else(|_: Vec| unreachable!()); + Ok(arr) + }) + } +} + +impl WriteXdr for [T; N] { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + for t in self { + t.write_xdr(w)?; + } + Ok(()) + }) + } +} + +// VecM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct VecM(Vec) +where + T: 'static; + +impl Deref for VecM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for VecM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl VecM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl VecM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl VecM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl VecM { + #[must_use] + pub fn to_option(&self) -> Option { + if self.len() > 0 { + Some(self.0[0].clone()) + } else { + None + } + } +} + +#[cfg(not(feature = "alloc"))] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.to_option() + } +} + +#[cfg(feature = "alloc")] +impl VecM { + #[must_use] + pub fn into_option(mut self) -> Option { + self.0.drain(..).next() + } +} + +#[cfg(feature = "alloc")] +impl From> for Option { + #[must_use] + fn from(v: VecM) -> Self { + v.into_option() + } +} + +impl TryFrom> for VecM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: VecM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&VecM> for Vec { + #[must_use] + fn from(v: &VecM) -> Self { + v.0.clone() + } +} + +impl AsRef> for VecM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for VecM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T]> for VecM { + type Error = Error; + + fn try_from(v: &[T]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[T]> for VecM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[T] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[T; N]> for VecM { + type Error = Error; + + fn try_from(v: [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [T; N] { + type Error = VecM; + + fn try_from(v: VecM) -> core::result::Result { + let s: [T; N] = v.0.try_into().map_err(|v: Vec| VecM::(v))?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[T; N]> for VecM { + type Error = Error; + + fn try_from(v: &[T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [T; N]> for VecM { + type Error = Error; + + fn try_from(v: &'static [T; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for VecM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for VecM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: VecM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&VecM> for String { + type Error = Error; + + fn try_from(v: &VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for VecM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for VecM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(VecM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a VecM> for &'a str { + type Error = Error; + + fn try_from(v: &'a VecM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +impl ReadXdr for VecM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + let mut vec = Vec::new(); + for _ in 0..len { + let t = T::read_xdr(r)?; + vec.push(t); + } + + Ok(VecM(vec)) + }) + } +} + +impl WriteXdr for VecM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + for t in &self.0 { + t.write_xdr(w)?; + } + + Ok(()) + }) + } +} + +// BytesM ------------------------------------------------------------------------ + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct BytesM(Vec); + +impl core::fmt::Display for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in v { + write!(f, "{b:02x}")?; + } + Ok(()) + } +} + +impl core::fmt::Debug for BytesM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "BytesM(")?; + for b in v { + write!(f, "{b:02x}")?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for BytesM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() + } +} + +impl Deref for BytesM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for BytesM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl BytesM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl BytesM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl BytesM { + #[cfg(feature = "alloc")] + pub fn to_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for BytesM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: BytesM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&BytesM> for Vec { + #[must_use] + fn from(v: &BytesM) -> Self { + v.0.clone() + } +} + +impl AsRef> for BytesM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for BytesM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for BytesM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = BytesM; + + fn try_from(v: BytesM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(BytesM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for BytesM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for BytesM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for BytesM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: BytesM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&BytesM> for String { + type Error = Error; + + fn try_from(v: &BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for BytesM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for BytesM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(BytesM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a BytesM> for &'a str { + type Error = Error; + + fn try_from(v: &'a BytesM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for BytesM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(BytesM(vec)) + }) + } +} + +impl WriteXdr for BytesM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..pad_len(len as usize)])?; + + Ok(()) + }) + } +} + +// StringM ------------------------------------------------------------------------ + +/// A string type that contains arbitrary bytes. +/// +/// Convertible, fallibly, to/from a Rust UTF-8 String using +/// [`TryFrom`]/[`TryInto`]/[`StringM::to_utf8_string`]. +/// +/// Convertible, lossyly, to a Rust UTF-8 String using +/// [`StringM::to_utf8_string_lossy`]. +/// +/// Convertible to/from escaped printable-ASCII using +/// [`Display`]/[`ToString`]/[`FromStr`]. + +#[cfg(feature = "alloc")] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + feature = "serde", + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +#[cfg(not(feature = "alloc"))] +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +pub struct StringM(Vec); + +impl core::fmt::Display for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + Ok(()) + } +} + +impl core::fmt::Debug for StringM { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + #[cfg(feature = "alloc")] + let v = &self.0; + #[cfg(not(feature = "alloc"))] + let v = self.0; + write!(f, "StringM(")?; + for b in escape_bytes::Escape::new(v) { + write!(f, "{}", b as char)?; + } + write!(f, ")")?; + Ok(()) + } +} + +#[cfg(feature = "alloc")] +impl core::str::FromStr for StringM { + type Err = Error; + fn from_str(s: &str) -> core::result::Result { + let b = escape_bytes::unescape(s.as_bytes()).map_err(|_| Error::Invalid)?; + Ok(Self(b)) + } +} + +impl Deref for StringM { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Default for StringM { + fn default() -> Self { + Self(Vec::default()) + } +} + +impl StringM { + pub const MAX_LEN: usize = { MAX as usize }; + + #[must_use] + #[allow(clippy::unused_self)] + pub fn max_len(&self) -> usize { + Self::MAX_LEN + } + + #[must_use] + pub fn as_vec(&self) -> &Vec { + self.as_ref() + } +} + +impl StringM { + #[must_use] + #[cfg(feature = "alloc")] + pub fn to_vec(&self) -> Vec { + self.into() + } + + #[must_use] + pub fn into_vec(self) -> Vec { + self.into() + } +} + +impl StringM { + #[cfg(feature = "alloc")] + pub fn to_utf8_string(&self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + pub fn into_utf8_string(self) -> Result { + self.try_into() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn to_utf8_string_lossy(&self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn into_utf8_string_lossy(self) -> String { + String::from_utf8_lossy(&self.0).into_owned() + } +} + +impl TryFrom> for StringM { + type Error = Error; + + fn try_from(v: Vec) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl From> for Vec { + #[must_use] + fn from(v: StringM) -> Self { + v.0 + } +} + +#[cfg(feature = "alloc")] +impl From<&StringM> for Vec { + #[must_use] + fn from(v: &StringM) -> Self { + v.0.clone() + } +} + +impl AsRef> for StringM { + #[must_use] + fn as_ref(&self) -> &Vec { + &self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&Vec> for StringM { + type Error = Error; + + fn try_from(v: &Vec) -> Result { + v.as_slice().try_into() + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8]> for StringM { + type Error = Error; + + fn try_from(v: &[u8]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl AsRef<[u8]> for StringM { + #[cfg(feature = "alloc")] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } + #[cfg(not(feature = "alloc"))] + #[must_use] + fn as_ref(&self) -> &[u8] { + self.0 + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for [u8; N] { + type Error = StringM; + + fn try_from(v: StringM) -> core::result::Result { + let s: [u8; N] = v.0.try_into().map_err(StringM::)?; + Ok(s) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&[u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &[u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static [u8; N]> for StringM { + type Error = Error; + + fn try_from(v: &'static [u8; N]) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v)) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&String> for StringM { + type Error = Error; + + fn try_from(v: &String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes().to_vec())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom for StringM { + type Error = Error; + + fn try_from(v: String) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(feature = "alloc")] +impl TryFrom> for String { + type Error = Error; + + fn try_from(v: StringM) -> Result { + Ok(String::from_utf8(v.0)?) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&StringM> for String { + type Error = Error; + + fn try_from(v: &StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?.to_owned()) + } +} + +#[cfg(feature = "alloc")] +impl TryFrom<&str> for StringM { + type Error = Error; + + fn try_from(v: &str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.into())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +#[cfg(not(feature = "alloc"))] +impl TryFrom<&'static str> for StringM { + type Error = Error; + + fn try_from(v: &'static str) -> Result { + let len: u32 = v.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + if len <= MAX { + Ok(StringM(v.as_bytes())) + } else { + Err(Error::LengthExceedsMax) + } + } +} + +impl<'a, const MAX: u32> TryFrom<&'a StringM> for &'a str { + type Error = Error; + + fn try_from(v: &'a StringM) -> Result { + Ok(core::str::from_utf8(v.as_ref())?) + } +} + +impl ReadXdr for StringM { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let len: u32 = u32::read_xdr(r)?; + if len > MAX { + return Err(Error::LengthExceedsMax); + } + + r.consume_len(len as usize)?; + let padding = pad_len(len as usize); + r.consume_len(padding)?; + + let mut vec = vec![0u8; len as usize]; + r.read_exact(&mut vec)?; + + let pad = &mut [0u8; 3][..padding]; + r.read_exact(pad)?; + if pad.iter().any(|b| *b != 0) { + return Err(Error::NonZeroPadding); + } + + Ok(StringM(vec)) + }) + } +} + +impl WriteXdr for StringM { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let len: u32 = self.len().try_into().map_err(|_| Error::LengthExceedsMax)?; + len.write_xdr(w)?; + + w.consume_len(self.len())?; + let padding = pad_len(self.len()); + w.consume_len(padding)?; + + w.write_all(&self.0)?; + + w.write_all(&[0u8; 3][..padding])?; + + Ok(()) + }) + } +} + +// Frame ------------------------------------------------------------------------ + +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +pub struct Frame(pub T) +where + T: ReadXdr; + +impl ReadXdr for Frame +where + T: ReadXdr, +{ + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + // Read the frame header value that contains 1 flag-bit and a 33-bit length. + // - The 1 flag bit is 0 when there are more frames for the same record. + // - The 31-bit length is the length of the bytes within the frame that + // follow the frame header. + let header = u32::read_xdr(r)?; + // TODO: Use the length and cap the length we'll read from `r`. + let last_record = header >> 31 == 1; + if last_record { + // Read the record in the frame. + Ok(Self(T::read_xdr(r)?)) + } else { + // TODO: Support reading those additional frames for the same + // record. + Err(Error::Unsupported) + } + } +} + +#[cfg(all(test, feature = "std"))] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + pub fn vec_u8_read_without_padding() { + let buf = Cursor::new(vec![0, 0, 0, 4, 2, 2, 2, 2]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_read_with_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0, 0]); + let v = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v.to_vec(), vec![2]); + } + + #[test] + pub fn vec_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn vec_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![0, 0, 0, 1, 2, 3, 0, 0]); + let res = VecM::::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn vec_u8_write_without_padding() { + let mut buf = vec![]; + let v: VecM = vec![2, 2, 2, 2].try_into().unwrap(); + + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 4, 2, 2, 2, 2]); + } + + #[test] + pub fn vec_u8_write_with_padding() { + let mut buf = vec![]; + let v: VecM = vec![2].try_into().unwrap(); + v.write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![0, 0, 0, 1, 2, 0, 0, 0]); + } + + #[test] + pub fn arr_u8_read_without_padding() { + let buf = Cursor::new(vec![2, 2, 2, 2]); + let v = <[u8; 4]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_read_with_padding() { + let buf = Cursor::new(vec![2, 0, 0, 0]); + let v = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())).unwrap(); + assert_eq!(v, [2]); + } + + #[test] + pub fn arr_u8_read_with_insufficient_padding() { + let buf = Cursor::new(vec![2, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::Io(_)) => (), + _ => panic!("expected IO error got {res:?}"), + } + } + + #[test] + pub fn arr_u8_read_with_non_zero_padding() { + let buf = Cursor::new(vec![2, 3, 0, 0]); + let res = <[u8; 1]>::read_xdr(&mut Limited::new(buf, Limits::none())); + match res { + Err(Error::NonZeroPadding) => (), + _ => panic!("expected NonZeroPadding got {res:?}"), + } + } + + #[test] + pub fn arr_u8_write_without_padding() { + let mut buf = vec![]; + [2u8, 2, 2, 2] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 2, 2, 2]); + } + + #[test] + pub fn arr_u8_write_with_padding() { + let mut buf = vec![]; + [2u8] + .write_xdr(&mut Limited::new(Cursor::new(&mut buf), Limits::none())) + .unwrap(); + assert_eq!(buf, vec![2, 0, 0, 0]); + } +} + +#[cfg(all(test, feature = "std"))] +mod test { + use super::*; + + #[test] + fn into_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.into_option(), None); + } + + #[test] + fn into_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.into_option(), Some(1)); + } + + #[test] + fn to_option_none() { + let v: VecM = vec![].try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = vec![1].try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } + + #[test] + fn depth_limited_read_write_under_the_limit_success() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(4)); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::depth(4)); + let a_back: Option>> = ReadXdr::read_xdr(&mut dlr).unwrap(); + assert_eq!(a, a_back); + } + + #[test] + fn write_over_depth_limit_fail() { + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), Limits::depth(3)); + let res = a.write_xdr(&mut buf); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn read_over_depth_limit_fail() { + let read_limits = Limits::depth(3); + let write_limits = Limits::depth(5); + let a: Option>> = Some(Some(Some(5))); + let mut buf = Limited::new(Vec::new(), write_limits); + a.write_xdr(&mut buf).unwrap(); + + let mut dlr = Limited::new(Cursor::new(buf.inner.as_slice()), read_limits); + let res: Result>>> = ReadXdr::read_xdr(&mut dlr); + match res { + Err(Error::DepthLimitExceeded) => (), + _ => panic!("expected DepthLimitExceeded got {res:?}"), + } + } + + #[test] + fn length_limited_read_write_i32() { + // Exact limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: i32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u32() { + // Exact limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: u32 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u32; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_i64() { + // Exact limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: i64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123i64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_u64() { + // Exact limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: u64 = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = 123u64; + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bool() { + // Exact limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: bool = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = true; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + ::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_option() { + // Exact limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: Option = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = Some(true); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_u8() { + // Exact limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(4)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(5)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(5)); + let v_back: [u8; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(3)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [1u8, 2, 3]; + let mut buf = Limited::new(Vec::new(), Limits::len(4)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(3)); + assert_eq!( + <[u8; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_array_type() { + // Exact limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(12)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(13)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(13)); + let v_back: [bool; 3] = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(11)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = [true, false, true]; + let mut buf = Limited::new(Vec::new(), Limits::len(12)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(11)); + assert_eq!( + <[bool; 3] as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_vec() { + // Exact limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(16)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(17)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(17)); + let v_back: VecM = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(15)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = VecM::::try_from([1i32, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(16)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(15)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_bytes() { + // Exact limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: BytesM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = BytesM::<3>::try_from([1u8, 2, 3]).unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } + + #[test] + fn length_limited_read_write_string() { + // Exact limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(8)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 0); + assert_eq!(v, v_back); + + // Over limit, success + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(9)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 1); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(9)); + let v_back: StringM<3> = ReadXdr::read_xdr(&mut lr).unwrap(); + assert_eq!(buf.limits.len, 1); + assert_eq!(v, v_back); + + // Write under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(7)); + assert_eq!(v.write_xdr(&mut buf), Err(Error::LengthLimitExceeded)); + + // Read under limit, failure + let v = StringM::<3>::try_from("123").unwrap(); + let mut buf = Limited::new(Vec::new(), Limits::len(8)); + v.write_xdr(&mut buf).unwrap(); + assert_eq!(buf.limits.len, 0); + let mut lr = Limited::new(Cursor::new(buf.inner.as_slice()), Limits::len(7)); + assert_eq!( + as ReadXdr>::read_xdr(&mut lr), + Err(Error::LengthLimitExceeded) + ); + } +} + +#[cfg(all(test, not(feature = "alloc")))] +mod test { + use super::VecM; + + #[test] + fn to_option_none() { + let v: VecM = (&[]).try_into().unwrap(); + assert_eq!(v.to_option(), None); + } + + #[test] + fn to_option_some() { + let v: VecM<_, 1> = (&[1]).try_into().unwrap(); + assert_eq!(v.to_option(), Some(1)); + } +} + +/// SError is an XDR Typedef defines as: +/// +/// ```text +/// typedef int Error; +/// ``` +/// +pub type SError = i32; + +/// Multi is an XDR Typedef defines as: +/// +/// ```text +/// typedef int Multi; +/// ``` +/// +pub type Multi = i32; + +/// UnionKey is an XDR Enum defines as: +/// +/// ```text +/// enum UnionKey { +/// ERROR, +/// MULTI +/// }; +/// ``` +/// +// enum +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[repr(i32)] +pub enum UnionKey { + Error = 0, + Multi = 1, +} + + impl UnionKey { + pub const VARIANTS: [UnionKey; 2] = [ UnionKey::Error, +UnionKey::Multi, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Error", +"Multi", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error => "Error", +Self::Multi => "Multi", + } + } + + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } + } + + impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } + + impl Enum for UnionKey {} + + impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } + + impl TryFrom for UnionKey { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 0 => UnionKey::Error, +1 => UnionKey::Multi, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } + + impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } + } + + impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } + + impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } + +/// MyUnion is an XDR Union defines as: +/// +/// ```text +/// union MyUnion switch (UnionKey type) +/// { +/// case ERROR: +/// Error error; +/// case MULTI: +/// Multi things<>; +/// +/// +/// }; +/// ``` +/// +// union with discriminant UnionKey +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[allow(clippy::large_enum_variant)] +pub enum MyUnion { + Error(i32), + Multi(VecM::), +} + + impl MyUnion { + pub const VARIANTS: [UnionKey; 2] = [ + UnionKey::Error, +UnionKey::Multi, + ]; + pub const VARIANTS_STR: [&'static str; 2] = [ + "Error", +"Multi", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error(_) => "Error", +Self::Multi(_) => "Multi", + } + } + + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::Error(_) => UnionKey::Error, +Self::Multi(_) => UnionKey::Multi, + } + } + + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } + } + + impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } + } + + impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } + + impl Union for MyUnion {} + + impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::Error => Self::Error(i32::read_xdr(r)?), +UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } + + impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::Error(v) => v.write_xdr(w)?, +Self::Multi(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } + } + +/// IntUnion is an XDR Union defines as: +/// +/// ```text +/// union IntUnion switch (int type) +/// { +/// case 0: +/// Error error; +/// case 1: +/// Multi things<>; +/// +/// }; +/// ``` +/// +// union with discriminant i32 +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[allow(clippy::large_enum_variant)] +pub enum IntUnion { + V0(i32), + V1(VecM::), +} + + impl IntUnion { + pub const VARIANTS: [i32; 2] = [ + 0, +1, + ]; + pub const VARIANTS_STR: [&'static str; 2] = [ + "V0", +"V1", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::V0(_) => "V0", +Self::V1(_) => "V1", + } + } + + #[must_use] + pub const fn discriminant(&self) -> i32 { + #[allow(clippy::match_same_arms)] + match self { + Self::V0(_) => 0, +Self::V1(_) => 1, + } + } + + #[must_use] + pub const fn variants() -> [i32; 2] { + Self::VARIANTS + } + } + + impl Name for IntUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Discriminant for IntUnion { + #[must_use] + fn discriminant(&self) -> i32 { + Self::discriminant(self) + } + } + + impl Variants for IntUnion { + fn variants() -> slice::Iter<'static, i32> { + Self::VARIANTS.iter() + } + } + + impl Union for IntUnion {} + + impl ReadXdr for IntUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: i32 = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + 0 => Self::V0(i32::read_xdr(r)?), +1 => Self::V1(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } + + impl WriteXdr for IntUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::V0(v) => v.write_xdr(w)?, +Self::V1(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } + } + +/// IntUnion2 is an XDR Typedef defines as: +/// +/// ```text +/// typedef IntUnion IntUnion2; +/// ``` +/// +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "arbitrary", derive(Arbitrary))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[derive(Debug)] +pub struct IntUnion2(pub IntUnion); + +impl From for IntUnion { + #[must_use] + fn from(x: IntUnion2) -> Self { + x.0 + } +} + +impl From for IntUnion2 { + #[must_use] + fn from(x: IntUnion) -> Self { + IntUnion2(x) + } +} + +impl AsRef for IntUnion2 { + #[must_use] + fn as_ref(&self) -> &IntUnion { + &self.0 + } +} + +impl ReadXdr for IntUnion2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let i = IntUnion::read_xdr(r)?; + let v = IntUnion2(i); + Ok(v) + }) + } +} + +impl WriteXdr for IntUnion2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum TypeVariant { + SError, +Multi, +UnionKey, +MyUnion, +IntUnion, +IntUnion2, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, +TypeVariant::Multi, +TypeVariant::UnionKey, +TypeVariant::MyUnion, +TypeVariant::IntUnion, +TypeVariant::IntUnion2, ]; + pub const VARIANTS_STR: [&'static str; 6] = [ "SError", +"Multi", +"UnionKey", +"MyUnion", +"IntUnion", +"IntUnion2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError => "SError", +Self::Multi => "Multi", +Self::UnionKey => "UnionKey", +Self::MyUnion => "MyUnion", +Self::IntUnion => "IntUnion", +Self::IntUnion2 => "IntUnion2", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } + } + + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "SError" => Ok(Self::SError), +"Multi" => Ok(Self::Multi), +"UnionKey" => Ok(Self::UnionKey), +"MyUnion" => Ok(Self::MyUnion), +"IntUnion" => Ok(Self::IntUnion), +"IntUnion2" => Ok(Self::IntUnion2), + _ => Err(Error::Invalid), + } + } + } + + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] + pub enum Type { + SError(Box), +Multi(Box), +UnionKey(Box), +MyUnion(Box), +IntUnion(Box), +IntUnion2(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, +TypeVariant::Multi, +TypeVariant::UnionKey, +TypeVariant::MyUnion, +TypeVariant::IntUnion, +TypeVariant::IntUnion2, ]; + pub const VARIANTS_STR: [&'static str; 6] = [ "SError", +"Multi", +"UnionKey", +"MyUnion", +"IntUnion", +"IntUnion2", ]; + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::SError => r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))), +TypeVariant::Multi => r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))), +TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), +TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), +TypeVariant::IntUnion => r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))), +TypeVariant::IntUnion2 => r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))), + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t.0))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t.0))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t.0))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0))))), + } + } + + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), + } + } + + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } + + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), +TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), + } + } + + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::SError(ref v) => v.as_ref(), +Self::Multi(ref v) => v.as_ref(), +Self::UnionKey(ref v) => v.as_ref(), +Self::MyUnion(ref v) => v.as_ref(), +Self::IntUnion(ref v) => v.as_ref(), +Self::IntUnion2(ref v) => v.as_ref(), + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError(_) => "SError", +Self::Multi(_) => "Multi", +Self::UnionKey(_) => "UnionKey", +Self::MyUnion(_) => "MyUnion", +Self::IntUnion(_) => "IntUnion", +Self::IntUnion2(_) => "IntUnion2", + } + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::SError(_) => TypeVariant::SError, +Self::Multi(_) => TypeVariant::Multi, +Self::UnionKey(_) => TypeVariant::UnionKey, +Self::MyUnion(_) => TypeVariant::MyUnion, +Self::IntUnion(_) => TypeVariant::IntUnion, +Self::IntUnion2(_) => TypeVariant::IntUnion2, + } + } + } + + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } + + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } + + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::SError(v) => v.write_xdr(w), +Self::Multi(v) => v.write_xdr(w), +Self::UnionKey(v) => v.write_xdr(w), +Self::MyUnion(v) => v.write_xdr(w), +Self::IntUnion(v) => v.write_xdr(w), +Self::IntUnion2(v) => v.write_xdr(w), + } + } + } diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index 2e64bf021..c4a26e2ad 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2698,7 +2702,8 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum AccountFlags { AuthRequiredFlag = 1, @@ -2789,6 +2794,10 @@ impl WriteXdr for AccountFlags { derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] +#[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) +)] pub enum TypeVariant { AccountFlags, } @@ -2843,6 +2852,10 @@ impl core::str::FromStr for TypeVariant { serde(rename_all = "snake_case"), serde(untagged), )] +#[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) +)] pub enum Type { AccountFlags(Box), } diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index 14fafaded..e825a26e0 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2716,6 +2720,10 @@ pub type TestArray2 = VecM::; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { TestArray, TestArray2, @@ -2775,6 +2783,10 @@ Self::TestArray2 => "TestArray2", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { TestArray(Box), TestArray2(Box), diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index c16fd1aa6..9ccf36a9d 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2717,7 +2721,8 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum MessageType { ErrorMsg = 0, @@ -2880,7 +2885,8 @@ Self::FbaMessage => "FbaMessage", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { Red = 0, @@ -2988,7 +2994,8 @@ Self::Blue => "Blue", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color2 { Red2 = 0, @@ -3089,6 +3096,10 @@ Self::Blue2 => "Blue2", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { MessageType, Color, @@ -3153,6 +3164,10 @@ Self::Color2 => "Color2", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { MessageType(Box), Color(Box), diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 65d3c5e18..84ee3ac24 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2699,7 +2703,8 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { One = 1, @@ -2812,7 +2817,8 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct MyUnionOne { pub some_int: i32, } @@ -2849,7 +2855,8 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct MyUnionTwo { pub some_int: i32, pub foo: i32, @@ -2902,7 +2909,8 @@ self.foo.write_xdr(w)?; // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { One(MyUnionOne), @@ -3009,6 +3017,10 @@ Self::Offer => ().write_xdr(w)?, derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { UnionKey, Foo, @@ -3083,6 +3095,10 @@ Self::MyUnionTwo => "MyUnionTwo", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { UnionKey(Box), Foo(Box), diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index 6e5d07c38..2107c2e68 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2707,7 +2711,8 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct HasOptions { pub first_option: Option, pub second_option: Option, @@ -2745,6 +2750,10 @@ self.third_option.write_xdr(w)?; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { Arr, HasOptions, @@ -2804,6 +2813,10 @@ Self::HasOptions => "HasOptions", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { Arr(Box), HasOptions(Box), diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index e727d03b1..6d25b0678 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2709,7 +2713,8 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct MyStruct { pub some_int: i32, pub a_big_int: i64, @@ -2753,6 +2758,10 @@ self.max_string.write_xdr(w)?; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { Int64, MyStruct, @@ -2812,6 +2821,10 @@ Self::MyStruct => "MyStruct", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { Int64(Box), MyStruct(Box), diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index 3e55699ea..711dfcb3a 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2694,7 +2698,8 @@ mod test { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2810,7 +2815,8 @@ impl AsRef<[u8]> for Uint512 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint513(pub BytesM::<64>); @@ -2911,7 +2917,8 @@ impl AsRef<[u8]> for Uint513 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint514(pub BytesM); @@ -3012,7 +3019,8 @@ impl AsRef<[u8]> for Uint514 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str(pub StringM::<64>); @@ -3113,7 +3121,8 @@ impl AsRef<[u8]> for Str { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str2(pub StringM); @@ -3213,7 +3222,8 @@ impl AsRef<[u8]> for Str2 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3328,7 +3338,8 @@ impl AsRef<[u8]> for Hash { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes1(pub [Hash; 12]); @@ -3417,7 +3428,8 @@ impl AsRef<[Hash]> for Hashes1 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes2(pub VecM::); @@ -3518,7 +3530,8 @@ impl AsRef<[Hash]> for Hashes2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes3(pub VecM::); @@ -3618,7 +3631,8 @@ impl AsRef<[Hash]> for Hashes3 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash1(pub Option); @@ -3669,7 +3683,8 @@ impl WriteXdr for OptHash1 { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash2(pub Option); @@ -3761,7 +3776,8 @@ pub type Int4 = u64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct MyStruct { pub field1: Uint512, pub field2: OptHash1, @@ -3816,7 +3832,8 @@ self.field7.write_xdr(w)?; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct LotsOfMyStructs { pub members: VecM::, } @@ -3853,7 +3870,8 @@ impl WriteXdr for LotsOfMyStructs { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct HasStuff { pub data: LotsOfMyStructs, } @@ -3892,7 +3910,8 @@ impl WriteXdr for HasStuff { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { Red = 0, @@ -4015,7 +4034,8 @@ pub const BAR: u64 = FOO; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum NesterNestedEnum { 1 = 0, @@ -4115,7 +4135,8 @@ Self::2 => "2", /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct NesterNestedStruct { pub blah: i32, } @@ -4155,7 +4176,8 @@ impl WriteXdr for NesterNestedStruct { // union with discriminant Color #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum NesterNestedUnion { Red, @@ -4269,7 +4291,8 @@ impl WriteXdr for NesterNestedUnion { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Nester { pub nested_enum: NesterNestedEnum, pub nested_struct: NesterNestedStruct, @@ -4307,6 +4330,10 @@ self.nested_union.write_xdr(w)?; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { Uint512, Uint513, @@ -4471,6 +4498,10 @@ Self::NesterNestedUnion => "NesterNestedUnion", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { Uint512(Box), Uint513(Box), diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index b5f378dca..6730c5c47 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -873,7 +873,8 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1279,8 +1280,9 @@ impl WriteXdr for VecM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1660,8 +1662,9 @@ impl WriteXdr for BytesM { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( feature = "serde", - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema) + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2030,9 +2033,10 @@ impl WriteXdr for StringM { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2714,7 +2718,8 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { Error = 0, @@ -2821,7 +2826,8 @@ Self::Multi => "Multi", // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr, schemars::JsonSchema))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { Error(i32), @@ -2931,7 +2937,8 @@ Self::Multi(v) => v.write_xdr(w)?, // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum IntUnion { V0(i32), @@ -3033,7 +3040,8 @@ Self::V1(v) => v.write_xdr(w)?, /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3082,6 +3090,10 @@ impl WriteXdr for IntUnion2 { derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum TypeVariant { SError, Multi, @@ -3161,6 +3173,10 @@ Self::IntUnion2 => "IntUnion2", serde(rename_all = "snake_case"), serde(untagged), )] + #[cfg_attr( + all(feature = "schemars", feature = "serde", feature = "alloc"), + derive(schemars::JsonSchema) + )] pub enum Type { SError(Box), Multi(Box), From 8cfcc1a17472b933724c5b9501e4d33a680b09b1 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 7 Mar 2024 16:23:00 +1000 Subject: [PATCH 04/20] Add manual JsonSchema impls Copied from 66a4913f1bd0de167ff50edd05c93dd958bec0eb Copied from https://github.com/stellar/rs-stellar-xdr/pull/349 Co-authored-by: Willem Wyndham --- lib/xdrgen/generators/rust.rb | 4 +- lib/xdrgen/generators/rust/src/types.rs | 110 +++++++++++++++++++++++- 2 files changed, 108 insertions(+), 6 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index 41077ce9e..456b5673c 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -99,7 +99,7 @@ def render_enum_of_all_types(out, types) #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] #[cfg_attr( @@ -156,7 +156,7 @@ def render_enum_of_all_types(out, types) #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/lib/xdrgen/generators/rust/src/types.rs b/lib/xdrgen/generators/rust/src/types.rs index 593987397..e28b2d6eb 100644 --- a/lib/xdrgen/generators/rust/src/types.rs +++ b/lib/xdrgen/generators/rust/src/types.rs @@ -864,7 +864,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -889,6 +888,24 @@ impl Default for VecM { } } +#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1272,7 +1289,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1325,6 +1341,38 @@ impl Deref for BytesM { } } +#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(((MAX.checked_mul(4).unwrap_or(u32::MAX) / 3) + 3) & !3), + min_length: Some(((MAX.checked_mul(4).unwrap_or(u32::MAX) / 3) + 3) & !3), + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1654,7 +1702,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1714,6 +1761,24 @@ impl Default for StringM { } } +#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2026,11 +2091,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2055,6 +2134,29 @@ where } } +fn mut_array(schema: schemars::schema::Schema, f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +fn mut_string(schema: schemars::schema::Schema, f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; From 6499bc7413bf3ecd413916bbb82dfb04bc71a0a0 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:10:53 +1000 Subject: [PATCH 05/20] fix dead code --- lib/xdrgen/generators/rust/src/types.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/xdrgen/generators/rust/src/types.rs b/lib/xdrgen/generators/rust/src/types.rs index e28b2d6eb..e5a6fddba 100644 --- a/lib/xdrgen/generators/rust/src/types.rs +++ b/lib/xdrgen/generators/rust/src/types.rs @@ -2134,6 +2134,7 @@ where } } +#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] fn mut_array(schema: schemars::schema::Schema, f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation) -> schemars::schema::Schema { if let schemars::schema::Schema::Object(mut schema) = schema { if let Some(array) = schema.array.clone() { @@ -2145,6 +2146,7 @@ fn mut_array(schema: schemars::schema::Schema, f: impl FnOnce(schemars::schema:: } } +#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] fn mut_string(schema: schemars::schema::Schema, f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation) -> schemars::schema::Schema { if let schemars::schema::Schema::Object(mut schema) = schema { let string = *schema.string.unwrap_or_default().clone(); From 25db2c453dafa8f6f4d477503e2812c6668766e1 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:08:23 +1000 Subject: [PATCH 06/20] simplified features --- lib/xdrgen/generators/rust.rb | 18 +- lib/xdrgen/generators/rust/src/types.rs | 38 +- .../block_comments.x/MyXDR.rs | 162 ++- .../generator_spec_rust/const.x/MyXDR.rs | 497 ++++--- .../generator_spec_rust/enum.x/MyXDR.rs | 1190 +++++++++------- .../generator_spec_rust/nesting.x/MyXDR.rs | 1074 ++++++++------- .../generator_spec_rust/optional.x/MyXDR.rs | 561 ++++---- .../generator_spec_rust/struct.x/MyXDR.rs | 573 ++++---- .../generator_spec_rust/test.x/MyXDR.rs | 56 +- .../generator_spec_rust/union.x/MyXDR.rs | 1217 ++++++++++------- .../block_comments.x/MyXDR.rs | 162 ++- .../const.x/MyXDR.rs | 497 ++++--- .../enum.x/MyXDR.rs | 1180 +++++++++------- .../nesting.x/MyXDR.rs | 1054 +++++++------- .../optional.x/MyXDR.rs | 551 ++++---- .../struct.x/MyXDR.rs | 563 ++++---- .../test.x/MyXDR.rs | 52 +- .../union.x/MyXDR.rs | 1197 +++++++++------- .../block_comments.x/MyXDR.rs | 162 ++- .../const.x/MyXDR.rs | 497 ++++--- .../enum.x/MyXDR.rs | 1189 +++++++++------- .../nesting.x/MyXDR.rs | 1072 ++++++++------- .../optional.x/MyXDR.rs | 560 ++++---- .../struct.x/MyXDR.rs | 572 ++++---- .../test.x/MyXDR.rs | 56 +- .../union.x/MyXDR.rs | 1215 +++++++++------- 26 files changed, 9135 insertions(+), 6830 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index 456b5673c..684358e27 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -102,10 +102,7 @@ def render_enum_of_all_types(out, types) derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum TypeVariant { #{types.map { |t| "#{t}," }.join("\n")} } @@ -160,10 +157,7 @@ def render_enum_of_all_types(out, types) serde(rename_all = "snake_case"), serde(untagged), )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum Type { #{types.map { |t| "#{t}(Box<#{t}>)," }.join("\n")} } @@ -378,7 +372,7 @@ def render_struct(out, struct) out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} end if !@options[:rust_types_custom_jsonschema_impl].include?(name struct) - out.puts %{#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))]} + out.puts %{#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]} end out.puts "pub struct #{name struct} {" out.indent do @@ -427,7 +421,7 @@ def render_enum(out, enum) out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} end if !@options[:rust_types_custom_jsonschema_impl].include?(name enum) - out.puts %{#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))]} + out.puts %{#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]} end out.puts "#[repr(i32)]" out.puts "pub enum #{name enum} {" @@ -559,7 +553,7 @@ def render_union(out, union) out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} end if !@options[:rust_types_custom_jsonschema_impl].include?(name union) - out.puts %{#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))]} + out.puts %{#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]} end out.puts "#[allow(clippy::large_enum_variant)]" out.puts "pub enum #{name union} {" @@ -696,7 +690,7 @@ def render_typedef(out, typedef) out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} end if !@options[:rust_types_custom_jsonschema_impl].include?(name typedef) - out.puts %{#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))]} + out.puts %{#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]} end if !is_fixed_array_opaque(typedef.type) out.puts "#[derive(Debug)]" diff --git a/lib/xdrgen/generators/rust/src/types.rs b/lib/xdrgen/generators/rust/src/types.rs index e5a6fddba..410b93e31 100644 --- a/lib/xdrgen/generators/rust/src/types.rs +++ b/lib/xdrgen/generators/rust/src/types.rs @@ -888,7 +888,7 @@ impl Default for VecM { } } -#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] +#[cfg(feature = "schemars")] impl schemars::JsonSchema for VecM { fn schema_name() -> String { format!("VecM<{}, {}>", T::schema_name(), MAX) @@ -899,9 +899,11 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } }) } } @@ -1341,7 +1343,7 @@ impl Deref for BytesM { } } -#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] +#[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { format!("BytesM<{}>", MAX) @@ -1761,7 +1763,7 @@ impl Default for StringM { } } -#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] +#[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { format!("StringM<{}>", MAX) @@ -1772,9 +1774,11 @@ impl schemars::JsonSchema for StringM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| schemars::schema::StringValidation { - max_length: Some(MAX), - ..string + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } }) } } @@ -2095,7 +2099,7 @@ pub struct Frame(pub T) where T: ReadXdr; -#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] +#[cfg(feature = "schemars")] impl schemars::JsonSchema for Frame { fn schema_name() -> String { format!("Frame<{}>", T::schema_name()) @@ -2134,8 +2138,11 @@ where } } -#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] -fn mut_array(schema: schemars::schema::Schema, f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation) -> schemars::schema::Schema { +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { if let schemars::schema::Schema::Object(mut schema) = schema { if let Some(array) = schema.array.clone() { schema.array = Some(Box::new(f(*array))); @@ -2146,8 +2153,11 @@ fn mut_array(schema: schemars::schema::Schema, f: impl FnOnce(schemars::schema:: } } -#[cfg(all(feature = "schemars", feature = "serde", feature = "alloc"))] -fn mut_string(schema: schemars::schema::Schema, f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation) -> schemars::schema::Schema { +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { if let schemars::schema::Schema::Object(mut schema) = schema { let string = *schema.string.unwrap_or_default().clone(); let s = f(string); diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index c4a26e2ad..66aaeab58 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/block_comments.x", "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/block_comments.x", + "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2702,16 +2735,28 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum AccountFlags { - AuthRequiredFlag = 1, + AuthRequiredFlag = 1, } impl AccountFlags { - pub const VARIANTS: [AccountFlags; 1] = [ AccountFlags::AuthRequiredFlag, ]; - pub const VARIANTS_STR: [&'static str; 1] = [ "AuthRequiredFlag", ]; + pub const VARIANTS: [AccountFlags; 1] = [AccountFlags::AuthRequiredFlag]; + pub const VARIANTS_STR: [&'static str; 1] = ["AuthRequiredFlag"]; #[must_use] pub const fn name(&self) -> &'static str { @@ -2790,21 +2835,26 @@ impl WriteXdr for AccountFlags { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") )] #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) )] pub enum TypeVariant { AccountFlags, } impl TypeVariant { - pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; - pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; + pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; + pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; #[must_use] #[allow(clippy::too_many_lines)] @@ -2847,34 +2897,44 @@ impl core::str::FromStr for TypeVariant { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) )] #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) )] pub enum Type { AccountFlags(Box), } impl Type { - pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; - pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; + pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; + pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { match v { - TypeVariant::AccountFlags => r.with_limited_depth(|r| Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?)))), + TypeVariant::AccountFlags => r.with_limited_depth(|r| { + Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?))) + }), } } #[cfg(feature = "base64")] pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); let t = Self::read_xdr(v, &mut dec)?; Ok(t) } @@ -2893,33 +2953,54 @@ impl Type { #[cfg(feature = "base64")] pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), + TypeVariant::AccountFlags => Box::new( + ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), + ), } } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0))))), + TypeVariant::AccountFlags => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0)))), + ), } } #[cfg(feature = "base64")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); match v { - TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), + TypeVariant::AccountFlags => Box::new( + ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), + ), } } @@ -2933,7 +3014,10 @@ impl Type { #[cfg(feature = "base64")] pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } @@ -2942,7 +3026,9 @@ impl Type { #[allow(clippy::too_many_lines)] pub fn read_json(v: TypeVariant, r: impl Read) -> Result { match v { - TypeVariant::AccountFlags => Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))), + TypeVariant::AccountFlags => { + Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))) + } } } diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index e825a26e0..b3a737966 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/const.x", "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/const.x", + "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2712,235 +2745,281 @@ pub type TestArray = [i32; Foo]; /// typedef int TestArray2; /// ``` /// -pub type TestArray2 = VecM::; - - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - TestArray, -TestArray2, - } +pub type TestArray2 = VecM; - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, -TypeVariant::TestArray2, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", -"TestArray2", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray => "TestArray", -Self::TestArray2 => "TestArray2", - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + TestArray, + TestArray2, +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; + pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray => "TestArray", + Self::TestArray2 => "TestArray2", } + } - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "TestArray" => Ok(Self::TestArray), -"TestArray2" => Ok(Self::TestArray2), - _ => Err(Error::Invalid), - } - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - TestArray(Box), -TestArray2(Box), - } +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} - impl Type { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, -TypeVariant::TestArray2, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", -"TestArray2", ]; +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "TestArray" => Ok(Self::TestArray), + "TestArray2" => Ok(Self::TestArray2), + _ => Err(Error::Invalid), + } + } +} - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::TestArray => r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))), -TypeVariant::TestArray2 => r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))), - } - } +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + TestArray(Box), + TestArray2(Box), +} - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } +impl Type { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; + pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::TestArray => { + r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::TestArray2 => { + r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), -TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t.0))))), -TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), -TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new( + ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), + ), + TypeVariant::TestArray2 => Box::new( + ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray(Box::new(t.0)))), + ), + TypeVariant::TestArray2 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray2(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), -TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::TestArray => Box::new( + ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), + ), + TypeVariant::TestArray2 => Box::new( + ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::TestArray(ref v) => v.as_ref(), -Self::TestArray2(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray(_) => "TestArray", -Self::TestArray2(_) => "TestArray2", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), + TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::TestArray(_) => TypeVariant::TestArray, -Self::TestArray2(_) => TypeVariant::TestArray2, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::TestArray(ref v) => v.as_ref(), + Self::TestArray2(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray(_) => "TestArray", + Self::TestArray2(_) => "TestArray2", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::TestArray(_) => TypeVariant::TestArray, + Self::TestArray2(_) => TypeVariant::TestArray2, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::TestArray(v) => v.write_xdr(w), -Self::TestArray2(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::TestArray(v) => v.write_xdr(w), + Self::TestArray2(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index a5a302aaf..f9ee1e9fe 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/enum.x", "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/enum.x", + "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2698,19 +2731,19 @@ mod test { /// ERROR_MSG, /// HELLO, /// DONT_HAVE, -/// +/// /// GET_PEERS, // gets a list of peers this guy knows about /// PEERS, -/// +/// /// GET_TX_SET, // gets a particular txset by hash /// TX_SET, -/// +/// /// GET_VALIDATIONS, // gets validations for a given ledger hash /// VALIDATIONS, -/// +/// /// TRANSACTION, //pass on a tx you have heard about /// JSON_TRANSACTION, -/// +/// /// // FBA /// GET_FBA_QUORUMSET, /// FBA_QUORUMSET, @@ -2721,156 +2754,172 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum MessageType { - ErrorMsg = 0, - Hello = 1, - DontHave = 2, - GetPeers = 3, - Peers = 4, - GetTxSet = 5, - TxSet = 6, - GetValidations = 7, - Validations = 8, - Transaction = 9, - JsonTransaction = 10, - GetFbaQuorumset = 11, - FbaQuorumset = 12, - FbaMessage = 13, -} - - impl MessageType { - pub const VARIANTS: [MessageType; 14] = [ MessageType::ErrorMsg, -MessageType::Hello, -MessageType::DontHave, -MessageType::GetPeers, -MessageType::Peers, -MessageType::GetTxSet, -MessageType::TxSet, -MessageType::GetValidations, -MessageType::Validations, -MessageType::Transaction, -MessageType::JsonTransaction, -MessageType::GetFbaQuorumset, -MessageType::FbaQuorumset, -MessageType::FbaMessage, ]; - pub const VARIANTS_STR: [&'static str; 14] = [ "ErrorMsg", -"Hello", -"DontHave", -"GetPeers", -"Peers", -"GetTxSet", -"TxSet", -"GetValidations", -"Validations", -"Transaction", -"JsonTransaction", -"GetFbaQuorumset", -"FbaQuorumset", -"FbaMessage", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::ErrorMsg => "ErrorMsg", -Self::Hello => "Hello", -Self::DontHave => "DontHave", -Self::GetPeers => "GetPeers", -Self::Peers => "Peers", -Self::GetTxSet => "GetTxSet", -Self::TxSet => "TxSet", -Self::GetValidations => "GetValidations", -Self::Validations => "Validations", -Self::Transaction => "Transaction", -Self::JsonTransaction => "JsonTransaction", -Self::GetFbaQuorumset => "GetFbaQuorumset", -Self::FbaQuorumset => "FbaQuorumset", -Self::FbaMessage => "FbaMessage", - } - } + ErrorMsg = 0, + Hello = 1, + DontHave = 2, + GetPeers = 3, + Peers = 4, + GetTxSet = 5, + TxSet = 6, + GetValidations = 7, + Validations = 8, + Transaction = 9, + JsonTransaction = 10, + GetFbaQuorumset = 11, + FbaQuorumset = 12, + FbaMessage = 13, +} + +impl MessageType { + pub const VARIANTS: [MessageType; 14] = [ + MessageType::ErrorMsg, + MessageType::Hello, + MessageType::DontHave, + MessageType::GetPeers, + MessageType::Peers, + MessageType::GetTxSet, + MessageType::TxSet, + MessageType::GetValidations, + MessageType::Validations, + MessageType::Transaction, + MessageType::JsonTransaction, + MessageType::GetFbaQuorumset, + MessageType::FbaQuorumset, + MessageType::FbaMessage, + ]; + pub const VARIANTS_STR: [&'static str; 14] = [ + "ErrorMsg", + "Hello", + "DontHave", + "GetPeers", + "Peers", + "GetTxSet", + "TxSet", + "GetValidations", + "Validations", + "Transaction", + "JsonTransaction", + "GetFbaQuorumset", + "FbaQuorumset", + "FbaMessage", + ]; - #[must_use] - pub const fn variants() -> [MessageType; 14] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::ErrorMsg => "ErrorMsg", + Self::Hello => "Hello", + Self::DontHave => "DontHave", + Self::GetPeers => "GetPeers", + Self::Peers => "Peers", + Self::GetTxSet => "GetTxSet", + Self::TxSet => "TxSet", + Self::GetValidations => "GetValidations", + Self::Validations => "Validations", + Self::Transaction => "Transaction", + Self::JsonTransaction => "JsonTransaction", + Self::GetFbaQuorumset => "GetFbaQuorumset", + Self::FbaQuorumset => "FbaQuorumset", + Self::FbaMessage => "FbaMessage", } + } - impl Name for MessageType { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + pub const fn variants() -> [MessageType; 14] { + Self::VARIANTS + } +} - impl Variants for MessageType { - fn variants() -> slice::Iter<'static, MessageType> { - Self::VARIANTS.iter() - } - } +impl Name for MessageType { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Enum for MessageType {} +impl Variants for MessageType { + fn variants() -> slice::Iter<'static, MessageType> { + Self::VARIANTS.iter() + } +} - impl fmt::Display for MessageType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Enum for MessageType {} - impl TryFrom for MessageType { - type Error = Error; - - fn try_from(i: i32) -> Result { - let e = match i { - 0 => MessageType::ErrorMsg, -1 => MessageType::Hello, -2 => MessageType::DontHave, -3 => MessageType::GetPeers, -4 => MessageType::Peers, -5 => MessageType::GetTxSet, -6 => MessageType::TxSet, -7 => MessageType::GetValidations, -8 => MessageType::Validations, -9 => MessageType::Transaction, -10 => MessageType::JsonTransaction, -11 => MessageType::GetFbaQuorumset, -12 => MessageType::FbaQuorumset, -13 => MessageType::FbaMessage, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for MessageType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: MessageType) -> Self { - e as Self - } - } +impl TryFrom for MessageType { + type Error = Error; - impl ReadXdr for MessageType { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => MessageType::ErrorMsg, + 1 => MessageType::Hello, + 2 => MessageType::DontHave, + 3 => MessageType::GetPeers, + 4 => MessageType::Peers, + 5 => MessageType::GetTxSet, + 6 => MessageType::TxSet, + 7 => MessageType::GetValidations, + 8 => MessageType::Validations, + 9 => MessageType::Transaction, + 10 => MessageType::JsonTransaction, + 11 => MessageType::GetFbaQuorumset, + 12 => MessageType::FbaQuorumset, + 13 => MessageType::FbaMessage, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for MessageType { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: MessageType) -> Self { + e as Self + } +} + +impl ReadXdr for MessageType { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for MessageType { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// Color is an XDR Enum defines as: /// @@ -2885,101 +2934,109 @@ Self::FbaMessage => "FbaMessage", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum Color { - Red = 0, - Green = 1, - Blue = 2, -} - - impl Color { - pub const VARIANTS: [Color; 3] = [ Color::Red, -Color::Green, -Color::Blue, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "Red", -"Green", -"Blue", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red => "Red", -Self::Green => "Green", -Self::Blue => "Blue", - } - } + Red = 0, + Green = 1, + Blue = 2, +} - #[must_use] - pub const fn variants() -> [Color; 3] { - Self::VARIANTS - } - } +impl Color { + pub const VARIANTS: [Color; 3] = [Color::Red, Color::Green, Color::Blue]; + pub const VARIANTS_STR: [&'static str; 3] = ["Red", "Green", "Blue"]; - impl Name for Color { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red => "Red", + Self::Green => "Green", + Self::Blue => "Blue", } + } - impl Variants for Color { - fn variants() -> slice::Iter<'static, Color> { - Self::VARIANTS.iter() - } - } + #[must_use] + pub const fn variants() -> [Color; 3] { + Self::VARIANTS + } +} - impl Enum for Color {} +impl Name for Color { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl fmt::Display for Color { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Variants for Color { + fn variants() -> slice::Iter<'static, Color> { + Self::VARIANTS.iter() + } +} - impl TryFrom for Color { - type Error = Error; +impl Enum for Color {} - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color::Red, -1 => Color::Green, -2 => Color::Blue, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for Color { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: Color) -> Self { - e as Self - } - } +impl TryFrom for Color { + type Error = Error; - impl ReadXdr for Color { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color::Red, + 1 => Color::Green, + 2 => Color::Blue, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for Color { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: Color) -> Self { + e as Self + } +} + +impl ReadXdr for Color { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for Color { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// Color2 is an XDR Enum defines as: /// @@ -2994,346 +3051,417 @@ Self::Blue => "Blue", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum Color2 { - Red2 = 0, - Green2 = 1, - Blue2 = 2, -} - - impl Color2 { - pub const VARIANTS: [Color2; 3] = [ Color2::Red2, -Color2::Green2, -Color2::Blue2, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "Red2", -"Green2", -"Blue2", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red2 => "Red2", -Self::Green2 => "Green2", -Self::Blue2 => "Blue2", - } - } + Red2 = 0, + Green2 = 1, + Blue2 = 2, +} - #[must_use] - pub const fn variants() -> [Color2; 3] { - Self::VARIANTS - } - } +impl Color2 { + pub const VARIANTS: [Color2; 3] = [Color2::Red2, Color2::Green2, Color2::Blue2]; + pub const VARIANTS_STR: [&'static str; 3] = ["Red2", "Green2", "Blue2"]; - impl Name for Color2 { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red2 => "Red2", + Self::Green2 => "Green2", + Self::Blue2 => "Blue2", } + } - impl Variants for Color2 { - fn variants() -> slice::Iter<'static, Color2> { - Self::VARIANTS.iter() - } - } + #[must_use] + pub const fn variants() -> [Color2; 3] { + Self::VARIANTS + } +} - impl Enum for Color2 {} +impl Name for Color2 { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl fmt::Display for Color2 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Variants for Color2 { + fn variants() -> slice::Iter<'static, Color2> { + Self::VARIANTS.iter() + } +} - impl TryFrom for Color2 { - type Error = Error; +impl Enum for Color2 {} - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color2::Red2, -1 => Color2::Green2, -2 => Color2::Blue2, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for Color2 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: Color2) -> Self { - e as Self - } - } +impl TryFrom for Color2 { + type Error = Error; - impl ReadXdr for Color2 { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color2::Red2, + 1 => Color2::Green2, + 2 => Color2::Blue2, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for Color2 { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: Color2) -> Self { + e as Self + } +} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - MessageType, -Color, -Color2, - } - - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, -TypeVariant::Color, -TypeVariant::Color2, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", -"Color", -"Color2", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType => "MessageType", -Self::Color => "Color", -Self::Color2 => "Color2", - } - } +impl ReadXdr for Color2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS - } - } +impl WriteXdr for Color2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + MessageType, + Color, + Color2, +} - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 3] = [ + TypeVariant::MessageType, + TypeVariant::Color, + TypeVariant::Color2, + ]; + pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType => "MessageType", + Self::Color => "Color", + Self::Color2 => "Color2", } + } - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "MessageType" => Ok(Self::MessageType), -"Color" => Ok(Self::Color), -"Color2" => Ok(Self::Color2), - _ => Err(Error::Invalid), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } +} + +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "MessageType" => Ok(Self::MessageType), + "Color" => Ok(Self::Color), + "Color2" => Ok(Self::Color2), + _ => Err(Error::Invalid), } + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - MessageType(Box), -Color(Box), -Color2(Box), - } - - impl Type { - pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, -TypeVariant::Color, -TypeVariant::Color2, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", -"Color", -"Color2", ]; +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + MessageType(Box), + Color(Box), + Color2(Box), +} - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::MessageType => r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))), -TypeVariant::Color => r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))), -TypeVariant::Color2 => r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))), - } - } +impl Type { + pub const VARIANTS: [TypeVariant; 3] = [ + TypeVariant::MessageType, + TypeVariant::Color, + TypeVariant::Color2, + ]; + pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::MessageType => { + r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + TypeVariant::Color => { + r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::Color2 => { + r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), -TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), -TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t.0))))), -TypeVariant::Color => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t.0))))), -TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), -TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), -TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new( + ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), + ), + TypeVariant::Color => Box::new( + ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color(Box::new(t)))), + ), + TypeVariant::Color2 => Box::new( + ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color2(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MessageType(Box::new(t.0)))), + ), + TypeVariant::Color => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color(Box::new(t.0)))), + ), + TypeVariant::Color2 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color2(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::MessageType => Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::MessageType => Box::new( + ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), + ), + TypeVariant::Color => Box::new( + ReadXdrIter::<_, Color>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Color(Box::new(t)))), + ), + TypeVariant::Color2 => Box::new( + ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Color2(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::MessageType(ref v) => v.as_ref(), -Self::Color(ref v) => v.as_ref(), -Self::Color2(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType(_) => "MessageType", -Self::Color(_) => "Color", -Self::Color2(_) => "Color2", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::MessageType => { + Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))) } + TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), + TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::MessageType(_) => TypeVariant::MessageType, -Self::Color(_) => TypeVariant::Color, -Self::Color2(_) => TypeVariant::Color2, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::MessageType(ref v) => v.as_ref(), + Self::Color(ref v) => v.as_ref(), + Self::Color2(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType(_) => "MessageType", + Self::Color(_) => "Color", + Self::Color2(_) => "Color2", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::MessageType(_) => TypeVariant::MessageType, + Self::Color(_) => TypeVariant::Color, + Self::Color2(_) => TypeVariant::Color2, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::MessageType(v) => v.write_xdr(w), -Self::Color(v) => v.write_xdr(w), -Self::Color2(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::MessageType(v) => v.write_xdr(w), + Self::Color(v) => v.write_xdr(w), + Self::Color2(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 9f9b11976..043e66cd5 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/nesting.x", "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/nesting.x", + "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2703,101 +2736,109 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum UnionKey { - One = 1, - Two = 2, - Offer = 3, -} - - impl UnionKey { - pub const VARIANTS: [UnionKey; 3] = [ UnionKey::One, -UnionKey::Two, -UnionKey::Offer, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "One", -"Two", -"Offer", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One => "One", -Self::Two => "Two", -Self::Offer => "Offer", - } - } + One = 1, + Two = 2, + Offer = 3, +} - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } - } +impl UnionKey { + pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; + pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; - impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One => "One", + Self::Two => "Two", + Self::Offer => "Offer", } + } - impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } +} - impl Enum for UnionKey {} +impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl TryFrom for UnionKey { - type Error = Error; +impl Enum for UnionKey {} - fn try_from(i: i32) -> Result { - let e = match i { - 1 => UnionKey::One, -2 => UnionKey::Two, -3 => UnionKey::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } - } +impl TryFrom for UnionKey { + type Error = Error; - impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 1 => UnionKey::One, + 2 => UnionKey::Two, + 3 => UnionKey::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } +} + +impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// Foo is an XDR Typedef defines as: /// @@ -2817,18 +2858,30 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct MyUnionOne { - pub some_int: i32, + pub some_int: i32, } impl ReadXdr for MyUnionOne { #[cfg(feature = "std")] fn read_xdr(r: &mut Limited) -> Result { r.with_limited_depth(|r| { - Ok(Self{ - some_int: i32::read_xdr(r)?, + Ok(Self { + some_int: i32::read_xdr(r)?, }) }) } @@ -2855,35 +2908,47 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct MyUnionTwo { - pub some_int: i32, - pub foo: i32, + pub some_int: i32, + pub foo: i32, } - impl ReadXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self{ - some_int: i32::read_xdr(r)?, -foo: i32::read_xdr(r)?, - }) - }) - } - } +impl ReadXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self { + some_int: i32::read_xdr(r)?, + foo: i32::read_xdr(r)?, + }) + }) + } +} - impl WriteXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; -self.foo.write_xdr(w)?; - Ok(()) - }) - } - } +impl WriteXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; + self.foo.write_xdr(w)?; + Ok(()) + }) + } +} /// MyUnion is an XDR Union defines as: /// @@ -2894,13 +2959,13 @@ self.foo.write_xdr(w)?; /// struct { /// int someInt; /// } one; -/// +/// /// case TWO: /// struct { /// int someInt; /// Foo foo; /// } two; -/// +/// /// case OFFER: /// void; /// }; @@ -2909,386 +2974,471 @@ self.foo.write_xdr(w)?; // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - One(MyUnionOne), - Two(MyUnionTwo), - Offer, -} - - impl MyUnion { - pub const VARIANTS: [UnionKey; 3] = [ - UnionKey::One, -UnionKey::Two, -UnionKey::Offer, - ]; - pub const VARIANTS_STR: [&'static str; 3] = [ - "One", -"Two", -"Offer", - ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One(_) => "One", -Self::Two(_) => "Two", -Self::Offer => "Offer", - } - } + One(MyUnionOne), + Two(MyUnionTwo), + Offer, +} - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::One(_) => UnionKey::One, -Self::Two(_) => UnionKey::Two, -Self::Offer => UnionKey::Offer, - } - } +impl MyUnion { + pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; + pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One(_) => "One", + Self::Two(_) => "Two", + Self::Offer => "Offer", } + } - impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::One(_) => UnionKey::One, + Self::Two(_) => UnionKey::Two, + Self::Offer => UnionKey::Offer, } + } - impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } +} - impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } +impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Union for MyUnion {} +impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } +} - impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), -UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), -UnionKey::Offer => Self::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } - } +impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::One(v) => v.write_xdr(w)?, -Self::Two(v) => v.write_xdr(w)?, -Self::Offer => ().write_xdr(w)?, - }; - Ok(()) - }) - } - } +impl Union for MyUnion {} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - UnionKey, -Foo, -MyUnion, -MyUnionOne, -MyUnionTwo, - } - - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, -TypeVariant::Foo, -TypeVariant::MyUnion, -TypeVariant::MyUnionOne, -TypeVariant::MyUnionTwo, ]; - pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", -"Foo", -"MyUnion", -"MyUnionOne", -"MyUnionTwo", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey => "UnionKey", -Self::Foo => "Foo", -Self::MyUnion => "MyUnion", -Self::MyUnionOne => "MyUnionOne", -Self::MyUnionTwo => "MyUnionTwo", - } - } +impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), + UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), + UnionKey::Offer => Self::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } - } +impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::One(v) => v.write_xdr(w)?, + Self::Two(v) => v.write_xdr(w)?, + Self::Offer => ().write_xdr(w)?, + }; + Ok(()) + }) + } +} - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + UnionKey, + Foo, + MyUnion, + MyUnionOne, + MyUnionTwo, +} + +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 5] = [ + TypeVariant::UnionKey, + TypeVariant::Foo, + TypeVariant::MyUnion, + TypeVariant::MyUnionOne, + TypeVariant::MyUnionTwo, + ]; + pub const VARIANTS_STR: [&'static str; 5] = + ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey => "UnionKey", + Self::Foo => "Foo", + Self::MyUnion => "MyUnion", + Self::MyUnionOne => "MyUnionOne", + Self::MyUnionTwo => "MyUnionTwo", } + } - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "UnionKey" => Ok(Self::UnionKey), -"Foo" => Ok(Self::Foo), -"MyUnion" => Ok(Self::MyUnion), -"MyUnionOne" => Ok(Self::MyUnionOne), -"MyUnionTwo" => Ok(Self::MyUnionTwo), - _ => Err(Error::Invalid), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } +} + +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "UnionKey" => Ok(Self::UnionKey), + "Foo" => Ok(Self::Foo), + "MyUnion" => Ok(Self::MyUnion), + "MyUnionOne" => Ok(Self::MyUnionOne), + "MyUnionTwo" => Ok(Self::MyUnionTwo), + _ => Err(Error::Invalid), } + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - UnionKey(Box), -Foo(Box), -MyUnion(Box), -MyUnionOne(Box), -MyUnionTwo(Box), - } - - impl Type { - pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, -TypeVariant::Foo, -TypeVariant::MyUnion, -TypeVariant::MyUnionOne, -TypeVariant::MyUnionTwo, ]; - pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", -"Foo", -"MyUnion", -"MyUnionOne", -"MyUnionTwo", ]; +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + UnionKey(Box), + Foo(Box), + MyUnion(Box), + MyUnionOne(Box), + MyUnionTwo(Box), +} + +impl Type { + pub const VARIANTS: [TypeVariant; 5] = [ + TypeVariant::UnionKey, + TypeVariant::Foo, + TypeVariant::MyUnion, + TypeVariant::MyUnionOne, + TypeVariant::MyUnionTwo, + ]; + pub const VARIANTS_STR: [&'static str; 5] = + ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), -TypeVariant::Foo => r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))), -TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), -TypeVariant::MyUnionOne => r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))), -TypeVariant::MyUnionTwo => r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))), - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::UnionKey => { + r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) + TypeVariant::Foo => { + r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + TypeVariant::MyUnion => { + r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::MyUnionOne => { + r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), -TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), - } + TypeVariant::MyUnionTwo => { + r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), -TypeVariant::Foo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t.0))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), -TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0))))), -TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), -TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::Foo => Box::new( + ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Foo(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::MyUnionOne => Box::new( + ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), + ), + TypeVariant::MyUnionTwo => Box::new( + ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), + ), + TypeVariant::Foo => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Foo(Box::new(t.0)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), + ), + TypeVariant::MyUnionOne => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0)))), + ), + TypeVariant::MyUnionTwo => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::UnionKey(ref v) => v.as_ref(), -Self::Foo(ref v) => v.as_ref(), -Self::MyUnion(ref v) => v.as_ref(), -Self::MyUnionOne(ref v) => v.as_ref(), -Self::MyUnionTwo(ref v) => v.as_ref(), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::Foo => Box::new( + ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Foo(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::MyUnionOne => Box::new( + ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), + ), + TypeVariant::MyUnionTwo => Box::new( + ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), + ), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey(_) => "UnionKey", -Self::Foo(_) => "Foo", -Self::MyUnion(_) => "MyUnion", -Self::MyUnionOne(_) => "MyUnionOne", -Self::MyUnionTwo(_) => "MyUnionTwo", - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::UnionKey(_) => TypeVariant::UnionKey, -Self::Foo(_) => TypeVariant::Foo, -Self::MyUnion(_) => TypeVariant::MyUnion, -Self::MyUnionOne(_) => TypeVariant::MyUnionOne, -Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), + TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::UnionKey(ref v) => v.as_ref(), + Self::Foo(ref v) => v.as_ref(), + Self::MyUnion(ref v) => v.as_ref(), + Self::MyUnionOne(ref v) => v.as_ref(), + Self::MyUnionTwo(ref v) => v.as_ref(), } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey(_) => "UnionKey", + Self::Foo(_) => "Foo", + Self::MyUnion(_) => "MyUnion", + Self::MyUnionOne(_) => "MyUnionOne", + Self::MyUnionTwo(_) => "MyUnionTwo", } + } - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::UnionKey(v) => v.write_xdr(w), -Self::Foo(v) => v.write_xdr(w), -Self::MyUnion(v) => v.write_xdr(w), -Self::MyUnionOne(v) => v.write_xdr(w), -Self::MyUnionTwo(v) => v.write_xdr(w), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::UnionKey(_) => TypeVariant::UnionKey, + Self::Foo(_) => TypeVariant::Foo, + Self::MyUnion(_) => TypeVariant::MyUnion, + Self::MyUnionOne(_) => TypeVariant::MyUnionOne, + Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, } + } +} + +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::UnionKey(v) => v.write_xdr(w), + Self::Foo(v) => v.write_xdr(w), + Self::MyUnion(v) => v.write_xdr(w), + Self::MyUnionOne(v) => v.write_xdr(w), + Self::MyUnionTwo(v) => v.write_xdr(w), + } + } +} diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 576149b20..3fdd0d44f 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/optional.x", "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/optional.x", + "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2711,266 +2744,324 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct HasOptions { - pub first_option: Option, - pub second_option: Option, - pub third_option: Option, + pub first_option: Option, + pub second_option: Option, + pub third_option: Option, } - impl ReadXdr for HasOptions { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self{ - first_option: Option::::read_xdr(r)?, -second_option: Option::::read_xdr(r)?, -third_option: Option::::read_xdr(r)?, - }) - }) - } - } +impl ReadXdr for HasOptions { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self { + first_option: Option::::read_xdr(r)?, + second_option: Option::::read_xdr(r)?, + third_option: Option::::read_xdr(r)?, + }) + }) + } +} - impl WriteXdr for HasOptions { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.first_option.write_xdr(w)?; -self.second_option.write_xdr(w)?; -self.third_option.write_xdr(w)?; - Ok(()) - }) - } - } +impl WriteXdr for HasOptions { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.first_option.write_xdr(w)?; + self.second_option.write_xdr(w)?; + self.third_option.write_xdr(w)?; + Ok(()) + }) + } +} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - Arr, -HasOptions, - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + Arr, + HasOptions, +} - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, -TypeVariant::HasOptions, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", -"HasOptions", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr => "Arr", -Self::HasOptions => "HasOptions", - } - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; + pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr => "Arr", + Self::HasOptions => "HasOptions", } + } - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } +} - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Arr" => Ok(Self::Arr), -"HasOptions" => Ok(Self::HasOptions), - _ => Err(Error::Invalid), - } - } - } +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - Arr(Box), -HasOptions(Box), +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Arr" => Ok(Self::Arr), + "HasOptions" => Ok(Self::HasOptions), + _ => Err(Error::Invalid), } + } +} - impl Type { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, -TypeVariant::HasOptions, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", -"HasOptions", ]; - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Arr => r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))), -TypeVariant::HasOptions => r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))), - } - } +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + Arr(Box), + HasOptions(Box), +} - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } +impl Type { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; + pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Arr => { + r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::HasOptions => { + r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), -TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t.0))))), -TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), -TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new( + ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Arr(Box::new(t)))), + ), + TypeVariant::HasOptions => Box::new( + ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Arr(Box::new(t.0)))), + ), + TypeVariant::HasOptions => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::HasOptions(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), -TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Arr => Box::new( + ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Arr(Box::new(t)))), + ), + TypeVariant::HasOptions => Box::new( + ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Arr(ref v) => v.as_ref(), -Self::HasOptions(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr(_) => "Arr", -Self::HasOptions(_) => "HasOptions", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), + TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Arr(_) => TypeVariant::Arr, -Self::HasOptions(_) => TypeVariant::HasOptions, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Arr(ref v) => v.as_ref(), + Self::HasOptions(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr(_) => "Arr", + Self::HasOptions(_) => "HasOptions", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Arr(_) => TypeVariant::Arr, + Self::HasOptions(_) => TypeVariant::HasOptions, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Arr(v) => v.write_xdr(w), -Self::HasOptions(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Arr(v) => v.write_xdr(w), + Self::HasOptions(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index a6e91403c..9807c22c5 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/struct.x", "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/struct.x", + "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2713,272 +2746,330 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct MyStruct { - pub some_int: i32, - pub a_big_int: i64, - pub some_opaque: [u8; 10], - pub some_string: StringM, - pub max_string: StringM::<100>, + pub some_int: i32, + pub a_big_int: i64, + pub some_opaque: [u8; 10], + pub some_string: StringM, + pub max_string: StringM<100>, } - impl ReadXdr for MyStruct { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self{ - some_int: i32::read_xdr(r)?, -a_big_int: i64::read_xdr(r)?, -some_opaque: <[u8; 10]>::read_xdr(r)?, -some_string: StringM::read_xdr(r)?, -max_string: StringM::<100>::read_xdr(r)?, - }) - }) - } - } +impl ReadXdr for MyStruct { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self { + some_int: i32::read_xdr(r)?, + a_big_int: i64::read_xdr(r)?, + some_opaque: <[u8; 10]>::read_xdr(r)?, + some_string: StringM::read_xdr(r)?, + max_string: StringM::<100>::read_xdr(r)?, + }) + }) + } +} - impl WriteXdr for MyStruct { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; -self.a_big_int.write_xdr(w)?; -self.some_opaque.write_xdr(w)?; -self.some_string.write_xdr(w)?; -self.max_string.write_xdr(w)?; - Ok(()) - }) - } - } +impl WriteXdr for MyStruct { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; + self.a_big_int.write_xdr(w)?; + self.some_opaque.write_xdr(w)?; + self.some_string.write_xdr(w)?; + self.max_string.write_xdr(w)?; + Ok(()) + }) + } +} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - Int64, -MyStruct, - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + Int64, + MyStruct, +} - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, -TypeVariant::MyStruct, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", -"MyStruct", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64 => "Int64", -Self::MyStruct => "MyStruct", - } - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; + pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64 => "Int64", + Self::MyStruct => "MyStruct", } + } - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } +} - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Int64" => Ok(Self::Int64), -"MyStruct" => Ok(Self::MyStruct), - _ => Err(Error::Invalid), - } - } - } +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - Int64(Box), -MyStruct(Box), +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Int64" => Ok(Self::Int64), + "MyStruct" => Ok(Self::MyStruct), + _ => Err(Error::Invalid), } + } +} - impl Type { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, -TypeVariant::MyStruct, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", -"MyStruct", ]; - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Int64 => r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))), -TypeVariant::MyStruct => r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))), - } - } +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + Int64(Box), + MyStruct(Box), +} - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } +impl Type { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; + pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Int64 => { + r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::MyStruct => { + r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), -TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t.0))))), -TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), -TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new( + ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Int64(Box::new(t)))), + ), + TypeVariant::MyStruct => Box::new( + ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Int64(Box::new(t.0)))), + ), + TypeVariant::MyStruct => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyStruct(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Int64 => Box::new( + ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Int64(Box::new(t)))), + ), + TypeVariant::MyStruct => Box::new( + ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Int64(ref v) => v.as_ref(), -Self::MyStruct(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64(_) => "Int64", -Self::MyStruct(_) => "MyStruct", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Int64(_) => TypeVariant::Int64, -Self::MyStruct(_) => TypeVariant::MyStruct, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Int64(ref v) => v.as_ref(), + Self::MyStruct(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64(_) => "Int64", + Self::MyStruct(_) => "MyStruct", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Int64(_) => TypeVariant::Int64, + Self::MyStruct(_) => TypeVariant::MyStruct, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Int64(v) => v.write_xdr(w), -Self::MyStruct(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Int64(v) => v.write_xdr(w), + Self::MyStruct(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index fbb23396f..ad5a7c94b 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -874,7 +874,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1282,7 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1664,7 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2036,7 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2699,7 +2699,7 @@ mod test { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2816,7 +2816,7 @@ impl AsRef<[u8]> for Uint512 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint513(pub BytesM::<64>); @@ -2918,7 +2918,7 @@ impl AsRef<[u8]> for Uint513 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint514(pub BytesM); @@ -3020,7 +3020,7 @@ impl AsRef<[u8]> for Uint514 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str(pub StringM::<64>); @@ -3122,7 +3122,7 @@ impl AsRef<[u8]> for Str { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str2(pub StringM); @@ -3223,7 +3223,7 @@ impl AsRef<[u8]> for Str2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3339,7 +3339,7 @@ impl AsRef<[u8]> for Hash { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes1(pub [Hash; 12]); @@ -3429,7 +3429,7 @@ impl AsRef<[Hash]> for Hashes1 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes2(pub VecM::); @@ -3531,7 +3531,7 @@ impl AsRef<[Hash]> for Hashes2 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes3(pub VecM::); @@ -3632,7 +3632,7 @@ impl AsRef<[Hash]> for Hashes3 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash1(pub Option); @@ -3684,7 +3684,7 @@ impl WriteXdr for OptHash1 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash2(pub Option); @@ -3777,7 +3777,7 @@ pub type Int4 = u64; #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyStruct { pub field1: Uint512, pub field2: OptHash1, @@ -3833,7 +3833,7 @@ self.field7.write_xdr(w)?; #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct LotsOfMyStructs { pub members: VecM::, } @@ -3871,7 +3871,7 @@ impl WriteXdr for LotsOfMyStructs { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct HasStuff { pub data: LotsOfMyStructs, } @@ -3911,7 +3911,7 @@ impl WriteXdr for HasStuff { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { Red = 0, @@ -4035,7 +4035,7 @@ pub const BAR: u64 = FOO; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum NesterNestedEnum { 1 = 0, @@ -4136,7 +4136,7 @@ Self::2 => "2", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct NesterNestedStruct { pub blah: i32, } @@ -4177,7 +4177,7 @@ impl WriteXdr for NesterNestedStruct { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum NesterNestedUnion { Red, @@ -4292,7 +4292,7 @@ impl WriteXdr for NesterNestedUnion { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Nester { pub nested_enum: NesterNestedEnum, pub nested_struct: NesterNestedStruct, @@ -4330,10 +4330,7 @@ self.nested_union.write_xdr(w)?; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum TypeVariant { Uint512, Uint513, @@ -4498,10 +4495,7 @@ Self::NesterNestedUnion => "NesterNestedUnion", serde(rename_all = "snake_case"), serde(untagged), )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum Type { Uint512(Box), Uint513(Box), diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 9999db598..606846e05 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/union.x", "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/union.x", + "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2718,96 +2751,106 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum UnionKey { - Error = 0, - Multi = 1, + Error = 0, + Multi = 1, } - impl UnionKey { - pub const VARIANTS: [UnionKey; 2] = [ UnionKey::Error, -UnionKey::Multi, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Error", -"Multi", ]; +impl UnionKey { + pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; + pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error => "Error", -Self::Multi => "Multi", - } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error => "Error", + Self::Multi => "Multi", } + } - impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } +} - impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } +impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Enum for UnionKey {} +impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Enum for UnionKey {} - impl TryFrom for UnionKey { - type Error = Error; +impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - fn try_from(i: i32) -> Result { - let e = match i { - 0 => UnionKey::Error, -1 => UnionKey::Multi, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl TryFrom for UnionKey { + type Error = Error; - impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => UnionKey::Error, + 1 => UnionKey::Multi, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } +} - impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// MyUnion is an XDR Union defines as: /// @@ -2818,108 +2861,114 @@ Self::Multi => "Multi", /// Error error; /// case MULTI: /// Multi things<>; -/// -/// +/// +/// /// }; /// ``` /// // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - Error(i32), - Multi(VecM::), -} - - impl MyUnion { - pub const VARIANTS: [UnionKey; 2] = [ - UnionKey::Error, -UnionKey::Multi, - ]; - pub const VARIANTS_STR: [&'static str; 2] = [ - "Error", -"Multi", - ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error(_) => "Error", -Self::Multi(_) => "Multi", - } - } + Error(i32), + Multi(VecM), +} - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::Error(_) => UnionKey::Error, -Self::Multi(_) => UnionKey::Multi, - } - } +impl MyUnion { + pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; + pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error(_) => "Error", + Self::Multi(_) => "Multi", } + } - impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::Error(_) => UnionKey::Error, + Self::Multi(_) => UnionKey::Multi, } + } - impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } +} - impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } +impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Union for MyUnion {} +impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } +} - impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::Error => Self::Error(i32::read_xdr(r)?), -UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } - } +impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::Error(v) => v.write_xdr(w)?, -Self::Multi(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } - } +impl Union for MyUnion {} + +impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::Error => Self::Error(i32::read_xdr(r)?), + UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} + +impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::Error(v) => v.write_xdr(w)?, + Self::Multi(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } +} /// IntUnion is an XDR Union defines as: /// @@ -2930,107 +2979,113 @@ Self::Multi(v) => v.write_xdr(w)?, /// Error error; /// case 1: /// Multi things<>; -/// +/// /// }; /// ``` /// // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[allow(clippy::large_enum_variant)] pub enum IntUnion { - V0(i32), - V1(VecM::), -} - - impl IntUnion { - pub const VARIANTS: [i32; 2] = [ - 0, -1, - ]; - pub const VARIANTS_STR: [&'static str; 2] = [ - "V0", -"V1", - ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::V0(_) => "V0", -Self::V1(_) => "V1", - } - } + V0(i32), + V1(VecM), +} - #[must_use] - pub const fn discriminant(&self) -> i32 { - #[allow(clippy::match_same_arms)] - match self { - Self::V0(_) => 0, -Self::V1(_) => 1, - } - } +impl IntUnion { + pub const VARIANTS: [i32; 2] = [0, 1]; + pub const VARIANTS_STR: [&'static str; 2] = ["V0", "V1"]; - #[must_use] - pub const fn variants() -> [i32; 2] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::V0(_) => "V0", + Self::V1(_) => "V1", } + } - impl Name for IntUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn discriminant(&self) -> i32 { + #[allow(clippy::match_same_arms)] + match self { + Self::V0(_) => 0, + Self::V1(_) => 1, } + } - impl Discriminant for IntUnion { - #[must_use] - fn discriminant(&self) -> i32 { - Self::discriminant(self) - } - } + #[must_use] + pub const fn variants() -> [i32; 2] { + Self::VARIANTS + } +} - impl Variants for IntUnion { - fn variants() -> slice::Iter<'static, i32> { - Self::VARIANTS.iter() - } - } +impl Name for IntUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Union for IntUnion {} +impl Discriminant for IntUnion { + #[must_use] + fn discriminant(&self) -> i32 { + Self::discriminant(self) + } +} - impl ReadXdr for IntUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: i32 = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - 0 => Self::V0(i32::read_xdr(r)?), -1 => Self::V1(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } - } +impl Variants for IntUnion { + fn variants() -> slice::Iter<'static, i32> { + Self::VARIANTS.iter() + } +} - impl WriteXdr for IntUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::V0(v) => v.write_xdr(w)?, -Self::V1(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } - } +impl Union for IntUnion {} + +impl ReadXdr for IntUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: i32 = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + 0 => Self::V0(i32::read_xdr(r)?), + 1 => Self::V1(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} + +impl WriteXdr for IntUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::V0(v) => v.write_xdr(w)?, + Self::V1(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } +} /// IntUnion2 is an XDR Typedef defines as: /// @@ -3040,8 +3095,20 @@ Self::V1(v) => v.write_xdr(w)?, /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3080,305 +3147,407 @@ impl ReadXdr for IntUnion2 { impl WriteXdr for IntUnion2 { #[cfg(feature = "std")] fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w|{ self.0.write_xdr(w) }) - } -} - - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - SError, -Multi, -UnionKey, -MyUnion, -IntUnion, -IntUnion2, - } - - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, -TypeVariant::Multi, -TypeVariant::UnionKey, -TypeVariant::MyUnion, -TypeVariant::IntUnion, -TypeVariant::IntUnion2, ]; - pub const VARIANTS_STR: [&'static str; 6] = [ "SError", -"Multi", -"UnionKey", -"MyUnion", -"IntUnion", -"IntUnion2", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError => "SError", -Self::Multi => "Multi", -Self::UnionKey => "UnionKey", -Self::MyUnion => "MyUnion", -Self::IntUnion => "IntUnion", -Self::IntUnion2 => "IntUnion2", - } - } + w.with_limited_depth(|w| self.0.write_xdr(w)) + } +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + SError, + Multi, + UnionKey, + MyUnion, + IntUnion, + IntUnion2, +} + +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 6] = [ + TypeVariant::SError, + TypeVariant::Multi, + TypeVariant::UnionKey, + TypeVariant::MyUnion, + TypeVariant::IntUnion, + TypeVariant::IntUnion2, + ]; + pub const VARIANTS_STR: [&'static str; 6] = [ + "SError", + "Multi", + "UnionKey", + "MyUnion", + "IntUnion", + "IntUnion2", + ]; - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError => "SError", + Self::Multi => "Multi", + Self::UnionKey => "UnionKey", + Self::MyUnion => "MyUnion", + Self::IntUnion => "IntUnion", + Self::IntUnion2 => "IntUnion2", } + } - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "SError" => Ok(Self::SError), -"Multi" => Ok(Self::Multi), -"UnionKey" => Ok(Self::UnionKey), -"MyUnion" => Ok(Self::MyUnion), -"IntUnion" => Ok(Self::IntUnion), -"IntUnion2" => Ok(Self::IntUnion2), - _ => Err(Error::Invalid), - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "SError" => Ok(Self::SError), + "Multi" => Ok(Self::Multi), + "UnionKey" => Ok(Self::UnionKey), + "MyUnion" => Ok(Self::MyUnion), + "IntUnion" => Ok(Self::IntUnion), + "IntUnion2" => Ok(Self::IntUnion2), + _ => Err(Error::Invalid), } + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - SError(Box), -Multi(Box), -UnionKey(Box), -MyUnion(Box), -IntUnion(Box), -IntUnion2(Box), - } - - impl Type { - pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, -TypeVariant::Multi, -TypeVariant::UnionKey, -TypeVariant::MyUnion, -TypeVariant::IntUnion, -TypeVariant::IntUnion2, ]; - pub const VARIANTS_STR: [&'static str; 6] = [ "SError", -"Multi", -"UnionKey", -"MyUnion", -"IntUnion", -"IntUnion2", ]; +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + SError(Box), + Multi(Box), + UnionKey(Box), + MyUnion(Box), + IntUnion(Box), + IntUnion2(Box), +} + +impl Type { + pub const VARIANTS: [TypeVariant; 6] = [ + TypeVariant::SError, + TypeVariant::Multi, + TypeVariant::UnionKey, + TypeVariant::MyUnion, + TypeVariant::IntUnion, + TypeVariant::IntUnion2, + ]; + pub const VARIANTS_STR: [&'static str; 6] = [ + "SError", + "Multi", + "UnionKey", + "MyUnion", + "IntUnion", + "IntUnion2", + ]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::SError => r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))), -TypeVariant::Multi => r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))), -TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), -TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), -TypeVariant::IntUnion => r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))), -TypeVariant::IntUnion2 => r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))), - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::SError => { + r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) + TypeVariant::Multi => { + r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + TypeVariant::UnionKey => { + r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::MyUnion => { + r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), -TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), -TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), -TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), - } + TypeVariant::IntUnion => { + r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t.0))))), -TypeVariant::Multi => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t.0))))), -TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), -TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t.0))))), -TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0))))), - } + TypeVariant::IntUnion2 => { + r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))) } + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), -TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), -TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), -TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), -TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), -TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), -TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new( + ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::SError(Box::new(t)))), + ), + TypeVariant::Multi => Box::new( + ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Multi(Box::new(t)))), + ), + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::IntUnion => Box::new( + ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), + ), + TypeVariant::IntUnion2 => Box::new( + ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::SError(ref v) => v.as_ref(), -Self::Multi(ref v) => v.as_ref(), -Self::UnionKey(ref v) => v.as_ref(), -Self::MyUnion(ref v) => v.as_ref(), -Self::IntUnion(ref v) => v.as_ref(), -Self::IntUnion2(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::SError(Box::new(t.0)))), + ), + TypeVariant::Multi => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Multi(Box::new(t.0)))), + ), + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), + ), + TypeVariant::IntUnion => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion(Box::new(t.0)))), + ), + TypeVariant::IntUnion2 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0)))), + ), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError(_) => "SError", -Self::Multi(_) => "Multi", -Self::UnionKey(_) => "UnionKey", -Self::MyUnion(_) => "MyUnion", -Self::IntUnion(_) => "IntUnion", -Self::IntUnion2(_) => "IntUnion2", - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::SError => Box::new( + ReadXdrIter::<_, SError>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::SError(Box::new(t)))), + ), + TypeVariant::Multi => Box::new( + ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Multi(Box::new(t)))), + ), + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::IntUnion => Box::new( + ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), + ), + TypeVariant::IntUnion2 => Box::new( + ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), + ), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::SError(_) => TypeVariant::SError, -Self::Multi(_) => TypeVariant::Multi, -Self::UnionKey(_) => TypeVariant::UnionKey, -Self::MyUnion(_) => TypeVariant::MyUnion, -Self::IntUnion(_) => TypeVariant::IntUnion, -Self::IntUnion2(_) => TypeVariant::IntUnion2, - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), + TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), + TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), + TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::SError(ref v) => v.as_ref(), + Self::Multi(ref v) => v.as_ref(), + Self::UnionKey(ref v) => v.as_ref(), + Self::MyUnion(ref v) => v.as_ref(), + Self::IntUnion(ref v) => v.as_ref(), + Self::IntUnion2(ref v) => v.as_ref(), } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError(_) => "SError", + Self::Multi(_) => "Multi", + Self::UnionKey(_) => "UnionKey", + Self::MyUnion(_) => "MyUnion", + Self::IntUnion(_) => "IntUnion", + Self::IntUnion2(_) => "IntUnion2", } + } - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::SError(v) => v.write_xdr(w), -Self::Multi(v) => v.write_xdr(w), -Self::UnionKey(v) => v.write_xdr(w), -Self::MyUnion(v) => v.write_xdr(w), -Self::IntUnion(v) => v.write_xdr(w), -Self::IntUnion2(v) => v.write_xdr(w), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::SError(_) => TypeVariant::SError, + Self::Multi(_) => TypeVariant::Multi, + Self::UnionKey(_) => TypeVariant::UnionKey, + Self::MyUnion(_) => TypeVariant::MyUnion, + Self::IntUnion(_) => TypeVariant::IntUnion, + Self::IntUnion2(_) => TypeVariant::IntUnion2, } + } +} + +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::SError(v) => v.write_xdr(w), + Self::Multi(v) => v.write_xdr(w), + Self::UnionKey(v) => v.write_xdr(w), + Self::MyUnion(v) => v.write_xdr(w), + Self::IntUnion(v) => v.write_xdr(w), + Self::IntUnion2(v) => v.write_xdr(w), + } + } +} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index c4a26e2ad..66aaeab58 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/block_comments.x", "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/block_comments.x", + "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2702,16 +2735,28 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum AccountFlags { - AuthRequiredFlag = 1, + AuthRequiredFlag = 1, } impl AccountFlags { - pub const VARIANTS: [AccountFlags; 1] = [ AccountFlags::AuthRequiredFlag, ]; - pub const VARIANTS_STR: [&'static str; 1] = [ "AuthRequiredFlag", ]; + pub const VARIANTS: [AccountFlags; 1] = [AccountFlags::AuthRequiredFlag]; + pub const VARIANTS_STR: [&'static str; 1] = ["AuthRequiredFlag"]; #[must_use] pub const fn name(&self) -> &'static str { @@ -2790,21 +2835,26 @@ impl WriteXdr for AccountFlags { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") )] #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) )] pub enum TypeVariant { AccountFlags, } impl TypeVariant { - pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; - pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; + pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; + pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; #[must_use] #[allow(clippy::too_many_lines)] @@ -2847,34 +2897,44 @@ impl core::str::FromStr for TypeVariant { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) )] #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) )] pub enum Type { AccountFlags(Box), } impl Type { - pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; - pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; + pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; + pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { match v { - TypeVariant::AccountFlags => r.with_limited_depth(|r| Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?)))), + TypeVariant::AccountFlags => r.with_limited_depth(|r| { + Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?))) + }), } } #[cfg(feature = "base64")] pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); let t = Self::read_xdr(v, &mut dec)?; Ok(t) } @@ -2893,33 +2953,54 @@ impl Type { #[cfg(feature = "base64")] pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), + TypeVariant::AccountFlags => Box::new( + ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), + ), } } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0))))), + TypeVariant::AccountFlags => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0)))), + ), } } #[cfg(feature = "base64")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); match v { - TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), + TypeVariant::AccountFlags => Box::new( + ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), + ), } } @@ -2933,7 +3014,10 @@ impl Type { #[cfg(feature = "base64")] pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } @@ -2942,7 +3026,9 @@ impl Type { #[allow(clippy::too_many_lines)] pub fn read_json(v: TypeVariant, r: impl Read) -> Result { match v { - TypeVariant::AccountFlags => Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))), + TypeVariant::AccountFlags => { + Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))) + } } } diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index e825a26e0..b3a737966 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/const.x", "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/const.x", + "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2712,235 +2745,281 @@ pub type TestArray = [i32; Foo]; /// typedef int TestArray2; /// ``` /// -pub type TestArray2 = VecM::; - - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - TestArray, -TestArray2, - } +pub type TestArray2 = VecM; - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, -TypeVariant::TestArray2, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", -"TestArray2", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray => "TestArray", -Self::TestArray2 => "TestArray2", - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + TestArray, + TestArray2, +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; + pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray => "TestArray", + Self::TestArray2 => "TestArray2", } + } - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "TestArray" => Ok(Self::TestArray), -"TestArray2" => Ok(Self::TestArray2), - _ => Err(Error::Invalid), - } - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - TestArray(Box), -TestArray2(Box), - } +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} - impl Type { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, -TypeVariant::TestArray2, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", -"TestArray2", ]; +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "TestArray" => Ok(Self::TestArray), + "TestArray2" => Ok(Self::TestArray2), + _ => Err(Error::Invalid), + } + } +} - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::TestArray => r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))), -TypeVariant::TestArray2 => r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))), - } - } +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + TestArray(Box), + TestArray2(Box), +} - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } +impl Type { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; + pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::TestArray => { + r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::TestArray2 => { + r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), -TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t.0))))), -TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), -TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new( + ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), + ), + TypeVariant::TestArray2 => Box::new( + ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray(Box::new(t.0)))), + ), + TypeVariant::TestArray2 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray2(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), -TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::TestArray => Box::new( + ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), + ), + TypeVariant::TestArray2 => Box::new( + ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::TestArray(ref v) => v.as_ref(), -Self::TestArray2(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray(_) => "TestArray", -Self::TestArray2(_) => "TestArray2", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), + TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::TestArray(_) => TypeVariant::TestArray, -Self::TestArray2(_) => TypeVariant::TestArray2, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::TestArray(ref v) => v.as_ref(), + Self::TestArray2(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray(_) => "TestArray", + Self::TestArray2(_) => "TestArray2", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::TestArray(_) => TypeVariant::TestArray, + Self::TestArray2(_) => TypeVariant::TestArray2, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::TestArray(v) => v.write_xdr(w), -Self::TestArray2(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::TestArray(v) => v.write_xdr(w), + Self::TestArray2(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index 183011106..5311dbe7b 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/enum.x", "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/enum.x", + "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2698,19 +2731,19 @@ mod test { /// ERROR_MSG, /// HELLO, /// DONT_HAVE, -/// +/// /// GET_PEERS, // gets a list of peers this guy knows about /// PEERS, -/// +/// /// GET_TX_SET, // gets a particular txset by hash /// TX_SET, -/// +/// /// GET_VALIDATIONS, // gets validations for a given ledger hash /// VALIDATIONS, -/// +/// /// TRANSACTION, //pass on a tx you have heard about /// JSON_TRANSACTION, -/// +/// /// // FBA /// GET_FBA_QUORUMSET, /// FBA_QUORUMSET, @@ -2721,156 +2754,172 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum MessageType { - ErrorMsg = 0, - Hello = 1, - DontHave = 2, - GetPeers = 3, - Peers = 4, - GetTxSet = 5, - TxSet = 6, - GetValidations = 7, - Validations = 8, - Transaction = 9, - JsonTransaction = 10, - GetFbaQuorumset = 11, - FbaQuorumset = 12, - FbaMessage = 13, -} - - impl MessageType { - pub const VARIANTS: [MessageType; 14] = [ MessageType::ErrorMsg, -MessageType::Hello, -MessageType::DontHave, -MessageType::GetPeers, -MessageType::Peers, -MessageType::GetTxSet, -MessageType::TxSet, -MessageType::GetValidations, -MessageType::Validations, -MessageType::Transaction, -MessageType::JsonTransaction, -MessageType::GetFbaQuorumset, -MessageType::FbaQuorumset, -MessageType::FbaMessage, ]; - pub const VARIANTS_STR: [&'static str; 14] = [ "ErrorMsg", -"Hello", -"DontHave", -"GetPeers", -"Peers", -"GetTxSet", -"TxSet", -"GetValidations", -"Validations", -"Transaction", -"JsonTransaction", -"GetFbaQuorumset", -"FbaQuorumset", -"FbaMessage", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::ErrorMsg => "ErrorMsg", -Self::Hello => "Hello", -Self::DontHave => "DontHave", -Self::GetPeers => "GetPeers", -Self::Peers => "Peers", -Self::GetTxSet => "GetTxSet", -Self::TxSet => "TxSet", -Self::GetValidations => "GetValidations", -Self::Validations => "Validations", -Self::Transaction => "Transaction", -Self::JsonTransaction => "JsonTransaction", -Self::GetFbaQuorumset => "GetFbaQuorumset", -Self::FbaQuorumset => "FbaQuorumset", -Self::FbaMessage => "FbaMessage", - } - } + ErrorMsg = 0, + Hello = 1, + DontHave = 2, + GetPeers = 3, + Peers = 4, + GetTxSet = 5, + TxSet = 6, + GetValidations = 7, + Validations = 8, + Transaction = 9, + JsonTransaction = 10, + GetFbaQuorumset = 11, + FbaQuorumset = 12, + FbaMessage = 13, +} + +impl MessageType { + pub const VARIANTS: [MessageType; 14] = [ + MessageType::ErrorMsg, + MessageType::Hello, + MessageType::DontHave, + MessageType::GetPeers, + MessageType::Peers, + MessageType::GetTxSet, + MessageType::TxSet, + MessageType::GetValidations, + MessageType::Validations, + MessageType::Transaction, + MessageType::JsonTransaction, + MessageType::GetFbaQuorumset, + MessageType::FbaQuorumset, + MessageType::FbaMessage, + ]; + pub const VARIANTS_STR: [&'static str; 14] = [ + "ErrorMsg", + "Hello", + "DontHave", + "GetPeers", + "Peers", + "GetTxSet", + "TxSet", + "GetValidations", + "Validations", + "Transaction", + "JsonTransaction", + "GetFbaQuorumset", + "FbaQuorumset", + "FbaMessage", + ]; - #[must_use] - pub const fn variants() -> [MessageType; 14] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::ErrorMsg => "ErrorMsg", + Self::Hello => "Hello", + Self::DontHave => "DontHave", + Self::GetPeers => "GetPeers", + Self::Peers => "Peers", + Self::GetTxSet => "GetTxSet", + Self::TxSet => "TxSet", + Self::GetValidations => "GetValidations", + Self::Validations => "Validations", + Self::Transaction => "Transaction", + Self::JsonTransaction => "JsonTransaction", + Self::GetFbaQuorumset => "GetFbaQuorumset", + Self::FbaQuorumset => "FbaQuorumset", + Self::FbaMessage => "FbaMessage", } + } - impl Name for MessageType { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + pub const fn variants() -> [MessageType; 14] { + Self::VARIANTS + } +} - impl Variants for MessageType { - fn variants() -> slice::Iter<'static, MessageType> { - Self::VARIANTS.iter() - } - } +impl Name for MessageType { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Enum for MessageType {} +impl Variants for MessageType { + fn variants() -> slice::Iter<'static, MessageType> { + Self::VARIANTS.iter() + } +} - impl fmt::Display for MessageType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Enum for MessageType {} - impl TryFrom for MessageType { - type Error = Error; - - fn try_from(i: i32) -> Result { - let e = match i { - 0 => MessageType::ErrorMsg, -1 => MessageType::Hello, -2 => MessageType::DontHave, -3 => MessageType::GetPeers, -4 => MessageType::Peers, -5 => MessageType::GetTxSet, -6 => MessageType::TxSet, -7 => MessageType::GetValidations, -8 => MessageType::Validations, -9 => MessageType::Transaction, -10 => MessageType::JsonTransaction, -11 => MessageType::GetFbaQuorumset, -12 => MessageType::FbaQuorumset, -13 => MessageType::FbaMessage, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for MessageType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: MessageType) -> Self { - e as Self - } - } +impl TryFrom for MessageType { + type Error = Error; - impl ReadXdr for MessageType { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => MessageType::ErrorMsg, + 1 => MessageType::Hello, + 2 => MessageType::DontHave, + 3 => MessageType::GetPeers, + 4 => MessageType::Peers, + 5 => MessageType::GetTxSet, + 6 => MessageType::TxSet, + 7 => MessageType::GetValidations, + 8 => MessageType::Validations, + 9 => MessageType::Transaction, + 10 => MessageType::JsonTransaction, + 11 => MessageType::GetFbaQuorumset, + 12 => MessageType::FbaQuorumset, + 13 => MessageType::FbaMessage, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for MessageType { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: MessageType) -> Self { + e as Self + } +} + +impl ReadXdr for MessageType { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for MessageType { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// Color is an XDR Enum defines as: /// @@ -2885,101 +2934,109 @@ Self::FbaMessage => "FbaMessage", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum Color { - Red = 0, - Green = 1, - Blue = 2, -} - - impl Color { - pub const VARIANTS: [Color; 3] = [ Color::Red, -Color::Green, -Color::Blue, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "Red", -"Green", -"Blue", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red => "Red", -Self::Green => "Green", -Self::Blue => "Blue", - } - } + Red = 0, + Green = 1, + Blue = 2, +} - #[must_use] - pub const fn variants() -> [Color; 3] { - Self::VARIANTS - } - } +impl Color { + pub const VARIANTS: [Color; 3] = [Color::Red, Color::Green, Color::Blue]; + pub const VARIANTS_STR: [&'static str; 3] = ["Red", "Green", "Blue"]; - impl Name for Color { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red => "Red", + Self::Green => "Green", + Self::Blue => "Blue", } + } - impl Variants for Color { - fn variants() -> slice::Iter<'static, Color> { - Self::VARIANTS.iter() - } - } + #[must_use] + pub const fn variants() -> [Color; 3] { + Self::VARIANTS + } +} - impl Enum for Color {} +impl Name for Color { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl fmt::Display for Color { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Variants for Color { + fn variants() -> slice::Iter<'static, Color> { + Self::VARIANTS.iter() + } +} - impl TryFrom for Color { - type Error = Error; +impl Enum for Color {} - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color::Red, -1 => Color::Green, -2 => Color::Blue, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for Color { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: Color) -> Self { - e as Self - } - } +impl TryFrom for Color { + type Error = Error; - impl ReadXdr for Color { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color::Red, + 1 => Color::Green, + 2 => Color::Blue, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for Color { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: Color) -> Self { + e as Self + } +} + +impl ReadXdr for Color { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for Color { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// Color2 is an XDR Enum defines as: /// @@ -2994,345 +3051,408 @@ Self::Blue => "Blue", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] #[repr(i32)] pub enum Color2 { - Red2 = 0, - Green2 = 1, - Blue2 = 2, -} - - impl Color2 { - pub const VARIANTS: [Color2; 3] = [ Color2::Red2, -Color2::Green2, -Color2::Blue2, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "Red2", -"Green2", -"Blue2", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red2 => "Red2", -Self::Green2 => "Green2", -Self::Blue2 => "Blue2", - } - } + Red2 = 0, + Green2 = 1, + Blue2 = 2, +} - #[must_use] - pub const fn variants() -> [Color2; 3] { - Self::VARIANTS - } - } +impl Color2 { + pub const VARIANTS: [Color2; 3] = [Color2::Red2, Color2::Green2, Color2::Blue2]; + pub const VARIANTS_STR: [&'static str; 3] = ["Red2", "Green2", "Blue2"]; - impl Name for Color2 { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red2 => "Red2", + Self::Green2 => "Green2", + Self::Blue2 => "Blue2", } + } - impl Variants for Color2 { - fn variants() -> slice::Iter<'static, Color2> { - Self::VARIANTS.iter() - } - } + #[must_use] + pub const fn variants() -> [Color2; 3] { + Self::VARIANTS + } +} - impl Enum for Color2 {} +impl Name for Color2 { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl fmt::Display for Color2 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Variants for Color2 { + fn variants() -> slice::Iter<'static, Color2> { + Self::VARIANTS.iter() + } +} - impl TryFrom for Color2 { - type Error = Error; +impl Enum for Color2 {} - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color2::Red2, -1 => Color2::Green2, -2 => Color2::Blue2, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for Color2 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: Color2) -> Self { - e as Self - } - } +impl TryFrom for Color2 { + type Error = Error; - impl ReadXdr for Color2 { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color2::Red2, + 1 => Color2::Green2, + 2 => Color2::Blue2, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for Color2 { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: Color2) -> Self { + e as Self + } +} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - MessageType, -Color, -Color2, - } - - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, -TypeVariant::Color, -TypeVariant::Color2, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", -"Color", -"Color2", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType => "MessageType", -Self::Color => "Color", -Self::Color2 => "Color2", - } - } +impl ReadXdr for Color2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS - } - } +impl WriteXdr for Color2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + MessageType, + Color, + Color2, +} - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 3] = [ + TypeVariant::MessageType, + TypeVariant::Color, + TypeVariant::Color2, + ]; + pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType => "MessageType", + Self::Color => "Color", + Self::Color2 => "Color2", } + } - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "MessageType" => Ok(Self::MessageType), -"Color" => Ok(Self::Color), -"Color2" => Ok(Self::Color2), - _ => Err(Error::Invalid), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } +} + +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "MessageType" => Ok(Self::MessageType), + "Color" => Ok(Self::Color), + "Color2" => Ok(Self::Color2), + _ => Err(Error::Invalid), } + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - MessageType(Box), -Color(Box), -Color2(Box), - } - - impl Type { - pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, -TypeVariant::Color, -TypeVariant::Color2, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", -"Color", -"Color2", ]; +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + MessageType(Box), + Color(Box), + Color2(Box), +} - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::MessageType => r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))), -TypeVariant::Color => r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))), -TypeVariant::Color2 => r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))), - } - } +impl Type { + pub const VARIANTS: [TypeVariant; 3] = [ + TypeVariant::MessageType, + TypeVariant::Color, + TypeVariant::Color2, + ]; + pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::MessageType => { + r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + TypeVariant::Color => { + r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::Color2 => { + r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), -TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), -TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t.0))))), -TypeVariant::Color => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t.0))))), -TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), -TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), -TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new( + ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), + ), + TypeVariant::Color => Box::new( + ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color(Box::new(t)))), + ), + TypeVariant::Color2 => Box::new( + ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color2(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MessageType(Box::new(t.0)))), + ), + TypeVariant::Color => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color(Box::new(t.0)))), + ), + TypeVariant::Color2 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color2(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::MessageType => Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::MessageType => Box::new( + ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), + ), + TypeVariant::Color => Box::new( + ReadXdrIter::<_, Color>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Color(Box::new(t)))), + ), + TypeVariant::Color2 => Box::new( + ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Color2(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::MessageType(ref v) => v.as_ref(), -Self::Color(ref v) => v.as_ref(), -Self::Color2(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType(_) => "MessageType", -Self::Color(_) => "Color", -Self::Color2(_) => "Color2", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::MessageType => { + Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))) } + TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), + TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::MessageType(_) => TypeVariant::MessageType, -Self::Color(_) => TypeVariant::Color, -Self::Color2(_) => TypeVariant::Color2, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::MessageType(ref v) => v.as_ref(), + Self::Color(ref v) => v.as_ref(), + Self::Color2(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType(_) => "MessageType", + Self::Color(_) => "Color", + Self::Color2(_) => "Color2", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::MessageType(_) => TypeVariant::MessageType, + Self::Color(_) => TypeVariant::Color, + Self::Color2(_) => TypeVariant::Color2, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::MessageType(v) => v.write_xdr(w), -Self::Color(v) => v.write_xdr(w), -Self::Color2(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::MessageType(v) => v.write_xdr(w), + Self::Color(v) => v.write_xdr(w), + Self::Color2(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index 1a3607fa2..da9eab925 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/nesting.x", "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/nesting.x", + "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2703,100 +2736,100 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] #[repr(i32)] pub enum UnionKey { - One = 1, - Two = 2, - Offer = 3, -} - - impl UnionKey { - pub const VARIANTS: [UnionKey; 3] = [ UnionKey::One, -UnionKey::Two, -UnionKey::Offer, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "One", -"Two", -"Offer", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One => "One", -Self::Two => "Two", -Self::Offer => "Offer", - } - } + One = 1, + Two = 2, + Offer = 3, +} - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } - } +impl UnionKey { + pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; + pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; - impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One => "One", + Self::Two => "Two", + Self::Offer => "Offer", } + } - impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } +} - impl Enum for UnionKey {} +impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl TryFrom for UnionKey { - type Error = Error; +impl Enum for UnionKey {} - fn try_from(i: i32) -> Result { - let e = match i { - 1 => UnionKey::One, -2 => UnionKey::Two, -3 => UnionKey::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } - } +impl TryFrom for UnionKey { + type Error = Error; - impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 1 => UnionKey::One, + 2 => UnionKey::Two, + 3 => UnionKey::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } +} + +impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// Foo is an XDR Typedef defines as: /// @@ -2816,18 +2849,30 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct MyUnionOne { - pub some_int: i32, + pub some_int: i32, } impl ReadXdr for MyUnionOne { #[cfg(feature = "std")] fn read_xdr(r: &mut Limited) -> Result { r.with_limited_depth(|r| { - Ok(Self{ - some_int: i32::read_xdr(r)?, + Ok(Self { + some_int: i32::read_xdr(r)?, }) }) } @@ -2854,35 +2899,47 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct MyUnionTwo { - pub some_int: i32, - pub foo: i32, + pub some_int: i32, + pub foo: i32, } - impl ReadXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self{ - some_int: i32::read_xdr(r)?, -foo: i32::read_xdr(r)?, - }) - }) - } - } +impl ReadXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self { + some_int: i32::read_xdr(r)?, + foo: i32::read_xdr(r)?, + }) + }) + } +} - impl WriteXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; -self.foo.write_xdr(w)?; - Ok(()) - }) - } - } +impl WriteXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; + self.foo.write_xdr(w)?; + Ok(()) + }) + } +} /// MyUnion is an XDR Union defines as: /// @@ -2893,13 +2950,13 @@ self.foo.write_xdr(w)?; /// struct { /// int someInt; /// } one; -/// +/// /// case TWO: /// struct { /// int someInt; /// Foo foo; /// } two; -/// +/// /// case OFFER: /// void; /// }; @@ -2908,385 +2965,462 @@ self.foo.write_xdr(w)?; // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - One(MyUnionOne), - Two(MyUnionTwo), - Offer, -} - - impl MyUnion { - pub const VARIANTS: [UnionKey; 3] = [ - UnionKey::One, -UnionKey::Two, -UnionKey::Offer, - ]; - pub const VARIANTS_STR: [&'static str; 3] = [ - "One", -"Two", -"Offer", - ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One(_) => "One", -Self::Two(_) => "Two", -Self::Offer => "Offer", - } - } + One(MyUnionOne), + Two(MyUnionTwo), + Offer, +} - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::One(_) => UnionKey::One, -Self::Two(_) => UnionKey::Two, -Self::Offer => UnionKey::Offer, - } - } +impl MyUnion { + pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; + pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One(_) => "One", + Self::Two(_) => "Two", + Self::Offer => "Offer", } + } - impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::One(_) => UnionKey::One, + Self::Two(_) => UnionKey::Two, + Self::Offer => UnionKey::Offer, } + } - impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } +} - impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } +impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Union for MyUnion {} +impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } +} - impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), -UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), -UnionKey::Offer => Self::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } - } +impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::One(v) => v.write_xdr(w)?, -Self::Two(v) => v.write_xdr(w)?, -Self::Offer => ().write_xdr(w)?, - }; - Ok(()) - }) - } - } +impl Union for MyUnion {} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - UnionKey, -Foo, -MyUnion, -MyUnionOne, -MyUnionTwo, - } - - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, -TypeVariant::Foo, -TypeVariant::MyUnion, -TypeVariant::MyUnionOne, -TypeVariant::MyUnionTwo, ]; - pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", -"Foo", -"MyUnion", -"MyUnionOne", -"MyUnionTwo", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey => "UnionKey", -Self::Foo => "Foo", -Self::MyUnion => "MyUnion", -Self::MyUnionOne => "MyUnionOne", -Self::MyUnionTwo => "MyUnionTwo", - } - } +impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), + UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), + UnionKey::Offer => Self::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } - } +impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::One(v) => v.write_xdr(w)?, + Self::Two(v) => v.write_xdr(w)?, + Self::Offer => ().write_xdr(w)?, + }; + Ok(()) + }) + } +} - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + UnionKey, + Foo, + MyUnion, + MyUnionOne, + MyUnionTwo, +} + +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 5] = [ + TypeVariant::UnionKey, + TypeVariant::Foo, + TypeVariant::MyUnion, + TypeVariant::MyUnionOne, + TypeVariant::MyUnionTwo, + ]; + pub const VARIANTS_STR: [&'static str; 5] = + ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey => "UnionKey", + Self::Foo => "Foo", + Self::MyUnion => "MyUnion", + Self::MyUnionOne => "MyUnionOne", + Self::MyUnionTwo => "MyUnionTwo", } + } - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "UnionKey" => Ok(Self::UnionKey), -"Foo" => Ok(Self::Foo), -"MyUnion" => Ok(Self::MyUnion), -"MyUnionOne" => Ok(Self::MyUnionOne), -"MyUnionTwo" => Ok(Self::MyUnionTwo), - _ => Err(Error::Invalid), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } +} + +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "UnionKey" => Ok(Self::UnionKey), + "Foo" => Ok(Self::Foo), + "MyUnion" => Ok(Self::MyUnion), + "MyUnionOne" => Ok(Self::MyUnionOne), + "MyUnionTwo" => Ok(Self::MyUnionTwo), + _ => Err(Error::Invalid), } + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - UnionKey(Box), -Foo(Box), -MyUnion(Box), -MyUnionOne(Box), -MyUnionTwo(Box), - } - - impl Type { - pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, -TypeVariant::Foo, -TypeVariant::MyUnion, -TypeVariant::MyUnionOne, -TypeVariant::MyUnionTwo, ]; - pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", -"Foo", -"MyUnion", -"MyUnionOne", -"MyUnionTwo", ]; +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + UnionKey(Box), + Foo(Box), + MyUnion(Box), + MyUnionOne(Box), + MyUnionTwo(Box), +} + +impl Type { + pub const VARIANTS: [TypeVariant; 5] = [ + TypeVariant::UnionKey, + TypeVariant::Foo, + TypeVariant::MyUnion, + TypeVariant::MyUnionOne, + TypeVariant::MyUnionTwo, + ]; + pub const VARIANTS_STR: [&'static str; 5] = + ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), -TypeVariant::Foo => r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))), -TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), -TypeVariant::MyUnionOne => r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))), -TypeVariant::MyUnionTwo => r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))), - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::UnionKey => { + r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) + TypeVariant::Foo => { + r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + TypeVariant::MyUnion => { + r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::MyUnionOne => { + r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), -TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), - } + TypeVariant::MyUnionTwo => { + r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), -TypeVariant::Foo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t.0))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), -TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0))))), -TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), -TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::Foo => Box::new( + ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Foo(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::MyUnionOne => Box::new( + ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), + ), + TypeVariant::MyUnionTwo => Box::new( + ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), + ), + TypeVariant::Foo => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Foo(Box::new(t.0)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), + ), + TypeVariant::MyUnionOne => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0)))), + ), + TypeVariant::MyUnionTwo => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::UnionKey(ref v) => v.as_ref(), -Self::Foo(ref v) => v.as_ref(), -Self::MyUnion(ref v) => v.as_ref(), -Self::MyUnionOne(ref v) => v.as_ref(), -Self::MyUnionTwo(ref v) => v.as_ref(), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::Foo => Box::new( + ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Foo(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::MyUnionOne => Box::new( + ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), + ), + TypeVariant::MyUnionTwo => Box::new( + ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), + ), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey(_) => "UnionKey", -Self::Foo(_) => "Foo", -Self::MyUnion(_) => "MyUnion", -Self::MyUnionOne(_) => "MyUnionOne", -Self::MyUnionTwo(_) => "MyUnionTwo", - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::UnionKey(_) => TypeVariant::UnionKey, -Self::Foo(_) => TypeVariant::Foo, -Self::MyUnion(_) => TypeVariant::MyUnion, -Self::MyUnionOne(_) => TypeVariant::MyUnionOne, -Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), + TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::UnionKey(ref v) => v.as_ref(), + Self::Foo(ref v) => v.as_ref(), + Self::MyUnion(ref v) => v.as_ref(), + Self::MyUnionOne(ref v) => v.as_ref(), + Self::MyUnionTwo(ref v) => v.as_ref(), } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey(_) => "UnionKey", + Self::Foo(_) => "Foo", + Self::MyUnion(_) => "MyUnion", + Self::MyUnionOne(_) => "MyUnionOne", + Self::MyUnionTwo(_) => "MyUnionTwo", } + } - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::UnionKey(v) => v.write_xdr(w), -Self::Foo(v) => v.write_xdr(w), -Self::MyUnion(v) => v.write_xdr(w), -Self::MyUnionOne(v) => v.write_xdr(w), -Self::MyUnionTwo(v) => v.write_xdr(w), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::UnionKey(_) => TypeVariant::UnionKey, + Self::Foo(_) => TypeVariant::Foo, + Self::MyUnion(_) => TypeVariant::MyUnion, + Self::MyUnionOne(_) => TypeVariant::MyUnionOne, + Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, } + } +} + +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::UnionKey(v) => v.write_xdr(w), + Self::Foo(v) => v.write_xdr(w), + Self::MyUnion(v) => v.write_xdr(w), + Self::MyUnionOne(v) => v.write_xdr(w), + Self::MyUnionTwo(v) => v.write_xdr(w), + } + } +} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index 3ef88298f..727848396 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/optional.x", "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/optional.x", + "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2711,265 +2744,315 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] pub struct HasOptions { - pub first_option: Option, - pub second_option: Option, - pub third_option: Option, + pub first_option: Option, + pub second_option: Option, + pub third_option: Option, } - impl ReadXdr for HasOptions { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self{ - first_option: Option::::read_xdr(r)?, -second_option: Option::::read_xdr(r)?, -third_option: Option::::read_xdr(r)?, - }) - }) - } - } +impl ReadXdr for HasOptions { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self { + first_option: Option::::read_xdr(r)?, + second_option: Option::::read_xdr(r)?, + third_option: Option::::read_xdr(r)?, + }) + }) + } +} - impl WriteXdr for HasOptions { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.first_option.write_xdr(w)?; -self.second_option.write_xdr(w)?; -self.third_option.write_xdr(w)?; - Ok(()) - }) - } - } +impl WriteXdr for HasOptions { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.first_option.write_xdr(w)?; + self.second_option.write_xdr(w)?; + self.third_option.write_xdr(w)?; + Ok(()) + }) + } +} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - Arr, -HasOptions, - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + Arr, + HasOptions, +} - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, -TypeVariant::HasOptions, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", -"HasOptions", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr => "Arr", -Self::HasOptions => "HasOptions", - } - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; + pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr => "Arr", + Self::HasOptions => "HasOptions", } + } - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } +} - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Arr" => Ok(Self::Arr), -"HasOptions" => Ok(Self::HasOptions), - _ => Err(Error::Invalid), - } - } - } +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - Arr(Box), -HasOptions(Box), +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Arr" => Ok(Self::Arr), + "HasOptions" => Ok(Self::HasOptions), + _ => Err(Error::Invalid), } + } +} - impl Type { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, -TypeVariant::HasOptions, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", -"HasOptions", ]; - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Arr => r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))), -TypeVariant::HasOptions => r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))), - } - } +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + Arr(Box), + HasOptions(Box), +} - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } +impl Type { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; + pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Arr => { + r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::HasOptions => { + r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), -TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t.0))))), -TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), -TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new( + ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Arr(Box::new(t)))), + ), + TypeVariant::HasOptions => Box::new( + ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Arr(Box::new(t.0)))), + ), + TypeVariant::HasOptions => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::HasOptions(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), -TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Arr => Box::new( + ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Arr(Box::new(t)))), + ), + TypeVariant::HasOptions => Box::new( + ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Arr(ref v) => v.as_ref(), -Self::HasOptions(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr(_) => "Arr", -Self::HasOptions(_) => "HasOptions", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), + TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Arr(_) => TypeVariant::Arr, -Self::HasOptions(_) => TypeVariant::HasOptions, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Arr(ref v) => v.as_ref(), + Self::HasOptions(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr(_) => "Arr", + Self::HasOptions(_) => "HasOptions", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Arr(_) => TypeVariant::Arr, + Self::HasOptions(_) => TypeVariant::HasOptions, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Arr(v) => v.write_xdr(w), -Self::HasOptions(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Arr(v) => v.write_xdr(w), + Self::HasOptions(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index 5d9aaaa54..f7e9fd9ba 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/struct.x", "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/struct.x", + "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2713,271 +2746,321 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] pub struct MyStruct { - pub some_int: i32, - pub a_big_int: i64, - pub some_opaque: [u8; 10], - pub some_string: StringM, - pub max_string: StringM::<100>, + pub some_int: i32, + pub a_big_int: i64, + pub some_opaque: [u8; 10], + pub some_string: StringM, + pub max_string: StringM<100>, } - impl ReadXdr for MyStruct { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self{ - some_int: i32::read_xdr(r)?, -a_big_int: i64::read_xdr(r)?, -some_opaque: <[u8; 10]>::read_xdr(r)?, -some_string: StringM::read_xdr(r)?, -max_string: StringM::<100>::read_xdr(r)?, - }) - }) - } - } +impl ReadXdr for MyStruct { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self { + some_int: i32::read_xdr(r)?, + a_big_int: i64::read_xdr(r)?, + some_opaque: <[u8; 10]>::read_xdr(r)?, + some_string: StringM::read_xdr(r)?, + max_string: StringM::<100>::read_xdr(r)?, + }) + }) + } +} - impl WriteXdr for MyStruct { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; -self.a_big_int.write_xdr(w)?; -self.some_opaque.write_xdr(w)?; -self.some_string.write_xdr(w)?; -self.max_string.write_xdr(w)?; - Ok(()) - }) - } - } +impl WriteXdr for MyStruct { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; + self.a_big_int.write_xdr(w)?; + self.some_opaque.write_xdr(w)?; + self.some_string.write_xdr(w)?; + self.max_string.write_xdr(w)?; + Ok(()) + }) + } +} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - Int64, -MyStruct, - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + Int64, + MyStruct, +} - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, -TypeVariant::MyStruct, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", -"MyStruct", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64 => "Int64", -Self::MyStruct => "MyStruct", - } - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; + pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64 => "Int64", + Self::MyStruct => "MyStruct", } + } - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } +} - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Int64" => Ok(Self::Int64), -"MyStruct" => Ok(Self::MyStruct), - _ => Err(Error::Invalid), - } - } - } +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - Int64(Box), -MyStruct(Box), +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Int64" => Ok(Self::Int64), + "MyStruct" => Ok(Self::MyStruct), + _ => Err(Error::Invalid), } + } +} - impl Type { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, -TypeVariant::MyStruct, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", -"MyStruct", ]; - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Int64 => r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))), -TypeVariant::MyStruct => r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))), - } - } +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + Int64(Box), + MyStruct(Box), +} - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } +impl Type { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; + pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Int64 => { + r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::MyStruct => { + r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), -TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t.0))))), -TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), -TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new( + ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Int64(Box::new(t)))), + ), + TypeVariant::MyStruct => Box::new( + ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Int64(Box::new(t.0)))), + ), + TypeVariant::MyStruct => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyStruct(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Int64 => Box::new( + ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Int64(Box::new(t)))), + ), + TypeVariant::MyStruct => Box::new( + ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Int64(ref v) => v.as_ref(), -Self::MyStruct(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64(_) => "Int64", -Self::MyStruct(_) => "MyStruct", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Int64(_) => TypeVariant::Int64, -Self::MyStruct(_) => TypeVariant::MyStruct, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Int64(ref v) => v.as_ref(), + Self::MyStruct(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64(_) => "Int64", + Self::MyStruct(_) => "MyStruct", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Int64(_) => TypeVariant::Int64, + Self::MyStruct(_) => TypeVariant::MyStruct, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Int64(v) => v.write_xdr(w), -Self::MyStruct(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Int64(v) => v.write_xdr(w), + Self::MyStruct(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index 663e7ab6d..6bfd3f85b 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -874,7 +874,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1282,7 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1664,7 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2036,7 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2699,7 +2699,7 @@ mod test { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2816,7 +2816,7 @@ impl AsRef<[u8]> for Uint512 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint513(pub BytesM::<64>); @@ -2918,7 +2918,7 @@ impl AsRef<[u8]> for Uint513 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint514(pub BytesM); @@ -3020,7 +3020,7 @@ impl AsRef<[u8]> for Uint514 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str(pub StringM::<64>); @@ -3122,7 +3122,7 @@ impl AsRef<[u8]> for Str { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str2(pub StringM); @@ -3223,7 +3223,7 @@ impl AsRef<[u8]> for Str2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3339,7 +3339,7 @@ impl AsRef<[u8]> for Hash { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes1(pub [Hash; 12]); @@ -3429,7 +3429,7 @@ impl AsRef<[Hash]> for Hashes1 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes2(pub VecM::); @@ -3531,7 +3531,7 @@ impl AsRef<[Hash]> for Hashes2 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes3(pub VecM::); @@ -3632,7 +3632,7 @@ impl AsRef<[Hash]> for Hashes3 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash1(pub Option); @@ -3684,7 +3684,7 @@ impl WriteXdr for OptHash1 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash2(pub Option); @@ -3869,7 +3869,7 @@ impl WriteXdr for LotsOfMyStructs { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct HasStuff { pub data: LotsOfMyStructs, } @@ -3909,7 +3909,7 @@ impl WriteXdr for HasStuff { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { Red = 0, @@ -4033,7 +4033,7 @@ pub const BAR: u64 = FOO; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum NesterNestedEnum { 1 = 0, @@ -4134,7 +4134,7 @@ Self::2 => "2", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct NesterNestedStruct { pub blah: i32, } @@ -4175,7 +4175,7 @@ impl WriteXdr for NesterNestedStruct { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum NesterNestedUnion { Red, @@ -4290,7 +4290,7 @@ impl WriteXdr for NesterNestedUnion { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Nester { pub nested_enum: NesterNestedEnum, pub nested_struct: NesterNestedStruct, @@ -4328,10 +4328,7 @@ self.nested_union.write_xdr(w)?; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum TypeVariant { Uint512, Uint513, @@ -4496,10 +4493,7 @@ Self::NesterNestedUnion => "NesterNestedUnion", serde(rename_all = "snake_case"), serde(untagged), )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum Type { Uint512(Box), Uint513(Box), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index 314534ca0..d242b71ad 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/union.x", "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/union.x", + "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2718,95 +2751,97 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] #[repr(i32)] pub enum UnionKey { - Error = 0, - Multi = 1, + Error = 0, + Multi = 1, } - impl UnionKey { - pub const VARIANTS: [UnionKey; 2] = [ UnionKey::Error, -UnionKey::Multi, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Error", -"Multi", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error => "Error", -Self::Multi => "Multi", - } - } +impl UnionKey { + pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; + pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error => "Error", + Self::Multi => "Multi", } + } - impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } +} - impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } +impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Enum for UnionKey {} +impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Enum for UnionKey {} - impl TryFrom for UnionKey { - type Error = Error; +impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - fn try_from(i: i32) -> Result { - let e = match i { - 0 => UnionKey::Error, -1 => UnionKey::Multi, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl TryFrom for UnionKey { + type Error = Error; - impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => UnionKey::Error, + 1 => UnionKey::Multi, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } +} - impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// MyUnion is an XDR Union defines as: /// @@ -2817,107 +2852,105 @@ Self::Multi => "Multi", /// Error error; /// case MULTI: /// Multi things<>; -/// -/// +/// +/// /// }; /// ``` /// // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - Error(i32), - Multi(VecM::), -} - - impl MyUnion { - pub const VARIANTS: [UnionKey; 2] = [ - UnionKey::Error, -UnionKey::Multi, - ]; - pub const VARIANTS_STR: [&'static str; 2] = [ - "Error", -"Multi", - ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error(_) => "Error", -Self::Multi(_) => "Multi", - } - } + Error(i32), + Multi(VecM), +} - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::Error(_) => UnionKey::Error, -Self::Multi(_) => UnionKey::Multi, - } - } +impl MyUnion { + pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; + pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error(_) => "Error", + Self::Multi(_) => "Multi", } + } - impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::Error(_) => UnionKey::Error, + Self::Multi(_) => UnionKey::Multi, } + } - impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } +} - impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } +impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Union for MyUnion {} +impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } +} - impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::Error => Self::Error(i32::read_xdr(r)?), -UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } - } +impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::Error(v) => v.write_xdr(w)?, -Self::Multi(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } - } +impl Union for MyUnion {} + +impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::Error => Self::Error(i32::read_xdr(r)?), + UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} + +impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::Error(v) => v.write_xdr(w)?, + Self::Multi(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } +} /// IntUnion is an XDR Union defines as: /// @@ -2928,107 +2961,113 @@ Self::Multi(v) => v.write_xdr(w)?, /// Error error; /// case 1: /// Multi things<>; -/// +/// /// }; /// ``` /// // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[allow(clippy::large_enum_variant)] pub enum IntUnion { - V0(i32), - V1(VecM::), -} - - impl IntUnion { - pub const VARIANTS: [i32; 2] = [ - 0, -1, - ]; - pub const VARIANTS_STR: [&'static str; 2] = [ - "V0", -"V1", - ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::V0(_) => "V0", -Self::V1(_) => "V1", - } - } + V0(i32), + V1(VecM), +} - #[must_use] - pub const fn discriminant(&self) -> i32 { - #[allow(clippy::match_same_arms)] - match self { - Self::V0(_) => 0, -Self::V1(_) => 1, - } - } +impl IntUnion { + pub const VARIANTS: [i32; 2] = [0, 1]; + pub const VARIANTS_STR: [&'static str; 2] = ["V0", "V1"]; - #[must_use] - pub const fn variants() -> [i32; 2] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::V0(_) => "V0", + Self::V1(_) => "V1", } + } - impl Name for IntUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn discriminant(&self) -> i32 { + #[allow(clippy::match_same_arms)] + match self { + Self::V0(_) => 0, + Self::V1(_) => 1, } + } - impl Discriminant for IntUnion { - #[must_use] - fn discriminant(&self) -> i32 { - Self::discriminant(self) - } - } + #[must_use] + pub const fn variants() -> [i32; 2] { + Self::VARIANTS + } +} - impl Variants for IntUnion { - fn variants() -> slice::Iter<'static, i32> { - Self::VARIANTS.iter() - } - } +impl Name for IntUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Union for IntUnion {} +impl Discriminant for IntUnion { + #[must_use] + fn discriminant(&self) -> i32 { + Self::discriminant(self) + } +} - impl ReadXdr for IntUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: i32 = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - 0 => Self::V0(i32::read_xdr(r)?), -1 => Self::V1(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } - } +impl Variants for IntUnion { + fn variants() -> slice::Iter<'static, i32> { + Self::VARIANTS.iter() + } +} - impl WriteXdr for IntUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::V0(v) => v.write_xdr(w)?, -Self::V1(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } - } +impl Union for IntUnion {} + +impl ReadXdr for IntUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: i32 = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + 0 => Self::V0(i32::read_xdr(r)?), + 1 => Self::V1(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} + +impl WriteXdr for IntUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::V0(v) => v.write_xdr(w)?, + Self::V1(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } +} /// IntUnion2 is an XDR Typedef defines as: /// @@ -3038,8 +3077,20 @@ Self::V1(v) => v.write_xdr(w)?, /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3078,305 +3129,407 @@ impl ReadXdr for IntUnion2 { impl WriteXdr for IntUnion2 { #[cfg(feature = "std")] fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w|{ self.0.write_xdr(w) }) - } -} - - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - SError, -Multi, -UnionKey, -MyUnion, -IntUnion, -IntUnion2, - } - - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, -TypeVariant::Multi, -TypeVariant::UnionKey, -TypeVariant::MyUnion, -TypeVariant::IntUnion, -TypeVariant::IntUnion2, ]; - pub const VARIANTS_STR: [&'static str; 6] = [ "SError", -"Multi", -"UnionKey", -"MyUnion", -"IntUnion", -"IntUnion2", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError => "SError", -Self::Multi => "Multi", -Self::UnionKey => "UnionKey", -Self::MyUnion => "MyUnion", -Self::IntUnion => "IntUnion", -Self::IntUnion2 => "IntUnion2", - } - } + w.with_limited_depth(|w| self.0.write_xdr(w)) + } +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + SError, + Multi, + UnionKey, + MyUnion, + IntUnion, + IntUnion2, +} + +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 6] = [ + TypeVariant::SError, + TypeVariant::Multi, + TypeVariant::UnionKey, + TypeVariant::MyUnion, + TypeVariant::IntUnion, + TypeVariant::IntUnion2, + ]; + pub const VARIANTS_STR: [&'static str; 6] = [ + "SError", + "Multi", + "UnionKey", + "MyUnion", + "IntUnion", + "IntUnion2", + ]; - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError => "SError", + Self::Multi => "Multi", + Self::UnionKey => "UnionKey", + Self::MyUnion => "MyUnion", + Self::IntUnion => "IntUnion", + Self::IntUnion2 => "IntUnion2", } + } - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "SError" => Ok(Self::SError), -"Multi" => Ok(Self::Multi), -"UnionKey" => Ok(Self::UnionKey), -"MyUnion" => Ok(Self::MyUnion), -"IntUnion" => Ok(Self::IntUnion), -"IntUnion2" => Ok(Self::IntUnion2), - _ => Err(Error::Invalid), - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "SError" => Ok(Self::SError), + "Multi" => Ok(Self::Multi), + "UnionKey" => Ok(Self::UnionKey), + "MyUnion" => Ok(Self::MyUnion), + "IntUnion" => Ok(Self::IntUnion), + "IntUnion2" => Ok(Self::IntUnion2), + _ => Err(Error::Invalid), } + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - SError(Box), -Multi(Box), -UnionKey(Box), -MyUnion(Box), -IntUnion(Box), -IntUnion2(Box), - } - - impl Type { - pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, -TypeVariant::Multi, -TypeVariant::UnionKey, -TypeVariant::MyUnion, -TypeVariant::IntUnion, -TypeVariant::IntUnion2, ]; - pub const VARIANTS_STR: [&'static str; 6] = [ "SError", -"Multi", -"UnionKey", -"MyUnion", -"IntUnion", -"IntUnion2", ]; +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + SError(Box), + Multi(Box), + UnionKey(Box), + MyUnion(Box), + IntUnion(Box), + IntUnion2(Box), +} + +impl Type { + pub const VARIANTS: [TypeVariant; 6] = [ + TypeVariant::SError, + TypeVariant::Multi, + TypeVariant::UnionKey, + TypeVariant::MyUnion, + TypeVariant::IntUnion, + TypeVariant::IntUnion2, + ]; + pub const VARIANTS_STR: [&'static str; 6] = [ + "SError", + "Multi", + "UnionKey", + "MyUnion", + "IntUnion", + "IntUnion2", + ]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::SError => r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))), -TypeVariant::Multi => r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))), -TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), -TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), -TypeVariant::IntUnion => r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))), -TypeVariant::IntUnion2 => r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))), - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::SError => { + r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) + TypeVariant::Multi => { + r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + TypeVariant::UnionKey => { + r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::MyUnion => { + r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), -TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), -TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), -TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), - } + TypeVariant::IntUnion => { + r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t.0))))), -TypeVariant::Multi => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t.0))))), -TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), -TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t.0))))), -TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0))))), - } + TypeVariant::IntUnion2 => { + r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))) } + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), -TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), -TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), -TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), -TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), -TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), -TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new( + ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::SError(Box::new(t)))), + ), + TypeVariant::Multi => Box::new( + ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Multi(Box::new(t)))), + ), + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::IntUnion => Box::new( + ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), + ), + TypeVariant::IntUnion2 => Box::new( + ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::SError(ref v) => v.as_ref(), -Self::Multi(ref v) => v.as_ref(), -Self::UnionKey(ref v) => v.as_ref(), -Self::MyUnion(ref v) => v.as_ref(), -Self::IntUnion(ref v) => v.as_ref(), -Self::IntUnion2(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::SError(Box::new(t.0)))), + ), + TypeVariant::Multi => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Multi(Box::new(t.0)))), + ), + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), + ), + TypeVariant::IntUnion => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion(Box::new(t.0)))), + ), + TypeVariant::IntUnion2 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0)))), + ), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError(_) => "SError", -Self::Multi(_) => "Multi", -Self::UnionKey(_) => "UnionKey", -Self::MyUnion(_) => "MyUnion", -Self::IntUnion(_) => "IntUnion", -Self::IntUnion2(_) => "IntUnion2", - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::SError => Box::new( + ReadXdrIter::<_, SError>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::SError(Box::new(t)))), + ), + TypeVariant::Multi => Box::new( + ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Multi(Box::new(t)))), + ), + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::IntUnion => Box::new( + ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), + ), + TypeVariant::IntUnion2 => Box::new( + ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), + ), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::SError(_) => TypeVariant::SError, -Self::Multi(_) => TypeVariant::Multi, -Self::UnionKey(_) => TypeVariant::UnionKey, -Self::MyUnion(_) => TypeVariant::MyUnion, -Self::IntUnion(_) => TypeVariant::IntUnion, -Self::IntUnion2(_) => TypeVariant::IntUnion2, - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), + TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), + TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), + TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::SError(ref v) => v.as_ref(), + Self::Multi(ref v) => v.as_ref(), + Self::UnionKey(ref v) => v.as_ref(), + Self::MyUnion(ref v) => v.as_ref(), + Self::IntUnion(ref v) => v.as_ref(), + Self::IntUnion2(ref v) => v.as_ref(), } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError(_) => "SError", + Self::Multi(_) => "Multi", + Self::UnionKey(_) => "UnionKey", + Self::MyUnion(_) => "MyUnion", + Self::IntUnion(_) => "IntUnion", + Self::IntUnion2(_) => "IntUnion2", } + } - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::SError(v) => v.write_xdr(w), -Self::Multi(v) => v.write_xdr(w), -Self::UnionKey(v) => v.write_xdr(w), -Self::MyUnion(v) => v.write_xdr(w), -Self::IntUnion(v) => v.write_xdr(w), -Self::IntUnion2(v) => v.write_xdr(w), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::SError(_) => TypeVariant::SError, + Self::Multi(_) => TypeVariant::Multi, + Self::UnionKey(_) => TypeVariant::UnionKey, + Self::MyUnion(_) => TypeVariant::MyUnion, + Self::IntUnion(_) => TypeVariant::IntUnion, + Self::IntUnion2(_) => TypeVariant::IntUnion2, } + } +} + +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::SError(v) => v.write_xdr(w), + Self::Multi(v) => v.write_xdr(w), + Self::UnionKey(v) => v.write_xdr(w), + Self::MyUnion(v) => v.write_xdr(w), + Self::IntUnion(v) => v.write_xdr(w), + Self::IntUnion2(v) => v.write_xdr(w), + } + } +} diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index c4a26e2ad..66aaeab58 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/block_comments.x", "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/block_comments.x", + "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2702,16 +2735,28 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum AccountFlags { - AuthRequiredFlag = 1, + AuthRequiredFlag = 1, } impl AccountFlags { - pub const VARIANTS: [AccountFlags; 1] = [ AccountFlags::AuthRequiredFlag, ]; - pub const VARIANTS_STR: [&'static str; 1] = [ "AuthRequiredFlag", ]; + pub const VARIANTS: [AccountFlags; 1] = [AccountFlags::AuthRequiredFlag]; + pub const VARIANTS_STR: [&'static str; 1] = ["AuthRequiredFlag"]; #[must_use] pub const fn name(&self) -> &'static str { @@ -2790,21 +2835,26 @@ impl WriteXdr for AccountFlags { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") )] #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) )] pub enum TypeVariant { AccountFlags, } impl TypeVariant { - pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; - pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; + pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; + pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; #[must_use] #[allow(clippy::too_many_lines)] @@ -2847,34 +2897,44 @@ impl core::str::FromStr for TypeVariant { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) )] #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) )] pub enum Type { AccountFlags(Box), } impl Type { - pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; - pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; + pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; + pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { match v { - TypeVariant::AccountFlags => r.with_limited_depth(|r| Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?)))), + TypeVariant::AccountFlags => r.with_limited_depth(|r| { + Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?))) + }), } } #[cfg(feature = "base64")] pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); let t = Self::read_xdr(v, &mut dec)?; Ok(t) } @@ -2893,33 +2953,54 @@ impl Type { #[cfg(feature = "base64")] pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), + TypeVariant::AccountFlags => Box::new( + ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), + ), } } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0))))), + TypeVariant::AccountFlags => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0)))), + ), } } #[cfg(feature = "base64")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); match v { - TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), + TypeVariant::AccountFlags => Box::new( + ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), + ), } } @@ -2933,7 +3014,10 @@ impl Type { #[cfg(feature = "base64")] pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } @@ -2942,7 +3026,9 @@ impl Type { #[allow(clippy::too_many_lines)] pub fn read_json(v: TypeVariant, r: impl Read) -> Result { match v { - TypeVariant::AccountFlags => Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))), + TypeVariant::AccountFlags => { + Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))) + } } } diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index e825a26e0..b3a737966 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/const.x", "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/const.x", + "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2712,235 +2745,281 @@ pub type TestArray = [i32; Foo]; /// typedef int TestArray2; /// ``` /// -pub type TestArray2 = VecM::; - - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - TestArray, -TestArray2, - } +pub type TestArray2 = VecM; - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, -TypeVariant::TestArray2, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", -"TestArray2", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray => "TestArray", -Self::TestArray2 => "TestArray2", - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + TestArray, + TestArray2, +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; + pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray => "TestArray", + Self::TestArray2 => "TestArray2", } + } - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "TestArray" => Ok(Self::TestArray), -"TestArray2" => Ok(Self::TestArray2), - _ => Err(Error::Invalid), - } - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - TestArray(Box), -TestArray2(Box), - } +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} - impl Type { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, -TypeVariant::TestArray2, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", -"TestArray2", ]; +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "TestArray" => Ok(Self::TestArray), + "TestArray2" => Ok(Self::TestArray2), + _ => Err(Error::Invalid), + } + } +} - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::TestArray => r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))), -TypeVariant::TestArray2 => r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))), - } - } +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + TestArray(Box), + TestArray2(Box), +} - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } +impl Type { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; + pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::TestArray => { + r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::TestArray2 => { + r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), -TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t.0))))), -TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), -TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new( + ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), + ), + TypeVariant::TestArray2 => Box::new( + ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray(Box::new(t.0)))), + ), + TypeVariant::TestArray2 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray2(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), -TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::TestArray => Box::new( + ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), + ), + TypeVariant::TestArray2 => Box::new( + ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::TestArray(ref v) => v.as_ref(), -Self::TestArray2(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray(_) => "TestArray", -Self::TestArray2(_) => "TestArray2", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), + TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::TestArray(_) => TypeVariant::TestArray, -Self::TestArray2(_) => TypeVariant::TestArray2, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::TestArray(ref v) => v.as_ref(), + Self::TestArray2(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray(_) => "TestArray", + Self::TestArray2(_) => "TestArray2", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::TestArray(_) => TypeVariant::TestArray, + Self::TestArray2(_) => TypeVariant::TestArray2, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::TestArray(v) => v.write_xdr(w), -Self::TestArray2(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::TestArray(v) => v.write_xdr(w), + Self::TestArray2(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index 9ccf36a9d..c5fa0ec22 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/enum.x", "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/enum.x", + "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2698,19 +2731,19 @@ mod test { /// ERROR_MSG, /// HELLO, /// DONT_HAVE, -/// +/// /// GET_PEERS, // gets a list of peers this guy knows about /// PEERS, -/// +/// /// GET_TX_SET, // gets a particular txset by hash /// TX_SET, -/// +/// /// GET_VALIDATIONS, // gets validations for a given ledger hash /// VALIDATIONS, -/// +/// /// TRANSACTION, //pass on a tx you have heard about /// JSON_TRANSACTION, -/// +/// /// // FBA /// GET_FBA_QUORUMSET, /// FBA_QUORUMSET, @@ -2721,156 +2754,172 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum MessageType { - ErrorMsg = 0, - Hello = 1, - DontHave = 2, - GetPeers = 3, - Peers = 4, - GetTxSet = 5, - TxSet = 6, - GetValidations = 7, - Validations = 8, - Transaction = 9, - JsonTransaction = 10, - GetFbaQuorumset = 11, - FbaQuorumset = 12, - FbaMessage = 13, -} - - impl MessageType { - pub const VARIANTS: [MessageType; 14] = [ MessageType::ErrorMsg, -MessageType::Hello, -MessageType::DontHave, -MessageType::GetPeers, -MessageType::Peers, -MessageType::GetTxSet, -MessageType::TxSet, -MessageType::GetValidations, -MessageType::Validations, -MessageType::Transaction, -MessageType::JsonTransaction, -MessageType::GetFbaQuorumset, -MessageType::FbaQuorumset, -MessageType::FbaMessage, ]; - pub const VARIANTS_STR: [&'static str; 14] = [ "ErrorMsg", -"Hello", -"DontHave", -"GetPeers", -"Peers", -"GetTxSet", -"TxSet", -"GetValidations", -"Validations", -"Transaction", -"JsonTransaction", -"GetFbaQuorumset", -"FbaQuorumset", -"FbaMessage", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::ErrorMsg => "ErrorMsg", -Self::Hello => "Hello", -Self::DontHave => "DontHave", -Self::GetPeers => "GetPeers", -Self::Peers => "Peers", -Self::GetTxSet => "GetTxSet", -Self::TxSet => "TxSet", -Self::GetValidations => "GetValidations", -Self::Validations => "Validations", -Self::Transaction => "Transaction", -Self::JsonTransaction => "JsonTransaction", -Self::GetFbaQuorumset => "GetFbaQuorumset", -Self::FbaQuorumset => "FbaQuorumset", -Self::FbaMessage => "FbaMessage", - } - } + ErrorMsg = 0, + Hello = 1, + DontHave = 2, + GetPeers = 3, + Peers = 4, + GetTxSet = 5, + TxSet = 6, + GetValidations = 7, + Validations = 8, + Transaction = 9, + JsonTransaction = 10, + GetFbaQuorumset = 11, + FbaQuorumset = 12, + FbaMessage = 13, +} + +impl MessageType { + pub const VARIANTS: [MessageType; 14] = [ + MessageType::ErrorMsg, + MessageType::Hello, + MessageType::DontHave, + MessageType::GetPeers, + MessageType::Peers, + MessageType::GetTxSet, + MessageType::TxSet, + MessageType::GetValidations, + MessageType::Validations, + MessageType::Transaction, + MessageType::JsonTransaction, + MessageType::GetFbaQuorumset, + MessageType::FbaQuorumset, + MessageType::FbaMessage, + ]; + pub const VARIANTS_STR: [&'static str; 14] = [ + "ErrorMsg", + "Hello", + "DontHave", + "GetPeers", + "Peers", + "GetTxSet", + "TxSet", + "GetValidations", + "Validations", + "Transaction", + "JsonTransaction", + "GetFbaQuorumset", + "FbaQuorumset", + "FbaMessage", + ]; - #[must_use] - pub const fn variants() -> [MessageType; 14] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::ErrorMsg => "ErrorMsg", + Self::Hello => "Hello", + Self::DontHave => "DontHave", + Self::GetPeers => "GetPeers", + Self::Peers => "Peers", + Self::GetTxSet => "GetTxSet", + Self::TxSet => "TxSet", + Self::GetValidations => "GetValidations", + Self::Validations => "Validations", + Self::Transaction => "Transaction", + Self::JsonTransaction => "JsonTransaction", + Self::GetFbaQuorumset => "GetFbaQuorumset", + Self::FbaQuorumset => "FbaQuorumset", + Self::FbaMessage => "FbaMessage", } + } - impl Name for MessageType { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + pub const fn variants() -> [MessageType; 14] { + Self::VARIANTS + } +} - impl Variants for MessageType { - fn variants() -> slice::Iter<'static, MessageType> { - Self::VARIANTS.iter() - } - } +impl Name for MessageType { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Enum for MessageType {} +impl Variants for MessageType { + fn variants() -> slice::Iter<'static, MessageType> { + Self::VARIANTS.iter() + } +} - impl fmt::Display for MessageType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Enum for MessageType {} - impl TryFrom for MessageType { - type Error = Error; - - fn try_from(i: i32) -> Result { - let e = match i { - 0 => MessageType::ErrorMsg, -1 => MessageType::Hello, -2 => MessageType::DontHave, -3 => MessageType::GetPeers, -4 => MessageType::Peers, -5 => MessageType::GetTxSet, -6 => MessageType::TxSet, -7 => MessageType::GetValidations, -8 => MessageType::Validations, -9 => MessageType::Transaction, -10 => MessageType::JsonTransaction, -11 => MessageType::GetFbaQuorumset, -12 => MessageType::FbaQuorumset, -13 => MessageType::FbaMessage, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for MessageType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: MessageType) -> Self { - e as Self - } - } +impl TryFrom for MessageType { + type Error = Error; - impl ReadXdr for MessageType { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => MessageType::ErrorMsg, + 1 => MessageType::Hello, + 2 => MessageType::DontHave, + 3 => MessageType::GetPeers, + 4 => MessageType::Peers, + 5 => MessageType::GetTxSet, + 6 => MessageType::TxSet, + 7 => MessageType::GetValidations, + 8 => MessageType::Validations, + 9 => MessageType::Transaction, + 10 => MessageType::JsonTransaction, + 11 => MessageType::GetFbaQuorumset, + 12 => MessageType::FbaQuorumset, + 13 => MessageType::FbaMessage, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for MessageType { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: MessageType) -> Self { + e as Self + } +} + +impl ReadXdr for MessageType { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for MessageType { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// Color is an XDR Enum defines as: /// @@ -2885,101 +2934,109 @@ Self::FbaMessage => "FbaMessage", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum Color { - Red = 0, - Green = 1, - Blue = 2, -} - - impl Color { - pub const VARIANTS: [Color; 3] = [ Color::Red, -Color::Green, -Color::Blue, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "Red", -"Green", -"Blue", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red => "Red", -Self::Green => "Green", -Self::Blue => "Blue", - } - } + Red = 0, + Green = 1, + Blue = 2, +} - #[must_use] - pub const fn variants() -> [Color; 3] { - Self::VARIANTS - } - } +impl Color { + pub const VARIANTS: [Color; 3] = [Color::Red, Color::Green, Color::Blue]; + pub const VARIANTS_STR: [&'static str; 3] = ["Red", "Green", "Blue"]; - impl Name for Color { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red => "Red", + Self::Green => "Green", + Self::Blue => "Blue", } + } - impl Variants for Color { - fn variants() -> slice::Iter<'static, Color> { - Self::VARIANTS.iter() - } - } + #[must_use] + pub const fn variants() -> [Color; 3] { + Self::VARIANTS + } +} - impl Enum for Color {} +impl Name for Color { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl fmt::Display for Color { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Variants for Color { + fn variants() -> slice::Iter<'static, Color> { + Self::VARIANTS.iter() + } +} - impl TryFrom for Color { - type Error = Error; +impl Enum for Color {} - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color::Red, -1 => Color::Green, -2 => Color::Blue, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for Color { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: Color) -> Self { - e as Self - } - } +impl TryFrom for Color { + type Error = Error; - impl ReadXdr for Color { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color::Red, + 1 => Color::Green, + 2 => Color::Blue, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for Color { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: Color) -> Self { + e as Self + } +} + +impl ReadXdr for Color { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for Color { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// Color2 is an XDR Enum defines as: /// @@ -2994,346 +3051,416 @@ Self::Blue => "Blue", // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum Color2 { - Red2 = 0, - Green2 = 1, - Blue2 = 2, -} - - impl Color2 { - pub const VARIANTS: [Color2; 3] = [ Color2::Red2, -Color2::Green2, -Color2::Blue2, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "Red2", -"Green2", -"Blue2", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red2 => "Red2", -Self::Green2 => "Green2", -Self::Blue2 => "Blue2", - } - } + Red2 = 0, + Green2 = 1, + Blue2 = 2, +} - #[must_use] - pub const fn variants() -> [Color2; 3] { - Self::VARIANTS - } - } +impl Color2 { + pub const VARIANTS: [Color2; 3] = [Color2::Red2, Color2::Green2, Color2::Blue2]; + pub const VARIANTS_STR: [&'static str; 3] = ["Red2", "Green2", "Blue2"]; - impl Name for Color2 { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red2 => "Red2", + Self::Green2 => "Green2", + Self::Blue2 => "Blue2", } + } - impl Variants for Color2 { - fn variants() -> slice::Iter<'static, Color2> { - Self::VARIANTS.iter() - } - } + #[must_use] + pub const fn variants() -> [Color2; 3] { + Self::VARIANTS + } +} - impl Enum for Color2 {} +impl Name for Color2 { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl fmt::Display for Color2 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Variants for Color2 { + fn variants() -> slice::Iter<'static, Color2> { + Self::VARIANTS.iter() + } +} - impl TryFrom for Color2 { - type Error = Error; +impl Enum for Color2 {} - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color2::Red2, -1 => Color2::Green2, -2 => Color2::Blue2, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for Color2 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: Color2) -> Self { - e as Self - } - } +impl TryFrom for Color2 { + type Error = Error; - impl ReadXdr for Color2 { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color2::Red2, + 1 => Color2::Green2, + 2 => Color2::Blue2, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for Color2 { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: Color2) -> Self { + e as Self + } +} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - MessageType, -Color, -Color2, - } - - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, -TypeVariant::Color, -TypeVariant::Color2, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", -"Color", -"Color2", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType => "MessageType", -Self::Color => "Color", -Self::Color2 => "Color2", - } - } +impl ReadXdr for Color2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS - } - } +impl WriteXdr for Color2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + MessageType, + Color, + Color2, +} - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 3] = [ + TypeVariant::MessageType, + TypeVariant::Color, + TypeVariant::Color2, + ]; + pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType => "MessageType", + Self::Color => "Color", + Self::Color2 => "Color2", } + } - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "MessageType" => Ok(Self::MessageType), -"Color" => Ok(Self::Color), -"Color2" => Ok(Self::Color2), - _ => Err(Error::Invalid), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } +} + +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "MessageType" => Ok(Self::MessageType), + "Color" => Ok(Self::Color), + "Color2" => Ok(Self::Color2), + _ => Err(Error::Invalid), } + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - MessageType(Box), -Color(Box), -Color2(Box), - } - - impl Type { - pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, -TypeVariant::Color, -TypeVariant::Color2, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", -"Color", -"Color2", ]; +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + MessageType(Box), + Color(Box), + Color2(Box), +} - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::MessageType => r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))), -TypeVariant::Color => r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))), -TypeVariant::Color2 => r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))), - } - } +impl Type { + pub const VARIANTS: [TypeVariant; 3] = [ + TypeVariant::MessageType, + TypeVariant::Color, + TypeVariant::Color2, + ]; + pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::MessageType => { + r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + TypeVariant::Color => { + r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::Color2 => { + r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), -TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), -TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t.0))))), -TypeVariant::Color => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t.0))))), -TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), -TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), -TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new( + ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), + ), + TypeVariant::Color => Box::new( + ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color(Box::new(t)))), + ), + TypeVariant::Color2 => Box::new( + ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color2(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MessageType(Box::new(t.0)))), + ), + TypeVariant::Color => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color(Box::new(t.0)))), + ), + TypeVariant::Color2 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Color2(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::MessageType => Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::MessageType => Box::new( + ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), + ), + TypeVariant::Color => Box::new( + ReadXdrIter::<_, Color>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Color(Box::new(t)))), + ), + TypeVariant::Color2 => Box::new( + ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Color2(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::MessageType(ref v) => v.as_ref(), -Self::Color(ref v) => v.as_ref(), -Self::Color2(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType(_) => "MessageType", -Self::Color(_) => "Color", -Self::Color2(_) => "Color2", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::MessageType => { + Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))) } + TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), + TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::MessageType(_) => TypeVariant::MessageType, -Self::Color(_) => TypeVariant::Color, -Self::Color2(_) => TypeVariant::Color2, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::MessageType(ref v) => v.as_ref(), + Self::Color(ref v) => v.as_ref(), + Self::Color2(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType(_) => "MessageType", + Self::Color(_) => "Color", + Self::Color2(_) => "Color2", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::MessageType(_) => TypeVariant::MessageType, + Self::Color(_) => TypeVariant::Color, + Self::Color2(_) => TypeVariant::Color2, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::MessageType(v) => v.write_xdr(w), -Self::Color(v) => v.write_xdr(w), -Self::Color2(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::MessageType(v) => v.write_xdr(w), + Self::Color(v) => v.write_xdr(w), + Self::Color2(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 84ee3ac24..31994e1f6 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/nesting.x", "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/nesting.x", + "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2703,101 +2736,108 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum UnionKey { - One = 1, - Two = 2, - Offer = 3, -} - - impl UnionKey { - pub const VARIANTS: [UnionKey; 3] = [ UnionKey::One, -UnionKey::Two, -UnionKey::Offer, ]; - pub const VARIANTS_STR: [&'static str; 3] = [ "One", -"Two", -"Offer", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One => "One", -Self::Two => "Two", -Self::Offer => "Offer", - } - } + One = 1, + Two = 2, + Offer = 3, +} - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } - } +impl UnionKey { + pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; + pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; - impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One => "One", + Self::Two => "Two", + Self::Offer => "Offer", } + } - impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } +} - impl Enum for UnionKey {} +impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl TryFrom for UnionKey { - type Error = Error; +impl Enum for UnionKey {} - fn try_from(i: i32) -> Result { - let e = match i { - 1 => UnionKey::One, -2 => UnionKey::Two, -3 => UnionKey::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } - } +impl TryFrom for UnionKey { + type Error = Error; - impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 1 => UnionKey::One, + 2 => UnionKey::Two, + 3 => UnionKey::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } +} + +impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// Foo is an XDR Typedef defines as: /// @@ -2817,18 +2857,30 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct MyUnionOne { - pub some_int: i32, + pub some_int: i32, } impl ReadXdr for MyUnionOne { #[cfg(feature = "std")] fn read_xdr(r: &mut Limited) -> Result { r.with_limited_depth(|r| { - Ok(Self{ - some_int: i32::read_xdr(r)?, + Ok(Self { + some_int: i32::read_xdr(r)?, }) }) } @@ -2855,35 +2907,47 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct MyUnionTwo { - pub some_int: i32, - pub foo: i32, + pub some_int: i32, + pub foo: i32, } - impl ReadXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self{ - some_int: i32::read_xdr(r)?, -foo: i32::read_xdr(r)?, - }) - }) - } - } +impl ReadXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self { + some_int: i32::read_xdr(r)?, + foo: i32::read_xdr(r)?, + }) + }) + } +} - impl WriteXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; -self.foo.write_xdr(w)?; - Ok(()) - }) - } - } +impl WriteXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; + self.foo.write_xdr(w)?; + Ok(()) + }) + } +} /// MyUnion is an XDR Union defines as: /// @@ -2894,13 +2958,13 @@ self.foo.write_xdr(w)?; /// struct { /// int someInt; /// } one; -/// +/// /// case TWO: /// struct { /// int someInt; /// Foo foo; /// } two; -/// +/// /// case OFFER: /// void; /// }; @@ -2909,386 +2973,470 @@ self.foo.write_xdr(w)?; // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - One(MyUnionOne), - Two(MyUnionTwo), - Offer, -} - - impl MyUnion { - pub const VARIANTS: [UnionKey; 3] = [ - UnionKey::One, -UnionKey::Two, -UnionKey::Offer, - ]; - pub const VARIANTS_STR: [&'static str; 3] = [ - "One", -"Two", -"Offer", - ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One(_) => "One", -Self::Two(_) => "Two", -Self::Offer => "Offer", - } - } + One(MyUnionOne), + Two(MyUnionTwo), + Offer, +} - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::One(_) => UnionKey::One, -Self::Two(_) => UnionKey::Two, -Self::Offer => UnionKey::Offer, - } - } +impl MyUnion { + pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; + pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One(_) => "One", + Self::Two(_) => "Two", + Self::Offer => "Offer", } + } - impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::One(_) => UnionKey::One, + Self::Two(_) => UnionKey::Two, + Self::Offer => UnionKey::Offer, } + } - impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } +} - impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } +impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Union for MyUnion {} +impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } +} - impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), -UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), -UnionKey::Offer => Self::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } - } +impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::One(v) => v.write_xdr(w)?, -Self::Two(v) => v.write_xdr(w)?, -Self::Offer => ().write_xdr(w)?, - }; - Ok(()) - }) - } - } +impl Union for MyUnion {} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - UnionKey, -Foo, -MyUnion, -MyUnionOne, -MyUnionTwo, - } - - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, -TypeVariant::Foo, -TypeVariant::MyUnion, -TypeVariant::MyUnionOne, -TypeVariant::MyUnionTwo, ]; - pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", -"Foo", -"MyUnion", -"MyUnionOne", -"MyUnionTwo", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey => "UnionKey", -Self::Foo => "Foo", -Self::MyUnion => "MyUnion", -Self::MyUnionOne => "MyUnionOne", -Self::MyUnionTwo => "MyUnionTwo", - } - } +impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), + UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), + UnionKey::Offer => Self::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } - } +impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::One(v) => v.write_xdr(w)?, + Self::Two(v) => v.write_xdr(w)?, + Self::Offer => ().write_xdr(w)?, + }; + Ok(()) + }) + } +} - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + UnionKey, + Foo, + MyUnion, + MyUnionOne, + MyUnionTwo, +} + +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 5] = [ + TypeVariant::UnionKey, + TypeVariant::Foo, + TypeVariant::MyUnion, + TypeVariant::MyUnionOne, + TypeVariant::MyUnionTwo, + ]; + pub const VARIANTS_STR: [&'static str; 5] = + ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey => "UnionKey", + Self::Foo => "Foo", + Self::MyUnion => "MyUnion", + Self::MyUnionOne => "MyUnionOne", + Self::MyUnionTwo => "MyUnionTwo", } + } - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "UnionKey" => Ok(Self::UnionKey), -"Foo" => Ok(Self::Foo), -"MyUnion" => Ok(Self::MyUnion), -"MyUnionOne" => Ok(Self::MyUnionOne), -"MyUnionTwo" => Ok(Self::MyUnionTwo), - _ => Err(Error::Invalid), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } +} + +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "UnionKey" => Ok(Self::UnionKey), + "Foo" => Ok(Self::Foo), + "MyUnion" => Ok(Self::MyUnion), + "MyUnionOne" => Ok(Self::MyUnionOne), + "MyUnionTwo" => Ok(Self::MyUnionTwo), + _ => Err(Error::Invalid), } + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - UnionKey(Box), -Foo(Box), -MyUnion(Box), -MyUnionOne(Box), -MyUnionTwo(Box), - } - - impl Type { - pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, -TypeVariant::Foo, -TypeVariant::MyUnion, -TypeVariant::MyUnionOne, -TypeVariant::MyUnionTwo, ]; - pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", -"Foo", -"MyUnion", -"MyUnionOne", -"MyUnionTwo", ]; +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + UnionKey(Box), + Foo(Box), + MyUnion(Box), + MyUnionOne(Box), + MyUnionTwo(Box), +} + +impl Type { + pub const VARIANTS: [TypeVariant; 5] = [ + TypeVariant::UnionKey, + TypeVariant::Foo, + TypeVariant::MyUnion, + TypeVariant::MyUnionOne, + TypeVariant::MyUnionTwo, + ]; + pub const VARIANTS_STR: [&'static str; 5] = + ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), -TypeVariant::Foo => r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))), -TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), -TypeVariant::MyUnionOne => r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))), -TypeVariant::MyUnionTwo => r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))), - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::UnionKey => { + r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) + TypeVariant::Foo => { + r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + TypeVariant::MyUnion => { + r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::MyUnionOne => { + r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), -TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), - } + TypeVariant::MyUnionTwo => { + r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), -TypeVariant::Foo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t.0))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), -TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0))))), -TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), -TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::Foo => Box::new( + ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Foo(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::MyUnionOne => Box::new( + ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), + ), + TypeVariant::MyUnionTwo => Box::new( + ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), + ), + TypeVariant::Foo => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Foo(Box::new(t.0)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), + ), + TypeVariant::MyUnionOne => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0)))), + ), + TypeVariant::MyUnionTwo => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::UnionKey(ref v) => v.as_ref(), -Self::Foo(ref v) => v.as_ref(), -Self::MyUnion(ref v) => v.as_ref(), -Self::MyUnionOne(ref v) => v.as_ref(), -Self::MyUnionTwo(ref v) => v.as_ref(), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::Foo => Box::new( + ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Foo(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::MyUnionOne => Box::new( + ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), + ), + TypeVariant::MyUnionTwo => Box::new( + ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), + ), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey(_) => "UnionKey", -Self::Foo(_) => "Foo", -Self::MyUnion(_) => "MyUnion", -Self::MyUnionOne(_) => "MyUnionOne", -Self::MyUnionTwo(_) => "MyUnionTwo", - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::UnionKey(_) => TypeVariant::UnionKey, -Self::Foo(_) => TypeVariant::Foo, -Self::MyUnion(_) => TypeVariant::MyUnion, -Self::MyUnionOne(_) => TypeVariant::MyUnionOne, -Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), + TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::UnionKey(ref v) => v.as_ref(), + Self::Foo(ref v) => v.as_ref(), + Self::MyUnion(ref v) => v.as_ref(), + Self::MyUnionOne(ref v) => v.as_ref(), + Self::MyUnionTwo(ref v) => v.as_ref(), } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey(_) => "UnionKey", + Self::Foo(_) => "Foo", + Self::MyUnion(_) => "MyUnion", + Self::MyUnionOne(_) => "MyUnionOne", + Self::MyUnionTwo(_) => "MyUnionTwo", } + } - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::UnionKey(v) => v.write_xdr(w), -Self::Foo(v) => v.write_xdr(w), -Self::MyUnion(v) => v.write_xdr(w), -Self::MyUnionOne(v) => v.write_xdr(w), -Self::MyUnionTwo(v) => v.write_xdr(w), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::UnionKey(_) => TypeVariant::UnionKey, + Self::Foo(_) => TypeVariant::Foo, + Self::MyUnion(_) => TypeVariant::MyUnion, + Self::MyUnionOne(_) => TypeVariant::MyUnionOne, + Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, } + } +} + +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::UnionKey(v) => v.write_xdr(w), + Self::Foo(v) => v.write_xdr(w), + Self::MyUnion(v) => v.write_xdr(w), + Self::MyUnionOne(v) => v.write_xdr(w), + Self::MyUnionTwo(v) => v.write_xdr(w), + } + } +} diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index 2107c2e68..0e2739141 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/optional.x", "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/optional.x", + "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2711,266 +2744,323 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct HasOptions { - pub first_option: Option, - pub second_option: Option, - pub third_option: Option, + pub first_option: Option, + pub second_option: Option, + pub third_option: Option, } - impl ReadXdr for HasOptions { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self{ - first_option: Option::::read_xdr(r)?, -second_option: Option::::read_xdr(r)?, -third_option: Option::::read_xdr(r)?, - }) - }) - } - } +impl ReadXdr for HasOptions { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self { + first_option: Option::::read_xdr(r)?, + second_option: Option::::read_xdr(r)?, + third_option: Option::::read_xdr(r)?, + }) + }) + } +} - impl WriteXdr for HasOptions { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.first_option.write_xdr(w)?; -self.second_option.write_xdr(w)?; -self.third_option.write_xdr(w)?; - Ok(()) - }) - } - } +impl WriteXdr for HasOptions { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.first_option.write_xdr(w)?; + self.second_option.write_xdr(w)?; + self.third_option.write_xdr(w)?; + Ok(()) + }) + } +} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - Arr, -HasOptions, - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + Arr, + HasOptions, +} - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, -TypeVariant::HasOptions, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", -"HasOptions", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr => "Arr", -Self::HasOptions => "HasOptions", - } - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; + pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr => "Arr", + Self::HasOptions => "HasOptions", } + } - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } +} - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Arr" => Ok(Self::Arr), -"HasOptions" => Ok(Self::HasOptions), - _ => Err(Error::Invalid), - } - } - } +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - Arr(Box), -HasOptions(Box), +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Arr" => Ok(Self::Arr), + "HasOptions" => Ok(Self::HasOptions), + _ => Err(Error::Invalid), } + } +} - impl Type { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, -TypeVariant::HasOptions, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", -"HasOptions", ]; - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Arr => r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))), -TypeVariant::HasOptions => r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))), - } - } +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + Arr(Box), + HasOptions(Box), +} - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } +impl Type { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; + pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Arr => { + r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::HasOptions => { + r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), -TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t.0))))), -TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), -TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new( + ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Arr(Box::new(t)))), + ), + TypeVariant::HasOptions => Box::new( + ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Arr(Box::new(t.0)))), + ), + TypeVariant::HasOptions => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::HasOptions(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), -TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Arr => Box::new( + ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Arr(Box::new(t)))), + ), + TypeVariant::HasOptions => Box::new( + ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Arr(ref v) => v.as_ref(), -Self::HasOptions(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr(_) => "Arr", -Self::HasOptions(_) => "HasOptions", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), + TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Arr(_) => TypeVariant::Arr, -Self::HasOptions(_) => TypeVariant::HasOptions, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Arr(ref v) => v.as_ref(), + Self::HasOptions(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr(_) => "Arr", + Self::HasOptions(_) => "HasOptions", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Arr(_) => TypeVariant::Arr, + Self::HasOptions(_) => TypeVariant::HasOptions, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Arr(v) => v.write_xdr(w), -Self::HasOptions(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Arr(v) => v.write_xdr(w), + Self::HasOptions(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index 6d25b0678..a6fb8906a 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/struct.x", "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/struct.x", + "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2713,272 +2746,329 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct MyStruct { - pub some_int: i32, - pub a_big_int: i64, - pub some_opaque: [u8; 10], - pub some_string: StringM, - pub max_string: StringM::<100>, + pub some_int: i32, + pub a_big_int: i64, + pub some_opaque: [u8; 10], + pub some_string: StringM, + pub max_string: StringM<100>, } - impl ReadXdr for MyStruct { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self{ - some_int: i32::read_xdr(r)?, -a_big_int: i64::read_xdr(r)?, -some_opaque: <[u8; 10]>::read_xdr(r)?, -some_string: StringM::read_xdr(r)?, -max_string: StringM::<100>::read_xdr(r)?, - }) - }) - } - } +impl ReadXdr for MyStruct { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self { + some_int: i32::read_xdr(r)?, + a_big_int: i64::read_xdr(r)?, + some_opaque: <[u8; 10]>::read_xdr(r)?, + some_string: StringM::read_xdr(r)?, + max_string: StringM::<100>::read_xdr(r)?, + }) + }) + } +} - impl WriteXdr for MyStruct { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; -self.a_big_int.write_xdr(w)?; -self.some_opaque.write_xdr(w)?; -self.some_string.write_xdr(w)?; -self.max_string.write_xdr(w)?; - Ok(()) - }) - } - } +impl WriteXdr for MyStruct { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; + self.a_big_int.write_xdr(w)?; + self.some_opaque.write_xdr(w)?; + self.some_string.write_xdr(w)?; + self.max_string.write_xdr(w)?; + Ok(()) + }) + } +} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - Int64, -MyStruct, - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + Int64, + MyStruct, +} - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, -TypeVariant::MyStruct, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", -"MyStruct", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64 => "Int64", -Self::MyStruct => "MyStruct", - } - } +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; + pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64 => "Int64", + Self::MyStruct => "MyStruct", } + } - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } +} - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Int64" => Ok(Self::Int64), -"MyStruct" => Ok(Self::MyStruct), - _ => Err(Error::Invalid), - } - } - } +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - Int64(Box), -MyStruct(Box), +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Int64" => Ok(Self::Int64), + "MyStruct" => Ok(Self::MyStruct), + _ => Err(Error::Invalid), } + } +} - impl Type { - pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, -TypeVariant::MyStruct, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", -"MyStruct", ]; - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Int64 => r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))), -TypeVariant::MyStruct => r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))), - } - } +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + Int64(Box), + MyStruct(Box), +} - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } +impl Type { + pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; + pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Int64 => { + r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::MyStruct => { + r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))) } + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), -TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t.0))))), -TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t.0))))), - } - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), -TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new( + ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Int64(Box::new(t)))), + ), + TypeVariant::MyStruct => Box::new( + ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), + ), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Int64(Box::new(t.0)))), + ), + TypeVariant::MyStruct => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyStruct(Box::new(t.0)))), + ), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Int64 => Box::new( + ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Int64(Box::new(t)))), + ), + TypeVariant::MyStruct => Box::new( + ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Int64(ref v) => v.as_ref(), -Self::MyStruct(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64(_) => "Int64", -Self::MyStruct(_) => "MyStruct", - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Int64(_) => TypeVariant::Int64, -Self::MyStruct(_) => TypeVariant::MyStruct, - } - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Int64(ref v) => v.as_ref(), + Self::MyStruct(ref v) => v.as_ref(), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64(_) => "Int64", + Self::MyStruct(_) => "MyStruct", } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Int64(_) => TypeVariant::Int64, + Self::MyStruct(_) => TypeVariant::MyStruct, } + } +} - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Int64(v) => v.write_xdr(w), -Self::MyStruct(v) => v.write_xdr(w), - } - } +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Int64(v) => v.write_xdr(w), + Self::MyStruct(v) => v.write_xdr(w), } + } +} diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index 711dfcb3a..2036ac271 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -874,7 +874,7 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1282,7 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1664,7 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2036,7 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; @@ -2699,7 +2699,7 @@ mod test { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2816,7 +2816,7 @@ impl AsRef<[u8]> for Uint512 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint513(pub BytesM::<64>); @@ -2918,7 +2918,7 @@ impl AsRef<[u8]> for Uint513 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Uint514(pub BytesM); @@ -3020,7 +3020,7 @@ impl AsRef<[u8]> for Uint514 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str(pub StringM::<64>); @@ -3122,7 +3122,7 @@ impl AsRef<[u8]> for Str { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Str2(pub StringM); @@ -3223,7 +3223,7 @@ impl AsRef<[u8]> for Str2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3339,7 +3339,7 @@ impl AsRef<[u8]> for Hash { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes1(pub [Hash; 12]); @@ -3429,7 +3429,7 @@ impl AsRef<[Hash]> for Hashes1 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes2(pub VecM::); @@ -3531,7 +3531,7 @@ impl AsRef<[Hash]> for Hashes2 { #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[derive(Default)] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct Hashes3(pub VecM::); @@ -3632,7 +3632,7 @@ impl AsRef<[Hash]> for Hashes3 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash1(pub Option); @@ -3684,7 +3684,7 @@ impl WriteXdr for OptHash1 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct OptHash2(pub Option); @@ -3777,7 +3777,7 @@ pub type Int4 = u64; #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyStruct { pub field1: Uint512, pub field2: OptHash1, @@ -3833,7 +3833,7 @@ self.field7.write_xdr(w)?; #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct LotsOfMyStructs { pub members: VecM::, } @@ -3871,7 +3871,7 @@ impl WriteXdr for LotsOfMyStructs { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct HasStuff { pub data: LotsOfMyStructs, } @@ -3911,7 +3911,7 @@ impl WriteXdr for HasStuff { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { Red = 0, @@ -4035,7 +4035,7 @@ pub const BAR: u64 = FOO; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum NesterNestedEnum { 1 = 0, @@ -4136,7 +4136,7 @@ Self::2 => "2", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct NesterNestedStruct { pub blah: i32, } @@ -4177,7 +4177,7 @@ impl WriteXdr for NesterNestedStruct { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum NesterNestedUnion { Red, @@ -4292,7 +4292,7 @@ impl WriteXdr for NesterNestedUnion { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Nester { pub nested_enum: NesterNestedEnum, pub nested_struct: NesterNestedStruct, @@ -4330,10 +4330,7 @@ self.nested_union.write_xdr(w)?; derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), serde(rename_all = "snake_case") )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum TypeVariant { Uint512, Uint513, @@ -4498,10 +4495,7 @@ Self::NesterNestedUnion => "NesterNestedUnion", serde(rename_all = "snake_case"), serde(untagged), )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum Type { Uint512(Box), Uint513(Box), diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index 6730c5c47..0a72f6a15 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -4,9 +4,10 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ - ("spec/fixtures/generator/union.x", "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41") -]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( + "spec/fixtures/generator/union.x", + "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41", +)]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -874,7 +875,15 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -1282,7 +1291,15 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1664,7 +1681,15 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -2036,7 +2061,15 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] pub struct Frame(pub T) where T: ReadXdr; @@ -2718,96 +2751,105 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[repr(i32)] pub enum UnionKey { - Error = 0, - Multi = 1, + Error = 0, + Multi = 1, } - impl UnionKey { - pub const VARIANTS: [UnionKey; 2] = [ UnionKey::Error, -UnionKey::Multi, ]; - pub const VARIANTS_STR: [&'static str; 2] = [ "Error", -"Multi", ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error => "Error", -Self::Multi => "Multi", - } - } +impl UnionKey { + pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; + pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error => "Error", + Self::Multi => "Multi", } + } - impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } +} - impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } +impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Enum for UnionKey {} +impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } - } +impl Enum for UnionKey {} - impl TryFrom for UnionKey { - type Error = Error; +impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } +} - fn try_from(i: i32) -> Result { - let e = match i { - 0 => UnionKey::Error, -1 => UnionKey::Multi, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } - } +impl TryFrom for UnionKey { + type Error = Error; - impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } - } + fn try_from(i: i32) -> Result { + let e = match i { + 0 => UnionKey::Error, + 1 => UnionKey::Multi, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } +} - impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } - } +impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } +} - impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } - } +impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } +} + +impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } +} /// MyUnion is an XDR Union defines as: /// @@ -2818,108 +2860,113 @@ Self::Multi => "Multi", /// Error error; /// case MULTI: /// Multi things<>; -/// -/// +/// +/// /// }; /// ``` /// // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - Error(i32), - Multi(VecM::), -} - - impl MyUnion { - pub const VARIANTS: [UnionKey; 2] = [ - UnionKey::Error, -UnionKey::Multi, - ]; - pub const VARIANTS_STR: [&'static str; 2] = [ - "Error", -"Multi", - ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error(_) => "Error", -Self::Multi(_) => "Multi", - } - } + Error(i32), + Multi(VecM), +} - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::Error(_) => UnionKey::Error, -Self::Multi(_) => UnionKey::Multi, - } - } +impl MyUnion { + pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; + pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error(_) => "Error", + Self::Multi(_) => "Multi", } + } - impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::Error(_) => UnionKey::Error, + Self::Multi(_) => UnionKey::Multi, } + } - impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } - } + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } +} - impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } - } +impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Union for MyUnion {} +impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } +} - impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::Error => Self::Error(i32::read_xdr(r)?), -UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } - } +impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } +} - impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::Error(v) => v.write_xdr(w)?, -Self::Multi(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } - } +impl Union for MyUnion {} + +impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::Error => Self::Error(i32::read_xdr(r)?), + UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} + +impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::Error(v) => v.write_xdr(w)?, + Self::Multi(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } +} /// IntUnion is an XDR Union defines as: /// @@ -2930,107 +2977,113 @@ Self::Multi(v) => v.write_xdr(w)?, /// Error error; /// case 1: /// Multi things<>; -/// +/// /// }; /// ``` /// // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[allow(clippy::large_enum_variant)] pub enum IntUnion { - V0(i32), - V1(VecM::), -} - - impl IntUnion { - pub const VARIANTS: [i32; 2] = [ - 0, -1, - ]; - pub const VARIANTS_STR: [&'static str; 2] = [ - "V0", -"V1", - ]; - - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::V0(_) => "V0", -Self::V1(_) => "V1", - } - } + V0(i32), + V1(VecM), +} - #[must_use] - pub const fn discriminant(&self) -> i32 { - #[allow(clippy::match_same_arms)] - match self { - Self::V0(_) => 0, -Self::V1(_) => 1, - } - } +impl IntUnion { + pub const VARIANTS: [i32; 2] = [0, 1]; + pub const VARIANTS_STR: [&'static str; 2] = ["V0", "V1"]; - #[must_use] - pub const fn variants() -> [i32; 2] { - Self::VARIANTS - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::V0(_) => "V0", + Self::V1(_) => "V1", } + } - impl Name for IntUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + pub const fn discriminant(&self) -> i32 { + #[allow(clippy::match_same_arms)] + match self { + Self::V0(_) => 0, + Self::V1(_) => 1, } + } - impl Discriminant for IntUnion { - #[must_use] - fn discriminant(&self) -> i32 { - Self::discriminant(self) - } - } + #[must_use] + pub const fn variants() -> [i32; 2] { + Self::VARIANTS + } +} - impl Variants for IntUnion { - fn variants() -> slice::Iter<'static, i32> { - Self::VARIANTS.iter() - } - } +impl Name for IntUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} - impl Union for IntUnion {} +impl Discriminant for IntUnion { + #[must_use] + fn discriminant(&self) -> i32 { + Self::discriminant(self) + } +} - impl ReadXdr for IntUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: i32 = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - 0 => Self::V0(i32::read_xdr(r)?), -1 => Self::V1(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } - } +impl Variants for IntUnion { + fn variants() -> slice::Iter<'static, i32> { + Self::VARIANTS.iter() + } +} - impl WriteXdr for IntUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::V0(v) => v.write_xdr(w)?, -Self::V1(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } - } +impl Union for IntUnion {} + +impl ReadXdr for IntUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: i32 = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + 0 => Self::V0(i32::read_xdr(r)?), + 1 => Self::V1(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } +} + +impl WriteXdr for IntUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::V0(v) => v.write_xdr(w)?, + Self::V1(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } +} /// IntUnion2 is an XDR Typedef defines as: /// @@ -3040,8 +3093,20 @@ Self::V1(v) => v.write_xdr(w)?, /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] -#[cfg_attr(all(feature = "schemars", feature = "serde", feature = "alloc"), derive(schemars::JsonSchema))] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3080,305 +3145,407 @@ impl ReadXdr for IntUnion2 { impl WriteXdr for IntUnion2 { #[cfg(feature = "std")] fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w|{ self.0.write_xdr(w) }) - } -} - - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum TypeVariant { - SError, -Multi, -UnionKey, -MyUnion, -IntUnion, -IntUnion2, - } - - impl TypeVariant { - pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, -TypeVariant::Multi, -TypeVariant::UnionKey, -TypeVariant::MyUnion, -TypeVariant::IntUnion, -TypeVariant::IntUnion2, ]; - pub const VARIANTS_STR: [&'static str; 6] = [ "SError", -"Multi", -"UnionKey", -"MyUnion", -"IntUnion", -"IntUnion2", ]; - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError => "SError", -Self::Multi => "Multi", -Self::UnionKey => "UnionKey", -Self::MyUnion => "MyUnion", -Self::IntUnion => "IntUnion", -Self::IntUnion2 => "IntUnion2", - } - } + w.with_limited_depth(|w| self.0.write_xdr(w)) + } +} - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } - } +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case") +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum TypeVariant { + SError, + Multi, + UnionKey, + MyUnion, + IntUnion, + IntUnion2, +} + +impl TypeVariant { + pub const VARIANTS: [TypeVariant; 6] = [ + TypeVariant::SError, + TypeVariant::Multi, + TypeVariant::UnionKey, + TypeVariant::MyUnion, + TypeVariant::IntUnion, + TypeVariant::IntUnion2, + ]; + pub const VARIANTS_STR: [&'static str; 6] = [ + "SError", + "Multi", + "UnionKey", + "MyUnion", + "IntUnion", + "IntUnion2", + ]; - impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError => "SError", + Self::Multi => "Multi", + Self::UnionKey => "UnionKey", + Self::MyUnion => "MyUnion", + Self::IntUnion => "IntUnion", + Self::IntUnion2 => "IntUnion2", } + } - impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } +} - impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "SError" => Ok(Self::SError), -"Multi" => Ok(Self::Multi), -"UnionKey" => Ok(Self::UnionKey), -"MyUnion" => Ok(Self::MyUnion), -"IntUnion" => Ok(Self::IntUnion), -"IntUnion2" => Ok(Self::IntUnion2), - _ => Err(Error::Invalid), - } - } +impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "SError" => Ok(Self::SError), + "Multi" => Ok(Self::Multi), + "UnionKey" => Ok(Self::UnionKey), + "MyUnion" => Ok(Self::MyUnion), + "IntUnion" => Ok(Self::IntUnion), + "IntUnion2" => Ok(Self::IntUnion2), + _ => Err(Error::Invalid), } + } +} - #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] - #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged), - )] - #[cfg_attr( - all(feature = "schemars", feature = "serde", feature = "alloc"), - derive(schemars::JsonSchema) - )] - pub enum Type { - SError(Box), -Multi(Box), -UnionKey(Box), -MyUnion(Box), -IntUnion(Box), -IntUnion2(Box), - } - - impl Type { - pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, -TypeVariant::Multi, -TypeVariant::UnionKey, -TypeVariant::MyUnion, -TypeVariant::IntUnion, -TypeVariant::IntUnion2, ]; - pub const VARIANTS_STR: [&'static str; 6] = [ "SError", -"Multi", -"UnionKey", -"MyUnion", -"IntUnion", -"IntUnion2", ]; +#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + serde(rename_all = "snake_case"), + serde(untagged) +)] +#[cfg_attr( + all( + feature = "schemars", + feature = "serde", + feature = "serde_json", + feature = "alloc" + ), + derive(schemars::JsonSchema) +)] +pub enum Type { + SError(Box), + Multi(Box), + UnionKey(Box), + MyUnion(Box), + IntUnion(Box), + IntUnion2(Box), +} + +impl Type { + pub const VARIANTS: [TypeVariant; 6] = [ + TypeVariant::SError, + TypeVariant::Multi, + TypeVariant::UnionKey, + TypeVariant::MyUnion, + TypeVariant::IntUnion, + TypeVariant::IntUnion2, + ]; + pub const VARIANTS_STR: [&'static str; 6] = [ + "SError", + "Multi", + "UnionKey", + "MyUnion", + "IntUnion", + "IntUnion2", + ]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::SError => r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))), -TypeVariant::Multi => r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))), -TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), -TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), -TypeVariant::IntUnion => r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))), -TypeVariant::IntUnion2 => r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))), - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::SError => { + r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) + TypeVariant::Multi => { + r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } + TypeVariant::UnionKey => { + r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) } - - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) + TypeVariant::MyUnion => { + r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), -TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), -TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), -TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), - } + TypeVariant::IntUnion => { + r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))) } - - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t.0))))), -TypeVariant::Multi => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t.0))))), -TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), -TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t.0))))), -TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0))))), - } + TypeVariant::IntUnion2 => { + r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))) } + } + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), -TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), -TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), -TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), -TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), -TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), - } - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), + r.limits.clone(), + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), -TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), -TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), -TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), -TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), -TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new( + ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::SError(Box::new(t)))), + ), + TypeVariant::Multi => Box::new( + ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Multi(Box::new(t)))), + ), + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::IntUnion => Box::new( + ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), + ), + TypeVariant::IntUnion2 => Box::new( + ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), + ), + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::SError(ref v) => v.as_ref(), -Self::Multi(ref v) => v.as_ref(), -Self::UnionKey(ref v) => v.as_ref(), -Self::MyUnion(ref v) => v.as_ref(), -Self::IntUnion(ref v) => v.as_ref(), -Self::IntUnion2(ref v) => v.as_ref(), - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::SError(Box::new(t.0)))), + ), + TypeVariant::Multi => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::Multi(Box::new(t.0)))), + ), + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), + ), + TypeVariant::IntUnion => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion(Box::new(t.0)))), + ), + TypeVariant::IntUnion2 => Box::new( + ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0)))), + ), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError(_) => "SError", -Self::Multi(_) => "Multi", -Self::UnionKey(_) => "UnionKey", -Self::MyUnion(_) => "MyUnion", -Self::IntUnion(_) => "IntUnion", -Self::IntUnion2(_) => "IntUnion2", - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter( + v: TypeVariant, + r: &mut Limited, + ) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::SError => Box::new( + ReadXdrIter::<_, SError>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::SError(Box::new(t)))), + ), + TypeVariant::Multi => Box::new( + ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::Multi(Box::new(t)))), + ), + TypeVariant::UnionKey => Box::new( + ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), + ), + TypeVariant::MyUnion => Box::new( + ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), + ), + TypeVariant::IntUnion => Box::new( + ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), + ), + TypeVariant::IntUnion2 => Box::new( + ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()) + .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), + ), + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::SError(_) => TypeVariant::SError, -Self::Multi(_) => TypeVariant::Multi, -Self::UnionKey(_) => TypeVariant::UnionKey, -Self::MyUnion(_) => TypeVariant::MyUnion, -Self::IntUnion(_) => TypeVariant::IntUnion, -Self::IntUnion2(_) => TypeVariant::IntUnion2, - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new( + base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), + limits, + ); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } + + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), + TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), + TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), + TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), + TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), } + } - impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::SError(ref v) => v.as_ref(), + Self::Multi(ref v) => v.as_ref(), + Self::UnionKey(ref v) => v.as_ref(), + Self::MyUnion(ref v) => v.as_ref(), + Self::IntUnion(ref v) => v.as_ref(), + Self::IntUnion2(ref v) => v.as_ref(), } + } - impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError(_) => "SError", + Self::Multi(_) => "Multi", + Self::UnionKey(_) => "UnionKey", + Self::MyUnion(_) => "MyUnion", + Self::IntUnion(_) => "IntUnion", + Self::IntUnion2(_) => "IntUnion2", } + } - impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::SError(v) => v.write_xdr(w), -Self::Multi(v) => v.write_xdr(w), -Self::UnionKey(v) => v.write_xdr(w), -Self::MyUnion(v) => v.write_xdr(w), -Self::IntUnion(v) => v.write_xdr(w), -Self::IntUnion2(v) => v.write_xdr(w), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::SError(_) => TypeVariant::SError, + Self::Multi(_) => TypeVariant::Multi, + Self::UnionKey(_) => TypeVariant::UnionKey, + Self::MyUnion(_) => TypeVariant::MyUnion, + Self::IntUnion(_) => TypeVariant::IntUnion, + Self::IntUnion2(_) => TypeVariant::IntUnion2, } + } +} + +impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } +} + +impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } +} + +impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::SError(v) => v.write_xdr(w), + Self::Multi(v) => v.write_xdr(w), + Self::UnionKey(v) => v.write_xdr(w), + Self::MyUnion(v) => v.write_xdr(w), + Self::IntUnion(v) => v.write_xdr(w), + Self::IntUnion2(v) => v.write_xdr(w), + } + } +} From 1aa6d5e98da0082de1f87866c16cda4e79a70f1a Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:29:50 +1000 Subject: [PATCH 07/20] gen for fixed opaque typedefs --- lib/xdrgen/generators/rust.rb | 34 + lib/xdrgen/generators/rust/src/types.rs | 4 +- .../block_comments.x/MyXDR.rs | 278 ++-- .../generator_spec_rust/const.x/MyXDR.rs | 605 ++++---- .../generator_spec_rust/enum.x/MyXDR.rs | 1298 ++++++++-------- .../generator_spec_rust/nesting.x/MyXDR.rs | 1182 +++++++-------- .../generator_spec_rust/optional.x/MyXDR.rs | 669 +++++---- .../generator_spec_rust/struct.x/MyXDR.rs | 681 ++++----- .../generator_spec_rust/test.x/MyXDR.rs | 186 ++- .../generator_spec_rust/union.x/MyXDR.rs | 1325 ++++++++--------- .../block_comments.x/MyXDR.rs | 278 ++-- .../const.x/MyXDR.rs | 605 ++++---- .../enum.x/MyXDR.rs | 1288 ++++++++-------- .../nesting.x/MyXDR.rs | 1162 +++++++-------- .../optional.x/MyXDR.rs | 659 ++++---- .../struct.x/MyXDR.rs | 671 +++++---- .../test.x/MyXDR.rs | 186 ++- .../union.x/MyXDR.rs | 1305 ++++++++-------- .../block_comments.x/MyXDR.rs | 278 ++-- .../const.x/MyXDR.rs | 605 ++++---- .../enum.x/MyXDR.rs | 1297 ++++++++-------- .../nesting.x/MyXDR.rs | 1180 +++++++-------- .../optional.x/MyXDR.rs | 668 +++++---- .../struct.x/MyXDR.rs | 680 +++++---- .../test.x/MyXDR.rs | 186 ++- .../union.x/MyXDR.rs | 1323 ++++++++-------- 26 files changed, 9569 insertions(+), 9064 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index 684358e27..a5fc1a8af 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -733,6 +733,40 @@ def render_typedef(out, typedef) } EOS end + if is_fixed_array_opaque(typedef.type) && !@options[:rust_types_custom_jsonschema_impl].include?(name typedef) + out.puts <<-EOS.strip_heredoc + impl schemars::JsonSchema for #{name typedef} { + fn schema_name() -> String { + "#{name typedef}".to_string() + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: SOME(MAX * 2), + min_length: SOME(MAX * 2), + ..string + }) + } else { + schema_ + } + } + } + EOS + end out.puts <<-EOS.strip_heredoc impl From<#{name typedef}> for #{reference(typedef, typedef.type)} { #[must_use] diff --git a/lib/xdrgen/generators/rust/src/types.rs b/lib/xdrgen/generators/rust/src/types.rs index 410b93e31..68544dcda 100644 --- a/lib/xdrgen/generators/rust/src/types.rs +++ b/lib/xdrgen/generators/rust/src/types.rs @@ -1365,8 +1365,8 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(((MAX.checked_mul(4).unwrap_or(u32::MAX) / 3) + 3) & !3), - min_length: Some(((MAX.checked_mul(4).unwrap_or(u32::MAX) / 3) + 3) & !3), + max_length: Some(MAX * 2), + min_length: None, ..string }) } else { diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index 66aaeab58..b5de5241a 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/block_comments.x", - "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/block_comments.x", "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2735,28 +2816,16 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum AccountFlags { - AuthRequiredFlag = 1, + AuthRequiredFlag = 1, } impl AccountFlags { - pub const VARIANTS: [AccountFlags; 1] = [AccountFlags::AuthRequiredFlag]; - pub const VARIANTS_STR: [&'static str; 1] = ["AuthRequiredFlag"]; + pub const VARIANTS: [AccountFlags; 1] = [ AccountFlags::AuthRequiredFlag, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AuthRequiredFlag", ]; #[must_use] pub const fn name(&self) -> &'static str { @@ -2835,26 +2904,18 @@ impl WriteXdr for AccountFlags { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") )] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum TypeVariant { AccountFlags, } impl TypeVariant { - pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; - pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; + pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; #[must_use] #[allow(clippy::too_many_lines)] @@ -2897,44 +2958,31 @@ impl core::str::FromStr for TypeVariant { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), )] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum Type { AccountFlags(Box), } impl Type { - pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; - pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; + pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { match v { - TypeVariant::AccountFlags => r.with_limited_depth(|r| { - Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?))) - }), + TypeVariant::AccountFlags => r.with_limited_depth(|r| Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?)))), } } #[cfg(feature = "base64")] pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); let t = Self::read_xdr(v, &mut dec)?; Ok(t) } @@ -2953,54 +3001,33 @@ impl Type { #[cfg(feature = "base64")] pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new( - ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), - ), + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), } } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0)))), - ), + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0))))), } } #[cfg(feature = "base64")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); match v { - TypeVariant::AccountFlags => Box::new( - ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), - ), + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), } } @@ -3014,10 +3041,7 @@ impl Type { #[cfg(feature = "base64")] pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } @@ -3026,9 +3050,7 @@ impl Type { #[allow(clippy::too_many_lines)] pub fn read_json(v: TypeVariant, r: impl Read) -> Result { match v { - TypeVariant::AccountFlags => { - Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))) - } + TypeVariant::AccountFlags => Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))), } } diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index b3a737966..ed83d1639 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/const.x", - "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/const.x", "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2745,281 +2826,229 @@ pub type TestArray = [i32; Foo]; /// typedef int TestArray2; /// ``` /// -pub type TestArray2 = VecM; - -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - TestArray, - TestArray2, -} +pub type TestArray2 = VecM::; + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + TestArray, +TestArray2, + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; - pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, +TypeVariant::TestArray2, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", +"TestArray2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray => "TestArray", +Self::TestArray2 => "TestArray2", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray => "TestArray", - Self::TestArray2 => "TestArray2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "TestArray" => Ok(Self::TestArray), +"TestArray2" => Ok(Self::TestArray2), + _ => Err(Error::Invalid), + } + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "TestArray" => Ok(Self::TestArray), - "TestArray2" => Ok(Self::TestArray2), - _ => Err(Error::Invalid), + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + TestArray(Box), +TestArray2(Box), } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - TestArray(Box), - TestArray2(Box), -} + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, +TypeVariant::TestArray2, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", +"TestArray2", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; - pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::TestArray => r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))), +TypeVariant::TestArray2 => r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::TestArray => { - r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::TestArray2 => { - r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t.0))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t.0))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new( - ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), - ), - TypeVariant::TestArray2 => Box::new( - ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray(Box::new(t.0)))), - ), - TypeVariant::TestArray2 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray2(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::TestArray => Box::new( - ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), - ), - TypeVariant::TestArray2 => Box::new( - ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), +TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::TestArray(ref v) => v.as_ref(), +Self::TestArray2(ref v) => v.as_ref(), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), - TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray(_) => "TestArray", +Self::TestArray2(_) => "TestArray2", + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::TestArray(ref v) => v.as_ref(), - Self::TestArray2(ref v) => v.as_ref(), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray(_) => "TestArray", - Self::TestArray2(_) => "TestArray2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::TestArray(_) => TypeVariant::TestArray, +Self::TestArray2(_) => TypeVariant::TestArray2, + } + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::TestArray(_) => TypeVariant::TestArray, - Self::TestArray2(_) => TypeVariant::TestArray2, + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::TestArray(v) => v.write_xdr(w), - Self::TestArray2(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::TestArray(v) => v.write_xdr(w), +Self::TestArray2(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index f9ee1e9fe..9467d91ad 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/enum.x", - "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/enum.x", "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2731,19 +2812,19 @@ mod test { /// ERROR_MSG, /// HELLO, /// DONT_HAVE, -/// +/// /// GET_PEERS, // gets a list of peers this guy knows about /// PEERS, -/// +/// /// GET_TX_SET, // gets a particular txset by hash /// TX_SET, -/// +/// /// GET_VALIDATIONS, // gets validations for a given ledger hash /// VALIDATIONS, -/// +/// /// TRANSACTION, //pass on a tx you have heard about /// JSON_TRANSACTION, -/// +/// /// // FBA /// GET_FBA_QUORUMSET, /// FBA_QUORUMSET, @@ -2754,172 +2835,156 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum MessageType { - ErrorMsg = 0, - Hello = 1, - DontHave = 2, - GetPeers = 3, - Peers = 4, - GetTxSet = 5, - TxSet = 6, - GetValidations = 7, - Validations = 8, - Transaction = 9, - JsonTransaction = 10, - GetFbaQuorumset = 11, - FbaQuorumset = 12, - FbaMessage = 13, -} - -impl MessageType { - pub const VARIANTS: [MessageType; 14] = [ - MessageType::ErrorMsg, - MessageType::Hello, - MessageType::DontHave, - MessageType::GetPeers, - MessageType::Peers, - MessageType::GetTxSet, - MessageType::TxSet, - MessageType::GetValidations, - MessageType::Validations, - MessageType::Transaction, - MessageType::JsonTransaction, - MessageType::GetFbaQuorumset, - MessageType::FbaQuorumset, - MessageType::FbaMessage, - ]; - pub const VARIANTS_STR: [&'static str; 14] = [ - "ErrorMsg", - "Hello", - "DontHave", - "GetPeers", - "Peers", - "GetTxSet", - "TxSet", - "GetValidations", - "Validations", - "Transaction", - "JsonTransaction", - "GetFbaQuorumset", - "FbaQuorumset", - "FbaMessage", - ]; + ErrorMsg = 0, + Hello = 1, + DontHave = 2, + GetPeers = 3, + Peers = 4, + GetTxSet = 5, + TxSet = 6, + GetValidations = 7, + Validations = 8, + Transaction = 9, + JsonTransaction = 10, + GetFbaQuorumset = 11, + FbaQuorumset = 12, + FbaMessage = 13, +} + + impl MessageType { + pub const VARIANTS: [MessageType; 14] = [ MessageType::ErrorMsg, +MessageType::Hello, +MessageType::DontHave, +MessageType::GetPeers, +MessageType::Peers, +MessageType::GetTxSet, +MessageType::TxSet, +MessageType::GetValidations, +MessageType::Validations, +MessageType::Transaction, +MessageType::JsonTransaction, +MessageType::GetFbaQuorumset, +MessageType::FbaQuorumset, +MessageType::FbaMessage, ]; + pub const VARIANTS_STR: [&'static str; 14] = [ "ErrorMsg", +"Hello", +"DontHave", +"GetPeers", +"Peers", +"GetTxSet", +"TxSet", +"GetValidations", +"Validations", +"Transaction", +"JsonTransaction", +"GetFbaQuorumset", +"FbaQuorumset", +"FbaMessage", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::ErrorMsg => "ErrorMsg", +Self::Hello => "Hello", +Self::DontHave => "DontHave", +Self::GetPeers => "GetPeers", +Self::Peers => "Peers", +Self::GetTxSet => "GetTxSet", +Self::TxSet => "TxSet", +Self::GetValidations => "GetValidations", +Self::Validations => "Validations", +Self::Transaction => "Transaction", +Self::JsonTransaction => "JsonTransaction", +Self::GetFbaQuorumset => "GetFbaQuorumset", +Self::FbaQuorumset => "FbaQuorumset", +Self::FbaMessage => "FbaMessage", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::ErrorMsg => "ErrorMsg", - Self::Hello => "Hello", - Self::DontHave => "DontHave", - Self::GetPeers => "GetPeers", - Self::Peers => "Peers", - Self::GetTxSet => "GetTxSet", - Self::TxSet => "TxSet", - Self::GetValidations => "GetValidations", - Self::Validations => "Validations", - Self::Transaction => "Transaction", - Self::JsonTransaction => "JsonTransaction", - Self::GetFbaQuorumset => "GetFbaQuorumset", - Self::FbaQuorumset => "FbaQuorumset", - Self::FbaMessage => "FbaMessage", + #[must_use] + pub const fn variants() -> [MessageType; 14] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn variants() -> [MessageType; 14] { - Self::VARIANTS - } -} - -impl Name for MessageType { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for MessageType { - fn variants() -> slice::Iter<'static, MessageType> { - Self::VARIANTS.iter() - } -} + impl Name for MessageType { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Enum for MessageType {} + impl Variants for MessageType { + fn variants() -> slice::Iter<'static, MessageType> { + Self::VARIANTS.iter() + } + } -impl fmt::Display for MessageType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl Enum for MessageType {} -impl TryFrom for MessageType { - type Error = Error; + impl fmt::Display for MessageType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } - fn try_from(i: i32) -> Result { - let e = match i { - 0 => MessageType::ErrorMsg, - 1 => MessageType::Hello, - 2 => MessageType::DontHave, - 3 => MessageType::GetPeers, - 4 => MessageType::Peers, - 5 => MessageType::GetTxSet, - 6 => MessageType::TxSet, - 7 => MessageType::GetValidations, - 8 => MessageType::Validations, - 9 => MessageType::Transaction, - 10 => MessageType::JsonTransaction, - 11 => MessageType::GetFbaQuorumset, - 12 => MessageType::FbaQuorumset, - 13 => MessageType::FbaMessage, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + impl TryFrom for MessageType { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 0 => MessageType::ErrorMsg, +1 => MessageType::Hello, +2 => MessageType::DontHave, +3 => MessageType::GetPeers, +4 => MessageType::Peers, +5 => MessageType::GetTxSet, +6 => MessageType::TxSet, +7 => MessageType::GetValidations, +8 => MessageType::Validations, +9 => MessageType::Transaction, +10 => MessageType::JsonTransaction, +11 => MessageType::GetFbaQuorumset, +12 => MessageType::FbaQuorumset, +13 => MessageType::FbaMessage, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: MessageType) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: MessageType) -> Self { + e as Self + } + } -impl ReadXdr for MessageType { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for MessageType { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for MessageType { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for MessageType { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// Color is an XDR Enum defines as: /// @@ -2934,109 +2999,101 @@ impl WriteXdr for MessageType { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { - Red = 0, - Green = 1, - Blue = 2, -} - -impl Color { - pub const VARIANTS: [Color; 3] = [Color::Red, Color::Green, Color::Blue]; - pub const VARIANTS_STR: [&'static str; 3] = ["Red", "Green", "Blue"]; + Red = 0, + Green = 1, + Blue = 2, +} + + impl Color { + pub const VARIANTS: [Color; 3] = [ Color::Red, +Color::Green, +Color::Blue, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "Red", +"Green", +"Blue", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red => "Red", +Self::Green => "Green", +Self::Blue => "Blue", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red => "Red", - Self::Green => "Green", - Self::Blue => "Blue", + #[must_use] + pub const fn variants() -> [Color; 3] { + Self::VARIANTS + } } - } - - #[must_use] - pub const fn variants() -> [Color; 3] { - Self::VARIANTS - } -} -impl Name for Color { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for Color { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for Color { - fn variants() -> slice::Iter<'static, Color> { - Self::VARIANTS.iter() - } -} + impl Variants for Color { + fn variants() -> slice::Iter<'static, Color> { + Self::VARIANTS.iter() + } + } -impl Enum for Color {} + impl Enum for Color {} -impl fmt::Display for Color { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl fmt::Display for Color { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } -impl TryFrom for Color { - type Error = Error; + impl TryFrom for Color { + type Error = Error; - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color::Red, - 1 => Color::Green, - 2 => Color::Blue, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color::Red, +1 => Color::Green, +2 => Color::Blue, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: Color) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: Color) -> Self { + e as Self + } + } -impl ReadXdr for Color { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for Color { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for Color { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for Color { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// Color2 is an XDR Enum defines as: /// @@ -3051,417 +3108,340 @@ impl WriteXdr for Color { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color2 { - Red2 = 0, - Green2 = 1, - Blue2 = 2, -} - -impl Color2 { - pub const VARIANTS: [Color2; 3] = [Color2::Red2, Color2::Green2, Color2::Blue2]; - pub const VARIANTS_STR: [&'static str; 3] = ["Red2", "Green2", "Blue2"]; + Red2 = 0, + Green2 = 1, + Blue2 = 2, +} + + impl Color2 { + pub const VARIANTS: [Color2; 3] = [ Color2::Red2, +Color2::Green2, +Color2::Blue2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "Red2", +"Green2", +"Blue2", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red2 => "Red2", +Self::Green2 => "Green2", +Self::Blue2 => "Blue2", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red2 => "Red2", - Self::Green2 => "Green2", - Self::Blue2 => "Blue2", + #[must_use] + pub const fn variants() -> [Color2; 3] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn variants() -> [Color2; 3] { - Self::VARIANTS - } -} - -impl Name for Color2 { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for Color2 { - fn variants() -> slice::Iter<'static, Color2> { - Self::VARIANTS.iter() - } -} + impl Name for Color2 { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Enum for Color2 {} + impl Variants for Color2 { + fn variants() -> slice::Iter<'static, Color2> { + Self::VARIANTS.iter() + } + } -impl fmt::Display for Color2 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl Enum for Color2 {} -impl TryFrom for Color2 { - type Error = Error; + impl fmt::Display for Color2 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color2::Red2, - 1 => Color2::Green2, - 2 => Color2::Blue2, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + impl TryFrom for Color2 { + type Error = Error; -impl From for i32 { - #[must_use] - fn from(e: Color2) -> Self { - e as Self - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color2::Red2, +1 => Color2::Green2, +2 => Color2::Blue2, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl ReadXdr for Color2 { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl From for i32 { + #[must_use] + fn from(e: Color2) -> Self { + e as Self + } + } -impl WriteXdr for Color2 { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl ReadXdr for Color2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - MessageType, - Color, - Color2, -} + impl WriteXdr for Color2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 3] = [ - TypeVariant::MessageType, - TypeVariant::Color, - TypeVariant::Color2, - ]; - pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + MessageType, +Color, +Color2, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, +TypeVariant::Color, +TypeVariant::Color2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", +"Color", +"Color2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType => "MessageType", +Self::Color => "Color", +Self::Color2 => "Color2", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType => "MessageType", - Self::Color => "Color", - Self::Color2 => "Color2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS - } -} - -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "MessageType" => Ok(Self::MessageType), - "Color" => Ok(Self::Color), - "Color2" => Ok(Self::Color2), - _ => Err(Error::Invalid), + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "MessageType" => Ok(Self::MessageType), +"Color" => Ok(Self::Color), +"Color2" => Ok(Self::Color2), + _ => Err(Error::Invalid), + } + } } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - MessageType(Box), - Color(Box), - Color2(Box), -} + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + MessageType(Box), +Color(Box), +Color2(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, +TypeVariant::Color, +TypeVariant::Color2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", +"Color", +"Color2", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 3] = [ - TypeVariant::MessageType, - TypeVariant::Color, - TypeVariant::Color2, - ]; - pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::MessageType => r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))), +TypeVariant::Color => r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))), +TypeVariant::Color2 => r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::MessageType => { - r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::Color => { - r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - TypeVariant::Color2 => { - r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t.0))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t.0))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t.0))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new( - ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), - ), - TypeVariant::Color => Box::new( - ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color(Box::new(t)))), - ), - TypeVariant::Color2 => Box::new( - ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color2(Box::new(t)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MessageType(Box::new(t.0)))), - ), - TypeVariant::Color => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color(Box::new(t.0)))), - ), - TypeVariant::Color2 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color2(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::MessageType => Box::new( - ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), - ), - TypeVariant::Color => Box::new( - ReadXdrIter::<_, Color>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Color(Box::new(t)))), - ), - TypeVariant::Color2 => Box::new( - ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Color2(Box::new(t)))), - ), - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::MessageType => Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::MessageType(ref v) => v.as_ref(), +Self::Color(ref v) => v.as_ref(), +Self::Color2(ref v) => v.as_ref(), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType(_) => "MessageType", +Self::Color(_) => "Color", +Self::Color2(_) => "Color2", + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::MessageType => { - Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))) + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS } - TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), - TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), - } - } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::MessageType(ref v) => v.as_ref(), - Self::Color(ref v) => v.as_ref(), - Self::Color2(ref v) => v.as_ref(), + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::MessageType(_) => TypeVariant::MessageType, +Self::Color(_) => TypeVariant::Color, +Self::Color2(_) => TypeVariant::Color2, + } + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType(_) => "MessageType", - Self::Color(_) => "Color", - Self::Color2(_) => "Color2", + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::MessageType(_) => TypeVariant::MessageType, - Self::Color(_) => TypeVariant::Color, - Self::Color2(_) => TypeVariant::Color2, + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::MessageType(v) => v.write_xdr(w), - Self::Color(v) => v.write_xdr(w), - Self::Color2(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::MessageType(v) => v.write_xdr(w), +Self::Color(v) => v.write_xdr(w), +Self::Color2(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 043e66cd5..7a7cbe5e2 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/nesting.x", - "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/nesting.x", "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2736,109 +2817,101 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { - One = 1, - Two = 2, - Offer = 3, -} - -impl UnionKey { - pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; - pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; + One = 1, + Two = 2, + Offer = 3, +} + + impl UnionKey { + pub const VARIANTS: [UnionKey; 3] = [ UnionKey::One, +UnionKey::Two, +UnionKey::Offer, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "One", +"Two", +"Offer", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One => "One", +Self::Two => "Two", +Self::Offer => "Offer", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One => "One", - Self::Two => "Two", - Self::Offer => "Offer", + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } -} -impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Enum for UnionKey {} + impl Enum for UnionKey {} -impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } -impl TryFrom for UnionKey { - type Error = Error; + impl TryFrom for UnionKey { + type Error = Error; - fn try_from(i: i32) -> Result { - let e = match i { - 1 => UnionKey::One, - 2 => UnionKey::Two, - 3 => UnionKey::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 1 => UnionKey::One, +2 => UnionKey::Two, +3 => UnionKey::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } + } -impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// Foo is an XDR Typedef defines as: /// @@ -2858,30 +2931,18 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyUnionOne { - pub some_int: i32, + pub some_int: i32, } impl ReadXdr for MyUnionOne { #[cfg(feature = "std")] fn read_xdr(r: &mut Limited) -> Result { r.with_limited_depth(|r| { - Ok(Self { - some_int: i32::read_xdr(r)?, + Ok(Self{ + some_int: i32::read_xdr(r)?, }) }) } @@ -2908,47 +2969,35 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyUnionTwo { - pub some_int: i32, - pub foo: i32, + pub some_int: i32, + pub foo: i32, } -impl ReadXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self { - some_int: i32::read_xdr(r)?, - foo: i32::read_xdr(r)?, - }) - }) - } -} + impl ReadXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + some_int: i32::read_xdr(r)?, +foo: i32::read_xdr(r)?, + }) + }) + } + } -impl WriteXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; - self.foo.write_xdr(w)?; - Ok(()) - }) - } -} + impl WriteXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; +self.foo.write_xdr(w)?; + Ok(()) + }) + } + } /// MyUnion is an XDR Union defines as: /// @@ -2959,13 +3008,13 @@ impl WriteXdr for MyUnionTwo { /// struct { /// int someInt; /// } one; -/// +/// /// case TWO: /// struct { /// int someInt; /// Foo foo; /// } two; -/// +/// /// case OFFER: /// void; /// }; @@ -2974,471 +3023,380 @@ impl WriteXdr for MyUnionTwo { // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - One(MyUnionOne), - Two(MyUnionTwo), - Offer, -} + One(MyUnionOne), + Two(MyUnionTwo), + Offer, +} + + impl MyUnion { + pub const VARIANTS: [UnionKey; 3] = [ + UnionKey::One, +UnionKey::Two, +UnionKey::Offer, + ]; + pub const VARIANTS_STR: [&'static str; 3] = [ + "One", +"Two", +"Offer", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One(_) => "One", +Self::Two(_) => "Two", +Self::Offer => "Offer", + } + } -impl MyUnion { - pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; - pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::One(_) => UnionKey::One, +Self::Two(_) => UnionKey::Two, +Self::Offer => UnionKey::Offer, + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One(_) => "One", - Self::Two(_) => "Two", - Self::Offer => "Offer", + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::One(_) => UnionKey::One, - Self::Two(_) => UnionKey::Two, - Self::Offer => UnionKey::Offer, + impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } -} - -impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } -} + impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } + } -impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Union for MyUnion {} + impl Union for MyUnion {} -impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), - UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), - UnionKey::Offer => Self::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } -} + impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), +UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), +UnionKey::Offer => Self::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } -impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::One(v) => v.write_xdr(w)?, - Self::Two(v) => v.write_xdr(w)?, - Self::Offer => ().write_xdr(w)?, - }; - Ok(()) - }) - } -} + impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::One(v) => v.write_xdr(w)?, +Self::Two(v) => v.write_xdr(w)?, +Self::Offer => ().write_xdr(w)?, + }; + Ok(()) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - UnionKey, - Foo, - MyUnion, - MyUnionOne, - MyUnionTwo, -} - -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 5] = [ - TypeVariant::UnionKey, - TypeVariant::Foo, - TypeVariant::MyUnion, - TypeVariant::MyUnionOne, - TypeVariant::MyUnionTwo, - ]; - pub const VARIANTS_STR: [&'static str; 5] = - ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + UnionKey, +Foo, +MyUnion, +MyUnionOne, +MyUnionTwo, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, +TypeVariant::Foo, +TypeVariant::MyUnion, +TypeVariant::MyUnionOne, +TypeVariant::MyUnionTwo, ]; + pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", +"Foo", +"MyUnion", +"MyUnionOne", +"MyUnionTwo", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey => "UnionKey", +Self::Foo => "Foo", +Self::MyUnion => "MyUnion", +Self::MyUnionOne => "MyUnionOne", +Self::MyUnionTwo => "MyUnionTwo", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey => "UnionKey", - Self::Foo => "Foo", - Self::MyUnion => "MyUnion", - Self::MyUnionOne => "MyUnionOne", - Self::MyUnionTwo => "MyUnionTwo", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } -} -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "UnionKey" => Ok(Self::UnionKey), - "Foo" => Ok(Self::Foo), - "MyUnion" => Ok(Self::MyUnion), - "MyUnionOne" => Ok(Self::MyUnionOne), - "MyUnionTwo" => Ok(Self::MyUnionTwo), - _ => Err(Error::Invalid), + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "UnionKey" => Ok(Self::UnionKey), +"Foo" => Ok(Self::Foo), +"MyUnion" => Ok(Self::MyUnion), +"MyUnionOne" => Ok(Self::MyUnionOne), +"MyUnionTwo" => Ok(Self::MyUnionTwo), + _ => Err(Error::Invalid), + } + } } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - UnionKey(Box), - Foo(Box), - MyUnion(Box), - MyUnionOne(Box), - MyUnionTwo(Box), -} - -impl Type { - pub const VARIANTS: [TypeVariant; 5] = [ - TypeVariant::UnionKey, - TypeVariant::Foo, - TypeVariant::MyUnion, - TypeVariant::MyUnionOne, - TypeVariant::MyUnionTwo, - ]; - pub const VARIANTS_STR: [&'static str; 5] = - ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + UnionKey(Box), +Foo(Box), +MyUnion(Box), +MyUnionOne(Box), +MyUnionTwo(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, +TypeVariant::Foo, +TypeVariant::MyUnion, +TypeVariant::MyUnionOne, +TypeVariant::MyUnionTwo, ]; + pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", +"Foo", +"MyUnion", +"MyUnionOne", +"MyUnionTwo", ]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::UnionKey => { - r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) - } - TypeVariant::Foo => { - r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))) + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), +TypeVariant::Foo => r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))), +TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), +TypeVariant::MyUnionOne => r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))), +TypeVariant::MyUnionTwo => r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))), + } } - TypeVariant::MyUnion => { - r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::MyUnionOne => { - r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - TypeVariant::MyUnionTwo => { - r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), + } + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t.0))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::Foo => Box::new( - ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Foo(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::MyUnionOne => Box::new( - ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), - ), - TypeVariant::MyUnionTwo => Box::new( - ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), - ), - TypeVariant::Foo => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Foo(Box::new(t.0)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), - ), - TypeVariant::MyUnionOne => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0)))), - ), - TypeVariant::MyUnionTwo => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::Foo => Box::new( - ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Foo(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::MyUnionOne => Box::new( - ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), - ), - TypeVariant::MyUnionTwo => Box::new( - ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), - ), - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::UnionKey(ref v) => v.as_ref(), +Self::Foo(ref v) => v.as_ref(), +Self::MyUnion(ref v) => v.as_ref(), +Self::MyUnionOne(ref v) => v.as_ref(), +Self::MyUnionTwo(ref v) => v.as_ref(), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey(_) => "UnionKey", +Self::Foo(_) => "Foo", +Self::MyUnion(_) => "MyUnion", +Self::MyUnionOne(_) => "MyUnionOne", +Self::MyUnionTwo(_) => "MyUnionTwo", + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), - TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::UnionKey(ref v) => v.as_ref(), - Self::Foo(ref v) => v.as_ref(), - Self::MyUnion(ref v) => v.as_ref(), - Self::MyUnionOne(ref v) => v.as_ref(), - Self::MyUnionTwo(ref v) => v.as_ref(), + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::UnionKey(_) => TypeVariant::UnionKey, +Self::Foo(_) => TypeVariant::Foo, +Self::MyUnion(_) => TypeVariant::MyUnion, +Self::MyUnionOne(_) => TypeVariant::MyUnionOne, +Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, + } + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey(_) => "UnionKey", - Self::Foo(_) => "Foo", - Self::MyUnion(_) => "MyUnion", - Self::MyUnionOne(_) => "MyUnionOne", - Self::MyUnionTwo(_) => "MyUnionTwo", + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::UnionKey(_) => TypeVariant::UnionKey, - Self::Foo(_) => TypeVariant::Foo, - Self::MyUnion(_) => TypeVariant::MyUnion, - Self::MyUnionOne(_) => TypeVariant::MyUnionOne, - Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} - -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::UnionKey(v) => v.write_xdr(w), - Self::Foo(v) => v.write_xdr(w), - Self::MyUnion(v) => v.write_xdr(w), - Self::MyUnionOne(v) => v.write_xdr(w), - Self::MyUnionTwo(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::UnionKey(v) => v.write_xdr(w), +Self::Foo(v) => v.write_xdr(w), +Self::MyUnion(v) => v.write_xdr(w), +Self::MyUnionOne(v) => v.write_xdr(w), +Self::MyUnionTwo(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 3fdd0d44f..89b4e1caa 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/optional.x", - "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/optional.x", "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2744,324 +2825,260 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct HasOptions { - pub first_option: Option, - pub second_option: Option, - pub third_option: Option, + pub first_option: Option, + pub second_option: Option, + pub third_option: Option, } -impl ReadXdr for HasOptions { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self { - first_option: Option::::read_xdr(r)?, - second_option: Option::::read_xdr(r)?, - third_option: Option::::read_xdr(r)?, - }) - }) - } -} + impl ReadXdr for HasOptions { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + first_option: Option::::read_xdr(r)?, +second_option: Option::::read_xdr(r)?, +third_option: Option::::read_xdr(r)?, + }) + }) + } + } -impl WriteXdr for HasOptions { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.first_option.write_xdr(w)?; - self.second_option.write_xdr(w)?; - self.third_option.write_xdr(w)?; - Ok(()) - }) - } -} + impl WriteXdr for HasOptions { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.first_option.write_xdr(w)?; +self.second_option.write_xdr(w)?; +self.third_option.write_xdr(w)?; + Ok(()) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - Arr, - HasOptions, -} + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + Arr, +HasOptions, + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; - pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, +TypeVariant::HasOptions, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", +"HasOptions", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr => "Arr", +Self::HasOptions => "HasOptions", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr => "Arr", - Self::HasOptions => "HasOptions", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Arr" => Ok(Self::Arr), +"HasOptions" => Ok(Self::HasOptions), + _ => Err(Error::Invalid), + } + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Arr" => Ok(Self::Arr), - "HasOptions" => Ok(Self::HasOptions), - _ => Err(Error::Invalid), + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + Arr(Box), +HasOptions(Box), } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - Arr(Box), - HasOptions(Box), -} + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, +TypeVariant::HasOptions, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", +"HasOptions", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; - pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Arr => r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))), +TypeVariant::HasOptions => r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Arr => { - r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::HasOptions => { - r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t.0))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t.0))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new( - ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Arr(Box::new(t)))), - ), - TypeVariant::HasOptions => Box::new( - ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Arr(Box::new(t.0)))), - ), - TypeVariant::HasOptions => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::HasOptions(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Arr => Box::new( - ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Arr(Box::new(t)))), - ), - TypeVariant::HasOptions => Box::new( - ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), +TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Arr(ref v) => v.as_ref(), +Self::HasOptions(ref v) => v.as_ref(), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), - TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr(_) => "Arr", +Self::HasOptions(_) => "HasOptions", + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Arr(ref v) => v.as_ref(), - Self::HasOptions(ref v) => v.as_ref(), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr(_) => "Arr", - Self::HasOptions(_) => "HasOptions", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Arr(_) => TypeVariant::Arr, +Self::HasOptions(_) => TypeVariant::HasOptions, + } + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Arr(_) => TypeVariant::Arr, - Self::HasOptions(_) => TypeVariant::HasOptions, + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Arr(v) => v.write_xdr(w), - Self::HasOptions(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Arr(v) => v.write_xdr(w), +Self::HasOptions(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index 9807c22c5..8dc15e900 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/struct.x", - "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/struct.x", "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2746,330 +2827,266 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyStruct { - pub some_int: i32, - pub a_big_int: i64, - pub some_opaque: [u8; 10], - pub some_string: StringM, - pub max_string: StringM<100>, + pub some_int: i32, + pub a_big_int: i64, + pub some_opaque: [u8; 10], + pub some_string: StringM, + pub max_string: StringM::<100>, } -impl ReadXdr for MyStruct { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self { - some_int: i32::read_xdr(r)?, - a_big_int: i64::read_xdr(r)?, - some_opaque: <[u8; 10]>::read_xdr(r)?, - some_string: StringM::read_xdr(r)?, - max_string: StringM::<100>::read_xdr(r)?, - }) - }) - } -} + impl ReadXdr for MyStruct { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + some_int: i32::read_xdr(r)?, +a_big_int: i64::read_xdr(r)?, +some_opaque: <[u8; 10]>::read_xdr(r)?, +some_string: StringM::read_xdr(r)?, +max_string: StringM::<100>::read_xdr(r)?, + }) + }) + } + } -impl WriteXdr for MyStruct { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; - self.a_big_int.write_xdr(w)?; - self.some_opaque.write_xdr(w)?; - self.some_string.write_xdr(w)?; - self.max_string.write_xdr(w)?; - Ok(()) - }) - } -} + impl WriteXdr for MyStruct { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; +self.a_big_int.write_xdr(w)?; +self.some_opaque.write_xdr(w)?; +self.some_string.write_xdr(w)?; +self.max_string.write_xdr(w)?; + Ok(()) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - Int64, - MyStruct, -} + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + Int64, +MyStruct, + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; - pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, +TypeVariant::MyStruct, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", +"MyStruct", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64 => "Int64", +Self::MyStruct => "MyStruct", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64 => "Int64", - Self::MyStruct => "MyStruct", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Int64" => Ok(Self::Int64), +"MyStruct" => Ok(Self::MyStruct), + _ => Err(Error::Invalid), + } + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Int64" => Ok(Self::Int64), - "MyStruct" => Ok(Self::MyStruct), - _ => Err(Error::Invalid), + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + Int64(Box), +MyStruct(Box), } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - Int64(Box), - MyStruct(Box), -} + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, +TypeVariant::MyStruct, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", +"MyStruct", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; - pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Int64 => r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))), +TypeVariant::MyStruct => r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Int64 => { - r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::MyStruct => { - r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t.0))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t.0))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new( - ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Int64(Box::new(t)))), - ), - TypeVariant::MyStruct => Box::new( - ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Int64(Box::new(t.0)))), - ), - TypeVariant::MyStruct => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyStruct(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Int64 => Box::new( - ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Int64(Box::new(t)))), - ), - TypeVariant::MyStruct => Box::new( - ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Int64(ref v) => v.as_ref(), +Self::MyStruct(ref v) => v.as_ref(), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64(_) => "Int64", +Self::MyStruct(_) => "MyStruct", + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Int64(ref v) => v.as_ref(), - Self::MyStruct(ref v) => v.as_ref(), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64(_) => "Int64", - Self::MyStruct(_) => "MyStruct", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Int64(_) => TypeVariant::Int64, +Self::MyStruct(_) => TypeVariant::MyStruct, + } + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Int64(_) => TypeVariant::Int64, - Self::MyStruct(_) => TypeVariant::MyStruct, + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Int64(v) => v.write_xdr(w), - Self::MyStruct(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Int64(v) => v.write_xdr(w), +Self::MyStruct(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index ad5a7c94b..6e98de668 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -874,7 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -899,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1282,7 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1335,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1664,7 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1724,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2036,11 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2065,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2730,6 +2844,36 @@ impl core::str::FromStr for Uint512 { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +impl schemars::JsonSchema for Uint512 { + fn schema_name() -> String { + "Uint512".to_string() + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: SOME(MAX * 2), + min_length: SOME(MAX * 2), + ..string + }) + } else { + schema_ + } + } +} impl From for [u8; 64] { #[must_use] fn from(x: Uint512) -> Self { @@ -3254,6 +3398,36 @@ impl core::str::FromStr for Hash { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +impl schemars::JsonSchema for Hash { + fn schema_name() -> String { + "Hash".to_string() + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: SOME(MAX * 2), + min_length: SOME(MAX * 2), + ..string + }) + } else { + schema_ + } + } +} impl From for [u8; 32] { #[must_use] fn from(x: Hash) -> Self { @@ -4327,7 +4501,7 @@ self.nested_union.write_xdr(w)?; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -4491,7 +4665,7 @@ Self::NesterNestedUnion => "NesterNestedUnion", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 606846e05..85f23b584 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/union.x", - "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/union.x", "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2751,106 +2832,96 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { - Error = 0, - Multi = 1, + Error = 0, + Multi = 1, } -impl UnionKey { - pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; - pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; + impl UnionKey { + pub const VARIANTS: [UnionKey; 2] = [ UnionKey::Error, +UnionKey::Multi, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Error", +"Multi", ]; - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error => "Error", - Self::Multi => "Multi", - } - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error => "Error", +Self::Multi => "Multi", + } + } - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } -} + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } + } -impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Enum for UnionKey {} + impl Enum for UnionKey {} -impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } -impl TryFrom for UnionKey { - type Error = Error; + impl TryFrom for UnionKey { + type Error = Error; - fn try_from(i: i32) -> Result { - let e = match i { - 0 => UnionKey::Error, - 1 => UnionKey::Multi, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 0 => UnionKey::Error, +1 => UnionKey::Multi, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } + } -impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// MyUnion is an XDR Union defines as: /// @@ -2861,114 +2932,108 @@ impl WriteXdr for UnionKey { /// Error error; /// case MULTI: /// Multi things<>; -/// -/// +/// +/// /// }; /// ``` /// // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - Error(i32), - Multi(VecM), -} + Error(i32), + Multi(VecM::), +} + + impl MyUnion { + pub const VARIANTS: [UnionKey; 2] = [ + UnionKey::Error, +UnionKey::Multi, + ]; + pub const VARIANTS_STR: [&'static str; 2] = [ + "Error", +"Multi", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error(_) => "Error", +Self::Multi(_) => "Multi", + } + } -impl MyUnion { - pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; - pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::Error(_) => UnionKey::Error, +Self::Multi(_) => UnionKey::Multi, + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error(_) => "Error", - Self::Multi(_) => "Multi", + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::Error(_) => UnionKey::Error, - Self::Multi(_) => UnionKey::Multi, + impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } -} - -impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } -} + impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } + } -impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Union for MyUnion {} + impl Union for MyUnion {} -impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::Error => Self::Error(i32::read_xdr(r)?), - UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } -} + impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::Error => Self::Error(i32::read_xdr(r)?), +UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } -impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::Error(v) => v.write_xdr(w)?, - Self::Multi(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } -} + impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::Error(v) => v.write_xdr(w)?, +Self::Multi(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } + } /// IntUnion is an XDR Union defines as: /// @@ -2979,113 +3044,107 @@ impl WriteXdr for MyUnion { /// Error error; /// case 1: /// Multi things<>; -/// +/// /// }; /// ``` /// // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum IntUnion { - V0(i32), - V1(VecM), -} + V0(i32), + V1(VecM::), +} + + impl IntUnion { + pub const VARIANTS: [i32; 2] = [ + 0, +1, + ]; + pub const VARIANTS_STR: [&'static str; 2] = [ + "V0", +"V1", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::V0(_) => "V0", +Self::V1(_) => "V1", + } + } -impl IntUnion { - pub const VARIANTS: [i32; 2] = [0, 1]; - pub const VARIANTS_STR: [&'static str; 2] = ["V0", "V1"]; + #[must_use] + pub const fn discriminant(&self) -> i32 { + #[allow(clippy::match_same_arms)] + match self { + Self::V0(_) => 0, +Self::V1(_) => 1, + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::V0(_) => "V0", - Self::V1(_) => "V1", + #[must_use] + pub const fn variants() -> [i32; 2] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn discriminant(&self) -> i32 { - #[allow(clippy::match_same_arms)] - match self { - Self::V0(_) => 0, - Self::V1(_) => 1, + impl Name for IntUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - pub const fn variants() -> [i32; 2] { - Self::VARIANTS - } -} -impl Name for IntUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Discriminant for IntUnion { - #[must_use] - fn discriminant(&self) -> i32 { - Self::discriminant(self) - } -} + impl Discriminant for IntUnion { + #[must_use] + fn discriminant(&self) -> i32 { + Self::discriminant(self) + } + } -impl Variants for IntUnion { - fn variants() -> slice::Iter<'static, i32> { - Self::VARIANTS.iter() - } -} + impl Variants for IntUnion { + fn variants() -> slice::Iter<'static, i32> { + Self::VARIANTS.iter() + } + } -impl Union for IntUnion {} + impl Union for IntUnion {} -impl ReadXdr for IntUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: i32 = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - 0 => Self::V0(i32::read_xdr(r)?), - 1 => Self::V1(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } -} + impl ReadXdr for IntUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: i32 = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + 0 => Self::V0(i32::read_xdr(r)?), +1 => Self::V1(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } -impl WriteXdr for IntUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::V0(v) => v.write_xdr(w)?, - Self::V1(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } -} + impl WriteXdr for IntUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::V0(v) => v.write_xdr(w)?, +Self::V1(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } + } /// IntUnion2 is an XDR Typedef defines as: /// @@ -3095,20 +3154,8 @@ impl WriteXdr for IntUnion { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3147,407 +3194,299 @@ impl ReadXdr for IntUnion2 { impl WriteXdr for IntUnion2 { #[cfg(feature = "std")] fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| self.0.write_xdr(w)) - } -} - -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - SError, - Multi, - UnionKey, - MyUnion, - IntUnion, - IntUnion2, -} - -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 6] = [ - TypeVariant::SError, - TypeVariant::Multi, - TypeVariant::UnionKey, - TypeVariant::MyUnion, - TypeVariant::IntUnion, - TypeVariant::IntUnion2, - ]; - pub const VARIANTS_STR: [&'static str; 6] = [ - "SError", - "Multi", - "UnionKey", - "MyUnion", - "IntUnion", - "IntUnion2", - ]; + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + SError, +Multi, +UnionKey, +MyUnion, +IntUnion, +IntUnion2, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, +TypeVariant::Multi, +TypeVariant::UnionKey, +TypeVariant::MyUnion, +TypeVariant::IntUnion, +TypeVariant::IntUnion2, ]; + pub const VARIANTS_STR: [&'static str; 6] = [ "SError", +"Multi", +"UnionKey", +"MyUnion", +"IntUnion", +"IntUnion2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError => "SError", +Self::Multi => "Multi", +Self::UnionKey => "UnionKey", +Self::MyUnion => "MyUnion", +Self::IntUnion => "IntUnion", +Self::IntUnion2 => "IntUnion2", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError => "SError", - Self::Multi => "Multi", - Self::UnionKey => "UnionKey", - Self::MyUnion => "MyUnion", - Self::IntUnion => "IntUnion", - Self::IntUnion2 => "IntUnion2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } -} -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "SError" => Ok(Self::SError), - "Multi" => Ok(Self::Multi), - "UnionKey" => Ok(Self::UnionKey), - "MyUnion" => Ok(Self::MyUnion), - "IntUnion" => Ok(Self::IntUnion), - "IntUnion2" => Ok(Self::IntUnion2), - _ => Err(Error::Invalid), + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "SError" => Ok(Self::SError), +"Multi" => Ok(Self::Multi), +"UnionKey" => Ok(Self::UnionKey), +"MyUnion" => Ok(Self::MyUnion), +"IntUnion" => Ok(Self::IntUnion), +"IntUnion2" => Ok(Self::IntUnion2), + _ => Err(Error::Invalid), + } + } } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - SError(Box), - Multi(Box), - UnionKey(Box), - MyUnion(Box), - IntUnion(Box), - IntUnion2(Box), -} - -impl Type { - pub const VARIANTS: [TypeVariant; 6] = [ - TypeVariant::SError, - TypeVariant::Multi, - TypeVariant::UnionKey, - TypeVariant::MyUnion, - TypeVariant::IntUnion, - TypeVariant::IntUnion2, - ]; - pub const VARIANTS_STR: [&'static str; 6] = [ - "SError", - "Multi", - "UnionKey", - "MyUnion", - "IntUnion", - "IntUnion2", - ]; + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + SError(Box), +Multi(Box), +UnionKey(Box), +MyUnion(Box), +IntUnion(Box), +IntUnion2(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, +TypeVariant::Multi, +TypeVariant::UnionKey, +TypeVariant::MyUnion, +TypeVariant::IntUnion, +TypeVariant::IntUnion2, ]; + pub const VARIANTS_STR: [&'static str; 6] = [ "SError", +"Multi", +"UnionKey", +"MyUnion", +"IntUnion", +"IntUnion2", ]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::SError => { - r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))) - } - TypeVariant::Multi => { - r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))) - } - TypeVariant::UnionKey => { - r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::SError => r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))), +TypeVariant::Multi => r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))), +TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), +TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), +TypeVariant::IntUnion => r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))), +TypeVariant::IntUnion2 => r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))), + } } - TypeVariant::MyUnion => { - r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::IntUnion => { - r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - TypeVariant::IntUnion2 => { - r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t.0))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t.0))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t.0))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new( - ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::SError(Box::new(t)))), - ), - TypeVariant::Multi => Box::new( - ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Multi(Box::new(t)))), - ), - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::IntUnion => Box::new( - ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), - ), - TypeVariant::IntUnion2 => Box::new( - ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::SError(Box::new(t.0)))), - ), - TypeVariant::Multi => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Multi(Box::new(t.0)))), - ), - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), - ), - TypeVariant::IntUnion => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion(Box::new(t.0)))), - ), - TypeVariant::IntUnion2 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::SError => Box::new( - ReadXdrIter::<_, SError>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::SError(Box::new(t)))), - ), - TypeVariant::Multi => Box::new( - ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Multi(Box::new(t)))), - ), - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::IntUnion => Box::new( - ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), - ), - TypeVariant::IntUnion2 => Box::new( - ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), - ), - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), +TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::SError(ref v) => v.as_ref(), +Self::Multi(ref v) => v.as_ref(), +Self::UnionKey(ref v) => v.as_ref(), +Self::MyUnion(ref v) => v.as_ref(), +Self::IntUnion(ref v) => v.as_ref(), +Self::IntUnion2(ref v) => v.as_ref(), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError(_) => "SError", +Self::Multi(_) => "Multi", +Self::UnionKey(_) => "UnionKey", +Self::MyUnion(_) => "MyUnion", +Self::IntUnion(_) => "IntUnion", +Self::IntUnion2(_) => "IntUnion2", + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), - TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), - TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), - TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), - TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::SError(ref v) => v.as_ref(), - Self::Multi(ref v) => v.as_ref(), - Self::UnionKey(ref v) => v.as_ref(), - Self::MyUnion(ref v) => v.as_ref(), - Self::IntUnion(ref v) => v.as_ref(), - Self::IntUnion2(ref v) => v.as_ref(), + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::SError(_) => TypeVariant::SError, +Self::Multi(_) => TypeVariant::Multi, +Self::UnionKey(_) => TypeVariant::UnionKey, +Self::MyUnion(_) => TypeVariant::MyUnion, +Self::IntUnion(_) => TypeVariant::IntUnion, +Self::IntUnion2(_) => TypeVariant::IntUnion2, + } + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError(_) => "SError", - Self::Multi(_) => "Multi", - Self::UnionKey(_) => "UnionKey", - Self::MyUnion(_) => "MyUnion", - Self::IntUnion(_) => "IntUnion", - Self::IntUnion2(_) => "IntUnion2", + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::SError(_) => TypeVariant::SError, - Self::Multi(_) => TypeVariant::Multi, - Self::UnionKey(_) => TypeVariant::UnionKey, - Self::MyUnion(_) => TypeVariant::MyUnion, - Self::IntUnion(_) => TypeVariant::IntUnion, - Self::IntUnion2(_) => TypeVariant::IntUnion2, + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::SError(v) => v.write_xdr(w), - Self::Multi(v) => v.write_xdr(w), - Self::UnionKey(v) => v.write_xdr(w), - Self::MyUnion(v) => v.write_xdr(w), - Self::IntUnion(v) => v.write_xdr(w), - Self::IntUnion2(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::SError(v) => v.write_xdr(w), +Self::Multi(v) => v.write_xdr(w), +Self::UnionKey(v) => v.write_xdr(w), +Self::MyUnion(v) => v.write_xdr(w), +Self::IntUnion(v) => v.write_xdr(w), +Self::IntUnion2(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index 66aaeab58..b5de5241a 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/block_comments.x", - "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/block_comments.x", "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2735,28 +2816,16 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum AccountFlags { - AuthRequiredFlag = 1, + AuthRequiredFlag = 1, } impl AccountFlags { - pub const VARIANTS: [AccountFlags; 1] = [AccountFlags::AuthRequiredFlag]; - pub const VARIANTS_STR: [&'static str; 1] = ["AuthRequiredFlag"]; + pub const VARIANTS: [AccountFlags; 1] = [ AccountFlags::AuthRequiredFlag, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AuthRequiredFlag", ]; #[must_use] pub const fn name(&self) -> &'static str { @@ -2835,26 +2904,18 @@ impl WriteXdr for AccountFlags { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") )] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum TypeVariant { AccountFlags, } impl TypeVariant { - pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; - pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; + pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; #[must_use] #[allow(clippy::too_many_lines)] @@ -2897,44 +2958,31 @@ impl core::str::FromStr for TypeVariant { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), )] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum Type { AccountFlags(Box), } impl Type { - pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; - pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; + pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { match v { - TypeVariant::AccountFlags => r.with_limited_depth(|r| { - Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?))) - }), + TypeVariant::AccountFlags => r.with_limited_depth(|r| Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?)))), } } #[cfg(feature = "base64")] pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); let t = Self::read_xdr(v, &mut dec)?; Ok(t) } @@ -2953,54 +3001,33 @@ impl Type { #[cfg(feature = "base64")] pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new( - ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), - ), + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), } } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0)))), - ), + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0))))), } } #[cfg(feature = "base64")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); match v { - TypeVariant::AccountFlags => Box::new( - ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), - ), + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), } } @@ -3014,10 +3041,7 @@ impl Type { #[cfg(feature = "base64")] pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } @@ -3026,9 +3050,7 @@ impl Type { #[allow(clippy::too_many_lines)] pub fn read_json(v: TypeVariant, r: impl Read) -> Result { match v { - TypeVariant::AccountFlags => { - Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))) - } + TypeVariant::AccountFlags => Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))), } } diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index b3a737966..ed83d1639 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/const.x", - "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/const.x", "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2745,281 +2826,229 @@ pub type TestArray = [i32; Foo]; /// typedef int TestArray2; /// ``` /// -pub type TestArray2 = VecM; - -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - TestArray, - TestArray2, -} +pub type TestArray2 = VecM::; + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + TestArray, +TestArray2, + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; - pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, +TypeVariant::TestArray2, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", +"TestArray2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray => "TestArray", +Self::TestArray2 => "TestArray2", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray => "TestArray", - Self::TestArray2 => "TestArray2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "TestArray" => Ok(Self::TestArray), +"TestArray2" => Ok(Self::TestArray2), + _ => Err(Error::Invalid), + } + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "TestArray" => Ok(Self::TestArray), - "TestArray2" => Ok(Self::TestArray2), - _ => Err(Error::Invalid), + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + TestArray(Box), +TestArray2(Box), } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - TestArray(Box), - TestArray2(Box), -} + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, +TypeVariant::TestArray2, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", +"TestArray2", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; - pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::TestArray => r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))), +TypeVariant::TestArray2 => r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::TestArray => { - r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::TestArray2 => { - r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t.0))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t.0))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new( - ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), - ), - TypeVariant::TestArray2 => Box::new( - ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray(Box::new(t.0)))), - ), - TypeVariant::TestArray2 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray2(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::TestArray => Box::new( - ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), - ), - TypeVariant::TestArray2 => Box::new( - ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), +TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::TestArray(ref v) => v.as_ref(), +Self::TestArray2(ref v) => v.as_ref(), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), - TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray(_) => "TestArray", +Self::TestArray2(_) => "TestArray2", + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::TestArray(ref v) => v.as_ref(), - Self::TestArray2(ref v) => v.as_ref(), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray(_) => "TestArray", - Self::TestArray2(_) => "TestArray2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::TestArray(_) => TypeVariant::TestArray, +Self::TestArray2(_) => TypeVariant::TestArray2, + } + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::TestArray(_) => TypeVariant::TestArray, - Self::TestArray2(_) => TypeVariant::TestArray2, + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::TestArray(v) => v.write_xdr(w), - Self::TestArray2(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::TestArray(v) => v.write_xdr(w), +Self::TestArray2(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index 5311dbe7b..a3e12de51 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/enum.x", - "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/enum.x", "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2731,19 +2812,19 @@ mod test { /// ERROR_MSG, /// HELLO, /// DONT_HAVE, -/// +/// /// GET_PEERS, // gets a list of peers this guy knows about /// PEERS, -/// +/// /// GET_TX_SET, // gets a particular txset by hash /// TX_SET, -/// +/// /// GET_VALIDATIONS, // gets validations for a given ledger hash /// VALIDATIONS, -/// +/// /// TRANSACTION, //pass on a tx you have heard about /// JSON_TRANSACTION, -/// +/// /// // FBA /// GET_FBA_QUORUMSET, /// FBA_QUORUMSET, @@ -2754,172 +2835,156 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum MessageType { - ErrorMsg = 0, - Hello = 1, - DontHave = 2, - GetPeers = 3, - Peers = 4, - GetTxSet = 5, - TxSet = 6, - GetValidations = 7, - Validations = 8, - Transaction = 9, - JsonTransaction = 10, - GetFbaQuorumset = 11, - FbaQuorumset = 12, - FbaMessage = 13, -} - -impl MessageType { - pub const VARIANTS: [MessageType; 14] = [ - MessageType::ErrorMsg, - MessageType::Hello, - MessageType::DontHave, - MessageType::GetPeers, - MessageType::Peers, - MessageType::GetTxSet, - MessageType::TxSet, - MessageType::GetValidations, - MessageType::Validations, - MessageType::Transaction, - MessageType::JsonTransaction, - MessageType::GetFbaQuorumset, - MessageType::FbaQuorumset, - MessageType::FbaMessage, - ]; - pub const VARIANTS_STR: [&'static str; 14] = [ - "ErrorMsg", - "Hello", - "DontHave", - "GetPeers", - "Peers", - "GetTxSet", - "TxSet", - "GetValidations", - "Validations", - "Transaction", - "JsonTransaction", - "GetFbaQuorumset", - "FbaQuorumset", - "FbaMessage", - ]; + ErrorMsg = 0, + Hello = 1, + DontHave = 2, + GetPeers = 3, + Peers = 4, + GetTxSet = 5, + TxSet = 6, + GetValidations = 7, + Validations = 8, + Transaction = 9, + JsonTransaction = 10, + GetFbaQuorumset = 11, + FbaQuorumset = 12, + FbaMessage = 13, +} + + impl MessageType { + pub const VARIANTS: [MessageType; 14] = [ MessageType::ErrorMsg, +MessageType::Hello, +MessageType::DontHave, +MessageType::GetPeers, +MessageType::Peers, +MessageType::GetTxSet, +MessageType::TxSet, +MessageType::GetValidations, +MessageType::Validations, +MessageType::Transaction, +MessageType::JsonTransaction, +MessageType::GetFbaQuorumset, +MessageType::FbaQuorumset, +MessageType::FbaMessage, ]; + pub const VARIANTS_STR: [&'static str; 14] = [ "ErrorMsg", +"Hello", +"DontHave", +"GetPeers", +"Peers", +"GetTxSet", +"TxSet", +"GetValidations", +"Validations", +"Transaction", +"JsonTransaction", +"GetFbaQuorumset", +"FbaQuorumset", +"FbaMessage", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::ErrorMsg => "ErrorMsg", +Self::Hello => "Hello", +Self::DontHave => "DontHave", +Self::GetPeers => "GetPeers", +Self::Peers => "Peers", +Self::GetTxSet => "GetTxSet", +Self::TxSet => "TxSet", +Self::GetValidations => "GetValidations", +Self::Validations => "Validations", +Self::Transaction => "Transaction", +Self::JsonTransaction => "JsonTransaction", +Self::GetFbaQuorumset => "GetFbaQuorumset", +Self::FbaQuorumset => "FbaQuorumset", +Self::FbaMessage => "FbaMessage", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::ErrorMsg => "ErrorMsg", - Self::Hello => "Hello", - Self::DontHave => "DontHave", - Self::GetPeers => "GetPeers", - Self::Peers => "Peers", - Self::GetTxSet => "GetTxSet", - Self::TxSet => "TxSet", - Self::GetValidations => "GetValidations", - Self::Validations => "Validations", - Self::Transaction => "Transaction", - Self::JsonTransaction => "JsonTransaction", - Self::GetFbaQuorumset => "GetFbaQuorumset", - Self::FbaQuorumset => "FbaQuorumset", - Self::FbaMessage => "FbaMessage", + #[must_use] + pub const fn variants() -> [MessageType; 14] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn variants() -> [MessageType; 14] { - Self::VARIANTS - } -} - -impl Name for MessageType { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for MessageType { - fn variants() -> slice::Iter<'static, MessageType> { - Self::VARIANTS.iter() - } -} + impl Name for MessageType { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Enum for MessageType {} + impl Variants for MessageType { + fn variants() -> slice::Iter<'static, MessageType> { + Self::VARIANTS.iter() + } + } -impl fmt::Display for MessageType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl Enum for MessageType {} -impl TryFrom for MessageType { - type Error = Error; + impl fmt::Display for MessageType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } - fn try_from(i: i32) -> Result { - let e = match i { - 0 => MessageType::ErrorMsg, - 1 => MessageType::Hello, - 2 => MessageType::DontHave, - 3 => MessageType::GetPeers, - 4 => MessageType::Peers, - 5 => MessageType::GetTxSet, - 6 => MessageType::TxSet, - 7 => MessageType::GetValidations, - 8 => MessageType::Validations, - 9 => MessageType::Transaction, - 10 => MessageType::JsonTransaction, - 11 => MessageType::GetFbaQuorumset, - 12 => MessageType::FbaQuorumset, - 13 => MessageType::FbaMessage, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + impl TryFrom for MessageType { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 0 => MessageType::ErrorMsg, +1 => MessageType::Hello, +2 => MessageType::DontHave, +3 => MessageType::GetPeers, +4 => MessageType::Peers, +5 => MessageType::GetTxSet, +6 => MessageType::TxSet, +7 => MessageType::GetValidations, +8 => MessageType::Validations, +9 => MessageType::Transaction, +10 => MessageType::JsonTransaction, +11 => MessageType::GetFbaQuorumset, +12 => MessageType::FbaQuorumset, +13 => MessageType::FbaMessage, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: MessageType) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: MessageType) -> Self { + e as Self + } + } -impl ReadXdr for MessageType { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for MessageType { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for MessageType { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for MessageType { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// Color is an XDR Enum defines as: /// @@ -2934,109 +2999,101 @@ impl WriteXdr for MessageType { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { - Red = 0, - Green = 1, - Blue = 2, -} - -impl Color { - pub const VARIANTS: [Color; 3] = [Color::Red, Color::Green, Color::Blue]; - pub const VARIANTS_STR: [&'static str; 3] = ["Red", "Green", "Blue"]; + Red = 0, + Green = 1, + Blue = 2, +} + + impl Color { + pub const VARIANTS: [Color; 3] = [ Color::Red, +Color::Green, +Color::Blue, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "Red", +"Green", +"Blue", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red => "Red", +Self::Green => "Green", +Self::Blue => "Blue", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red => "Red", - Self::Green => "Green", - Self::Blue => "Blue", + #[must_use] + pub const fn variants() -> [Color; 3] { + Self::VARIANTS + } } - } - - #[must_use] - pub const fn variants() -> [Color; 3] { - Self::VARIANTS - } -} -impl Name for Color { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for Color { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for Color { - fn variants() -> slice::Iter<'static, Color> { - Self::VARIANTS.iter() - } -} + impl Variants for Color { + fn variants() -> slice::Iter<'static, Color> { + Self::VARIANTS.iter() + } + } -impl Enum for Color {} + impl Enum for Color {} -impl fmt::Display for Color { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl fmt::Display for Color { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } -impl TryFrom for Color { - type Error = Error; + impl TryFrom for Color { + type Error = Error; - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color::Red, - 1 => Color::Green, - 2 => Color::Blue, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color::Red, +1 => Color::Green, +2 => Color::Blue, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: Color) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: Color) -> Self { + e as Self + } + } -impl ReadXdr for Color { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for Color { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for Color { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for Color { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// Color2 is an XDR Enum defines as: /// @@ -3051,408 +3108,339 @@ impl WriteXdr for Color { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum Color2 { - Red2 = 0, - Green2 = 1, - Blue2 = 2, -} - -impl Color2 { - pub const VARIANTS: [Color2; 3] = [Color2::Red2, Color2::Green2, Color2::Blue2]; - pub const VARIANTS_STR: [&'static str; 3] = ["Red2", "Green2", "Blue2"]; + Red2 = 0, + Green2 = 1, + Blue2 = 2, +} + + impl Color2 { + pub const VARIANTS: [Color2; 3] = [ Color2::Red2, +Color2::Green2, +Color2::Blue2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "Red2", +"Green2", +"Blue2", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red2 => "Red2", +Self::Green2 => "Green2", +Self::Blue2 => "Blue2", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red2 => "Red2", - Self::Green2 => "Green2", - Self::Blue2 => "Blue2", + #[must_use] + pub const fn variants() -> [Color2; 3] { + Self::VARIANTS + } } - } - - #[must_use] - pub const fn variants() -> [Color2; 3] { - Self::VARIANTS - } -} -impl Name for Color2 { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for Color2 { - fn variants() -> slice::Iter<'static, Color2> { - Self::VARIANTS.iter() - } -} + impl Name for Color2 { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Enum for Color2 {} + impl Variants for Color2 { + fn variants() -> slice::Iter<'static, Color2> { + Self::VARIANTS.iter() + } + } -impl fmt::Display for Color2 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl Enum for Color2 {} -impl TryFrom for Color2 { - type Error = Error; + impl fmt::Display for Color2 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color2::Red2, - 1 => Color2::Green2, - 2 => Color2::Blue2, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + impl TryFrom for Color2 { + type Error = Error; -impl From for i32 { - #[must_use] - fn from(e: Color2) -> Self { - e as Self - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color2::Red2, +1 => Color2::Green2, +2 => Color2::Blue2, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl ReadXdr for Color2 { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl From for i32 { + #[must_use] + fn from(e: Color2) -> Self { + e as Self + } + } -impl WriteXdr for Color2 { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl ReadXdr for Color2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - MessageType, - Color, - Color2, -} + impl WriteXdr for Color2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 3] = [ - TypeVariant::MessageType, - TypeVariant::Color, - TypeVariant::Color2, - ]; - pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + MessageType, +Color, +Color2, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, +TypeVariant::Color, +TypeVariant::Color2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", +"Color", +"Color2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType => "MessageType", +Self::Color => "Color", +Self::Color2 => "Color2", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType => "MessageType", - Self::Color => "Color", - Self::Color2 => "Color2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS - } -} -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "MessageType" => Ok(Self::MessageType), - "Color" => Ok(Self::Color), - "Color2" => Ok(Self::Color2), - _ => Err(Error::Invalid), + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "MessageType" => Ok(Self::MessageType), +"Color" => Ok(Self::Color), +"Color2" => Ok(Self::Color2), + _ => Err(Error::Invalid), + } + } } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - MessageType(Box), - Color(Box), - Color2(Box), -} + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + MessageType(Box), +Color(Box), +Color2(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, +TypeVariant::Color, +TypeVariant::Color2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", +"Color", +"Color2", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 3] = [ - TypeVariant::MessageType, - TypeVariant::Color, - TypeVariant::Color2, - ]; - pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::MessageType => r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))), +TypeVariant::Color => r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))), +TypeVariant::Color2 => r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::MessageType => { - r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::Color => { - r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - TypeVariant::Color2 => { - r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t.0))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t.0))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t.0))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new( - ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), - ), - TypeVariant::Color => Box::new( - ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color(Box::new(t)))), - ), - TypeVariant::Color2 => Box::new( - ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color2(Box::new(t)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MessageType(Box::new(t.0)))), - ), - TypeVariant::Color => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color(Box::new(t.0)))), - ), - TypeVariant::Color2 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color2(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::MessageType => Box::new( - ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), - ), - TypeVariant::Color => Box::new( - ReadXdrIter::<_, Color>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Color(Box::new(t)))), - ), - TypeVariant::Color2 => Box::new( - ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Color2(Box::new(t)))), - ), - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::MessageType => Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::MessageType(ref v) => v.as_ref(), +Self::Color(ref v) => v.as_ref(), +Self::Color2(ref v) => v.as_ref(), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType(_) => "MessageType", +Self::Color(_) => "Color", +Self::Color2(_) => "Color2", + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::MessageType => { - Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))) + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS } - TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), - TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), - } - } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::MessageType(ref v) => v.as_ref(), - Self::Color(ref v) => v.as_ref(), - Self::Color2(ref v) => v.as_ref(), + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::MessageType(_) => TypeVariant::MessageType, +Self::Color(_) => TypeVariant::Color, +Self::Color2(_) => TypeVariant::Color2, + } + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType(_) => "MessageType", - Self::Color(_) => "Color", - Self::Color2(_) => "Color2", + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::MessageType(_) => TypeVariant::MessageType, - Self::Color(_) => TypeVariant::Color, - Self::Color2(_) => TypeVariant::Color2, + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::MessageType(v) => v.write_xdr(w), - Self::Color(v) => v.write_xdr(w), - Self::Color2(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::MessageType(v) => v.write_xdr(w), +Self::Color(v) => v.write_xdr(w), +Self::Color2(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index da9eab925..4ee0a2ef2 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/nesting.x", - "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/nesting.x", "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2736,100 +2817,100 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum UnionKey { - One = 1, - Two = 2, - Offer = 3, -} - -impl UnionKey { - pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; - pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; + One = 1, + Two = 2, + Offer = 3, +} + + impl UnionKey { + pub const VARIANTS: [UnionKey; 3] = [ UnionKey::One, +UnionKey::Two, +UnionKey::Offer, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "One", +"Two", +"Offer", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One => "One", +Self::Two => "Two", +Self::Offer => "Offer", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One => "One", - Self::Two => "Two", - Self::Offer => "Offer", + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } -} -impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Enum for UnionKey {} + impl Enum for UnionKey {} -impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } -impl TryFrom for UnionKey { - type Error = Error; + impl TryFrom for UnionKey { + type Error = Error; - fn try_from(i: i32) -> Result { - let e = match i { - 1 => UnionKey::One, - 2 => UnionKey::Two, - 3 => UnionKey::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 1 => UnionKey::One, +2 => UnionKey::Two, +3 => UnionKey::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } + } -impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// Foo is an XDR Typedef defines as: /// @@ -2849,30 +2930,18 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyUnionOne { - pub some_int: i32, + pub some_int: i32, } impl ReadXdr for MyUnionOne { #[cfg(feature = "std")] fn read_xdr(r: &mut Limited) -> Result { r.with_limited_depth(|r| { - Ok(Self { - some_int: i32::read_xdr(r)?, + Ok(Self{ + some_int: i32::read_xdr(r)?, }) }) } @@ -2899,47 +2968,35 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyUnionTwo { - pub some_int: i32, - pub foo: i32, + pub some_int: i32, + pub foo: i32, } -impl ReadXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self { - some_int: i32::read_xdr(r)?, - foo: i32::read_xdr(r)?, - }) - }) - } -} + impl ReadXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + some_int: i32::read_xdr(r)?, +foo: i32::read_xdr(r)?, + }) + }) + } + } -impl WriteXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; - self.foo.write_xdr(w)?; - Ok(()) - }) - } -} + impl WriteXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; +self.foo.write_xdr(w)?; + Ok(()) + }) + } + } /// MyUnion is an XDR Union defines as: /// @@ -2950,13 +3007,13 @@ impl WriteXdr for MyUnionTwo { /// struct { /// int someInt; /// } one; -/// +/// /// case TWO: /// struct { /// int someInt; /// Foo foo; /// } two; -/// +/// /// case OFFER: /// void; /// }; @@ -2965,462 +3022,379 @@ impl WriteXdr for MyUnionTwo { // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - One(MyUnionOne), - Two(MyUnionTwo), - Offer, -} + One(MyUnionOne), + Two(MyUnionTwo), + Offer, +} + + impl MyUnion { + pub const VARIANTS: [UnionKey; 3] = [ + UnionKey::One, +UnionKey::Two, +UnionKey::Offer, + ]; + pub const VARIANTS_STR: [&'static str; 3] = [ + "One", +"Two", +"Offer", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One(_) => "One", +Self::Two(_) => "Two", +Self::Offer => "Offer", + } + } -impl MyUnion { - pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; - pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::One(_) => UnionKey::One, +Self::Two(_) => UnionKey::Two, +Self::Offer => UnionKey::Offer, + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One(_) => "One", - Self::Two(_) => "Two", - Self::Offer => "Offer", + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::One(_) => UnionKey::One, - Self::Two(_) => UnionKey::Two, - Self::Offer => UnionKey::Offer, + impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } -} -impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } -} + impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } + } -impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Union for MyUnion {} + impl Union for MyUnion {} -impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), - UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), - UnionKey::Offer => Self::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } -} + impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), +UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), +UnionKey::Offer => Self::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } -impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::One(v) => v.write_xdr(w)?, - Self::Two(v) => v.write_xdr(w)?, - Self::Offer => ().write_xdr(w)?, - }; - Ok(()) - }) - } -} + impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::One(v) => v.write_xdr(w)?, +Self::Two(v) => v.write_xdr(w)?, +Self::Offer => ().write_xdr(w)?, + }; + Ok(()) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - UnionKey, - Foo, - MyUnion, - MyUnionOne, - MyUnionTwo, -} - -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 5] = [ - TypeVariant::UnionKey, - TypeVariant::Foo, - TypeVariant::MyUnion, - TypeVariant::MyUnionOne, - TypeVariant::MyUnionTwo, - ]; - pub const VARIANTS_STR: [&'static str; 5] = - ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + UnionKey, +Foo, +MyUnion, +MyUnionOne, +MyUnionTwo, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, +TypeVariant::Foo, +TypeVariant::MyUnion, +TypeVariant::MyUnionOne, +TypeVariant::MyUnionTwo, ]; + pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", +"Foo", +"MyUnion", +"MyUnionOne", +"MyUnionTwo", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey => "UnionKey", +Self::Foo => "Foo", +Self::MyUnion => "MyUnion", +Self::MyUnionOne => "MyUnionOne", +Self::MyUnionTwo => "MyUnionTwo", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey => "UnionKey", - Self::Foo => "Foo", - Self::MyUnion => "MyUnion", - Self::MyUnionOne => "MyUnionOne", - Self::MyUnionTwo => "MyUnionTwo", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } -} - -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "UnionKey" => Ok(Self::UnionKey), - "Foo" => Ok(Self::Foo), - "MyUnion" => Ok(Self::MyUnion), - "MyUnionOne" => Ok(Self::MyUnionOne), - "MyUnionTwo" => Ok(Self::MyUnionTwo), - _ => Err(Error::Invalid), + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "UnionKey" => Ok(Self::UnionKey), +"Foo" => Ok(Self::Foo), +"MyUnion" => Ok(Self::MyUnion), +"MyUnionOne" => Ok(Self::MyUnionOne), +"MyUnionTwo" => Ok(Self::MyUnionTwo), + _ => Err(Error::Invalid), + } + } } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - UnionKey(Box), - Foo(Box), - MyUnion(Box), - MyUnionOne(Box), - MyUnionTwo(Box), -} - -impl Type { - pub const VARIANTS: [TypeVariant; 5] = [ - TypeVariant::UnionKey, - TypeVariant::Foo, - TypeVariant::MyUnion, - TypeVariant::MyUnionOne, - TypeVariant::MyUnionTwo, - ]; - pub const VARIANTS_STR: [&'static str; 5] = - ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + UnionKey(Box), +Foo(Box), +MyUnion(Box), +MyUnionOne(Box), +MyUnionTwo(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, +TypeVariant::Foo, +TypeVariant::MyUnion, +TypeVariant::MyUnionOne, +TypeVariant::MyUnionTwo, ]; + pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", +"Foo", +"MyUnion", +"MyUnionOne", +"MyUnionTwo", ]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::UnionKey => { - r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) - } - TypeVariant::Foo => { - r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))) + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), +TypeVariant::Foo => r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))), +TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), +TypeVariant::MyUnionOne => r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))), +TypeVariant::MyUnionTwo => r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))), + } } - TypeVariant::MyUnion => { - r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::MyUnionOne => { - r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - TypeVariant::MyUnionTwo => { - r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), + } + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t.0))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::Foo => Box::new( - ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Foo(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::MyUnionOne => Box::new( - ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), - ), - TypeVariant::MyUnionTwo => Box::new( - ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), - ), - TypeVariant::Foo => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Foo(Box::new(t.0)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), - ), - TypeVariant::MyUnionOne => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0)))), - ), - TypeVariant::MyUnionTwo => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::Foo => Box::new( - ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Foo(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::MyUnionOne => Box::new( - ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), - ), - TypeVariant::MyUnionTwo => Box::new( - ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), - ), - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::UnionKey(ref v) => v.as_ref(), +Self::Foo(ref v) => v.as_ref(), +Self::MyUnion(ref v) => v.as_ref(), +Self::MyUnionOne(ref v) => v.as_ref(), +Self::MyUnionTwo(ref v) => v.as_ref(), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey(_) => "UnionKey", +Self::Foo(_) => "Foo", +Self::MyUnion(_) => "MyUnion", +Self::MyUnionOne(_) => "MyUnionOne", +Self::MyUnionTwo(_) => "MyUnionTwo", + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), - TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::UnionKey(ref v) => v.as_ref(), - Self::Foo(ref v) => v.as_ref(), - Self::MyUnion(ref v) => v.as_ref(), - Self::MyUnionOne(ref v) => v.as_ref(), - Self::MyUnionTwo(ref v) => v.as_ref(), + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::UnionKey(_) => TypeVariant::UnionKey, +Self::Foo(_) => TypeVariant::Foo, +Self::MyUnion(_) => TypeVariant::MyUnion, +Self::MyUnionOne(_) => TypeVariant::MyUnionOne, +Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, + } + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey(_) => "UnionKey", - Self::Foo(_) => "Foo", - Self::MyUnion(_) => "MyUnion", - Self::MyUnionOne(_) => "MyUnionOne", - Self::MyUnionTwo(_) => "MyUnionTwo", + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::UnionKey(_) => TypeVariant::UnionKey, - Self::Foo(_) => TypeVariant::Foo, - Self::MyUnion(_) => TypeVariant::MyUnion, - Self::MyUnionOne(_) => TypeVariant::MyUnionOne, - Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} - -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::UnionKey(v) => v.write_xdr(w), - Self::Foo(v) => v.write_xdr(w), - Self::MyUnion(v) => v.write_xdr(w), - Self::MyUnionOne(v) => v.write_xdr(w), - Self::MyUnionTwo(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::UnionKey(v) => v.write_xdr(w), +Self::Foo(v) => v.write_xdr(w), +Self::MyUnion(v) => v.write_xdr(w), +Self::MyUnionOne(v) => v.write_xdr(w), +Self::MyUnionTwo(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index 727848396..3e1fc448d 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/optional.x", - "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/optional.x", "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2744,315 +2825,259 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] pub struct HasOptions { - pub first_option: Option, - pub second_option: Option, - pub third_option: Option, + pub first_option: Option, + pub second_option: Option, + pub third_option: Option, } -impl ReadXdr for HasOptions { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self { - first_option: Option::::read_xdr(r)?, - second_option: Option::::read_xdr(r)?, - third_option: Option::::read_xdr(r)?, - }) - }) - } -} + impl ReadXdr for HasOptions { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + first_option: Option::::read_xdr(r)?, +second_option: Option::::read_xdr(r)?, +third_option: Option::::read_xdr(r)?, + }) + }) + } + } -impl WriteXdr for HasOptions { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.first_option.write_xdr(w)?; - self.second_option.write_xdr(w)?; - self.third_option.write_xdr(w)?; - Ok(()) - }) - } -} + impl WriteXdr for HasOptions { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.first_option.write_xdr(w)?; +self.second_option.write_xdr(w)?; +self.third_option.write_xdr(w)?; + Ok(()) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - Arr, - HasOptions, -} + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + Arr, +HasOptions, + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; - pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, +TypeVariant::HasOptions, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", +"HasOptions", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr => "Arr", +Self::HasOptions => "HasOptions", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr => "Arr", - Self::HasOptions => "HasOptions", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Arr" => Ok(Self::Arr), +"HasOptions" => Ok(Self::HasOptions), + _ => Err(Error::Invalid), + } + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Arr" => Ok(Self::Arr), - "HasOptions" => Ok(Self::HasOptions), - _ => Err(Error::Invalid), + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + Arr(Box), +HasOptions(Box), } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - Arr(Box), - HasOptions(Box), -} + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, +TypeVariant::HasOptions, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", +"HasOptions", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; - pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Arr => r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))), +TypeVariant::HasOptions => r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Arr => { - r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::HasOptions => { - r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t.0))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t.0))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new( - ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Arr(Box::new(t)))), - ), - TypeVariant::HasOptions => Box::new( - ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Arr(Box::new(t.0)))), - ), - TypeVariant::HasOptions => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::HasOptions(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Arr => Box::new( - ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Arr(Box::new(t)))), - ), - TypeVariant::HasOptions => Box::new( - ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), +TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Arr(ref v) => v.as_ref(), +Self::HasOptions(ref v) => v.as_ref(), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), - TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr(_) => "Arr", +Self::HasOptions(_) => "HasOptions", + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Arr(ref v) => v.as_ref(), - Self::HasOptions(ref v) => v.as_ref(), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr(_) => "Arr", - Self::HasOptions(_) => "HasOptions", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Arr(_) => TypeVariant::Arr, +Self::HasOptions(_) => TypeVariant::HasOptions, + } + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Arr(_) => TypeVariant::Arr, - Self::HasOptions(_) => TypeVariant::HasOptions, + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Arr(v) => v.write_xdr(w), - Self::HasOptions(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Arr(v) => v.write_xdr(w), +Self::HasOptions(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index f7e9fd9ba..734f1a959 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/struct.x", - "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/struct.x", "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2746,321 +2827,265 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] pub struct MyStruct { - pub some_int: i32, - pub a_big_int: i64, - pub some_opaque: [u8; 10], - pub some_string: StringM, - pub max_string: StringM<100>, + pub some_int: i32, + pub a_big_int: i64, + pub some_opaque: [u8; 10], + pub some_string: StringM, + pub max_string: StringM::<100>, } -impl ReadXdr for MyStruct { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self { - some_int: i32::read_xdr(r)?, - a_big_int: i64::read_xdr(r)?, - some_opaque: <[u8; 10]>::read_xdr(r)?, - some_string: StringM::read_xdr(r)?, - max_string: StringM::<100>::read_xdr(r)?, - }) - }) - } -} + impl ReadXdr for MyStruct { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + some_int: i32::read_xdr(r)?, +a_big_int: i64::read_xdr(r)?, +some_opaque: <[u8; 10]>::read_xdr(r)?, +some_string: StringM::read_xdr(r)?, +max_string: StringM::<100>::read_xdr(r)?, + }) + }) + } + } -impl WriteXdr for MyStruct { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; - self.a_big_int.write_xdr(w)?; - self.some_opaque.write_xdr(w)?; - self.some_string.write_xdr(w)?; - self.max_string.write_xdr(w)?; - Ok(()) - }) - } -} + impl WriteXdr for MyStruct { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; +self.a_big_int.write_xdr(w)?; +self.some_opaque.write_xdr(w)?; +self.some_string.write_xdr(w)?; +self.max_string.write_xdr(w)?; + Ok(()) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - Int64, - MyStruct, -} + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + Int64, +MyStruct, + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; - pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, +TypeVariant::MyStruct, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", +"MyStruct", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64 => "Int64", +Self::MyStruct => "MyStruct", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64 => "Int64", - Self::MyStruct => "MyStruct", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Int64" => Ok(Self::Int64), +"MyStruct" => Ok(Self::MyStruct), + _ => Err(Error::Invalid), + } + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Int64" => Ok(Self::Int64), - "MyStruct" => Ok(Self::MyStruct), - _ => Err(Error::Invalid), + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + Int64(Box), +MyStruct(Box), } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - Int64(Box), - MyStruct(Box), -} + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, +TypeVariant::MyStruct, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", +"MyStruct", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; - pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Int64 => r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))), +TypeVariant::MyStruct => r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Int64 => { - r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::MyStruct => { - r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t.0))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t.0))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new( - ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Int64(Box::new(t)))), - ), - TypeVariant::MyStruct => Box::new( - ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Int64(Box::new(t.0)))), - ), - TypeVariant::MyStruct => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyStruct(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Int64 => Box::new( - ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Int64(Box::new(t)))), - ), - TypeVariant::MyStruct => Box::new( - ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Int64(ref v) => v.as_ref(), +Self::MyStruct(ref v) => v.as_ref(), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64(_) => "Int64", +Self::MyStruct(_) => "MyStruct", + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Int64(ref v) => v.as_ref(), - Self::MyStruct(ref v) => v.as_ref(), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64(_) => "Int64", - Self::MyStruct(_) => "MyStruct", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Int64(_) => TypeVariant::Int64, +Self::MyStruct(_) => TypeVariant::MyStruct, + } + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Int64(_) => TypeVariant::Int64, - Self::MyStruct(_) => TypeVariant::MyStruct, + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Int64(v) => v.write_xdr(w), - Self::MyStruct(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Int64(v) => v.write_xdr(w), +Self::MyStruct(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index 6bfd3f85b..8565c0653 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -874,7 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -899,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1282,7 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1335,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1664,7 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1724,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2036,11 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2065,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2730,6 +2844,36 @@ impl core::str::FromStr for Uint512 { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +impl schemars::JsonSchema for Uint512 { + fn schema_name() -> String { + "Uint512".to_string() + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: SOME(MAX * 2), + min_length: SOME(MAX * 2), + ..string + }) + } else { + schema_ + } + } +} impl From for [u8; 64] { #[must_use] fn from(x: Uint512) -> Self { @@ -3254,6 +3398,36 @@ impl core::str::FromStr for Hash { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +impl schemars::JsonSchema for Hash { + fn schema_name() -> String { + "Hash".to_string() + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: SOME(MAX * 2), + min_length: SOME(MAX * 2), + ..string + }) + } else { + schema_ + } + } +} impl From for [u8; 32] { #[must_use] fn from(x: Hash) -> Self { @@ -4325,7 +4499,7 @@ self.nested_union.write_xdr(w)?; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -4489,7 +4663,7 @@ Self::NesterNestedUnion => "NesterNestedUnion", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index d242b71ad..43fb37cc8 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/union.x", - "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/union.x", "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2751,97 +2832,95 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] #[repr(i32)] pub enum UnionKey { - Error = 0, - Multi = 1, + Error = 0, + Multi = 1, } -impl UnionKey { - pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; - pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; + impl UnionKey { + pub const VARIANTS: [UnionKey; 2] = [ UnionKey::Error, +UnionKey::Multi, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Error", +"Multi", ]; - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error => "Error", - Self::Multi => "Multi", - } - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error => "Error", +Self::Multi => "Multi", + } + } - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } -} + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } + } -impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Enum for UnionKey {} + impl Enum for UnionKey {} -impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } -impl TryFrom for UnionKey { - type Error = Error; + impl TryFrom for UnionKey { + type Error = Error; - fn try_from(i: i32) -> Result { - let e = match i { - 0 => UnionKey::Error, - 1 => UnionKey::Multi, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 0 => UnionKey::Error, +1 => UnionKey::Multi, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } + } -impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// MyUnion is an XDR Union defines as: /// @@ -2852,105 +2931,107 @@ impl WriteXdr for UnionKey { /// Error error; /// case MULTI: /// Multi things<>; -/// -/// +/// +/// /// }; /// ``` /// // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - Error(i32), - Multi(VecM), -} + Error(i32), + Multi(VecM::), +} + + impl MyUnion { + pub const VARIANTS: [UnionKey; 2] = [ + UnionKey::Error, +UnionKey::Multi, + ]; + pub const VARIANTS_STR: [&'static str; 2] = [ + "Error", +"Multi", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error(_) => "Error", +Self::Multi(_) => "Multi", + } + } -impl MyUnion { - pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; - pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::Error(_) => UnionKey::Error, +Self::Multi(_) => UnionKey::Multi, + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error(_) => "Error", - Self::Multi(_) => "Multi", + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::Error(_) => UnionKey::Error, - Self::Multi(_) => UnionKey::Multi, + impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } -} - -impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } -} + impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } + } -impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Union for MyUnion {} + impl Union for MyUnion {} -impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::Error => Self::Error(i32::read_xdr(r)?), - UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } -} + impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::Error => Self::Error(i32::read_xdr(r)?), +UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } -impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::Error(v) => v.write_xdr(w)?, - Self::Multi(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } -} + impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::Error(v) => v.write_xdr(w)?, +Self::Multi(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } + } /// IntUnion is an XDR Union defines as: /// @@ -2961,113 +3042,107 @@ impl WriteXdr for MyUnion { /// Error error; /// case 1: /// Multi things<>; -/// +/// /// }; /// ``` /// // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum IntUnion { - V0(i32), - V1(VecM), -} + V0(i32), + V1(VecM::), +} + + impl IntUnion { + pub const VARIANTS: [i32; 2] = [ + 0, +1, + ]; + pub const VARIANTS_STR: [&'static str; 2] = [ + "V0", +"V1", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::V0(_) => "V0", +Self::V1(_) => "V1", + } + } -impl IntUnion { - pub const VARIANTS: [i32; 2] = [0, 1]; - pub const VARIANTS_STR: [&'static str; 2] = ["V0", "V1"]; + #[must_use] + pub const fn discriminant(&self) -> i32 { + #[allow(clippy::match_same_arms)] + match self { + Self::V0(_) => 0, +Self::V1(_) => 1, + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::V0(_) => "V0", - Self::V1(_) => "V1", + #[must_use] + pub const fn variants() -> [i32; 2] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn discriminant(&self) -> i32 { - #[allow(clippy::match_same_arms)] - match self { - Self::V0(_) => 0, - Self::V1(_) => 1, + impl Name for IntUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - pub const fn variants() -> [i32; 2] { - Self::VARIANTS - } -} - -impl Name for IntUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Discriminant for IntUnion { - #[must_use] - fn discriminant(&self) -> i32 { - Self::discriminant(self) - } -} + impl Discriminant for IntUnion { + #[must_use] + fn discriminant(&self) -> i32 { + Self::discriminant(self) + } + } -impl Variants for IntUnion { - fn variants() -> slice::Iter<'static, i32> { - Self::VARIANTS.iter() - } -} + impl Variants for IntUnion { + fn variants() -> slice::Iter<'static, i32> { + Self::VARIANTS.iter() + } + } -impl Union for IntUnion {} + impl Union for IntUnion {} -impl ReadXdr for IntUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: i32 = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - 0 => Self::V0(i32::read_xdr(r)?), - 1 => Self::V1(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } -} + impl ReadXdr for IntUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: i32 = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + 0 => Self::V0(i32::read_xdr(r)?), +1 => Self::V1(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } -impl WriteXdr for IntUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::V0(v) => v.write_xdr(w)?, - Self::V1(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } -} + impl WriteXdr for IntUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::V0(v) => v.write_xdr(w)?, +Self::V1(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } + } /// IntUnion2 is an XDR Typedef defines as: /// @@ -3077,20 +3152,8 @@ impl WriteXdr for IntUnion { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3129,407 +3192,299 @@ impl ReadXdr for IntUnion2 { impl WriteXdr for IntUnion2 { #[cfg(feature = "std")] fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| self.0.write_xdr(w)) - } -} - -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - SError, - Multi, - UnionKey, - MyUnion, - IntUnion, - IntUnion2, -} - -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 6] = [ - TypeVariant::SError, - TypeVariant::Multi, - TypeVariant::UnionKey, - TypeVariant::MyUnion, - TypeVariant::IntUnion, - TypeVariant::IntUnion2, - ]; - pub const VARIANTS_STR: [&'static str; 6] = [ - "SError", - "Multi", - "UnionKey", - "MyUnion", - "IntUnion", - "IntUnion2", - ]; + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + SError, +Multi, +UnionKey, +MyUnion, +IntUnion, +IntUnion2, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, +TypeVariant::Multi, +TypeVariant::UnionKey, +TypeVariant::MyUnion, +TypeVariant::IntUnion, +TypeVariant::IntUnion2, ]; + pub const VARIANTS_STR: [&'static str; 6] = [ "SError", +"Multi", +"UnionKey", +"MyUnion", +"IntUnion", +"IntUnion2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError => "SError", +Self::Multi => "Multi", +Self::UnionKey => "UnionKey", +Self::MyUnion => "MyUnion", +Self::IntUnion => "IntUnion", +Self::IntUnion2 => "IntUnion2", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError => "SError", - Self::Multi => "Multi", - Self::UnionKey => "UnionKey", - Self::MyUnion => "MyUnion", - Self::IntUnion => "IntUnion", - Self::IntUnion2 => "IntUnion2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } -} - -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "SError" => Ok(Self::SError), - "Multi" => Ok(Self::Multi), - "UnionKey" => Ok(Self::UnionKey), - "MyUnion" => Ok(Self::MyUnion), - "IntUnion" => Ok(Self::IntUnion), - "IntUnion2" => Ok(Self::IntUnion2), - _ => Err(Error::Invalid), + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "SError" => Ok(Self::SError), +"Multi" => Ok(Self::Multi), +"UnionKey" => Ok(Self::UnionKey), +"MyUnion" => Ok(Self::MyUnion), +"IntUnion" => Ok(Self::IntUnion), +"IntUnion2" => Ok(Self::IntUnion2), + _ => Err(Error::Invalid), + } + } } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - SError(Box), - Multi(Box), - UnionKey(Box), - MyUnion(Box), - IntUnion(Box), - IntUnion2(Box), -} - -impl Type { - pub const VARIANTS: [TypeVariant; 6] = [ - TypeVariant::SError, - TypeVariant::Multi, - TypeVariant::UnionKey, - TypeVariant::MyUnion, - TypeVariant::IntUnion, - TypeVariant::IntUnion2, - ]; - pub const VARIANTS_STR: [&'static str; 6] = [ - "SError", - "Multi", - "UnionKey", - "MyUnion", - "IntUnion", - "IntUnion2", - ]; + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + SError(Box), +Multi(Box), +UnionKey(Box), +MyUnion(Box), +IntUnion(Box), +IntUnion2(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, +TypeVariant::Multi, +TypeVariant::UnionKey, +TypeVariant::MyUnion, +TypeVariant::IntUnion, +TypeVariant::IntUnion2, ]; + pub const VARIANTS_STR: [&'static str; 6] = [ "SError", +"Multi", +"UnionKey", +"MyUnion", +"IntUnion", +"IntUnion2", ]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::SError => { - r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))) - } - TypeVariant::Multi => { - r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))) - } - TypeVariant::UnionKey => { - r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::SError => r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))), +TypeVariant::Multi => r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))), +TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), +TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), +TypeVariant::IntUnion => r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))), +TypeVariant::IntUnion2 => r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))), + } } - TypeVariant::MyUnion => { - r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::IntUnion => { - r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - TypeVariant::IntUnion2 => { - r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t.0))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t.0))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t.0))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new( - ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::SError(Box::new(t)))), - ), - TypeVariant::Multi => Box::new( - ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Multi(Box::new(t)))), - ), - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::IntUnion => Box::new( - ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), - ), - TypeVariant::IntUnion2 => Box::new( - ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::SError(Box::new(t.0)))), - ), - TypeVariant::Multi => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Multi(Box::new(t.0)))), - ), - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), - ), - TypeVariant::IntUnion => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion(Box::new(t.0)))), - ), - TypeVariant::IntUnion2 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::SError => Box::new( - ReadXdrIter::<_, SError>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::SError(Box::new(t)))), - ), - TypeVariant::Multi => Box::new( - ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Multi(Box::new(t)))), - ), - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::IntUnion => Box::new( - ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), - ), - TypeVariant::IntUnion2 => Box::new( - ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), - ), - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), +TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::SError(ref v) => v.as_ref(), +Self::Multi(ref v) => v.as_ref(), +Self::UnionKey(ref v) => v.as_ref(), +Self::MyUnion(ref v) => v.as_ref(), +Self::IntUnion(ref v) => v.as_ref(), +Self::IntUnion2(ref v) => v.as_ref(), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError(_) => "SError", +Self::Multi(_) => "Multi", +Self::UnionKey(_) => "UnionKey", +Self::MyUnion(_) => "MyUnion", +Self::IntUnion(_) => "IntUnion", +Self::IntUnion2(_) => "IntUnion2", + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), - TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), - TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), - TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), - TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::SError(ref v) => v.as_ref(), - Self::Multi(ref v) => v.as_ref(), - Self::UnionKey(ref v) => v.as_ref(), - Self::MyUnion(ref v) => v.as_ref(), - Self::IntUnion(ref v) => v.as_ref(), - Self::IntUnion2(ref v) => v.as_ref(), + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::SError(_) => TypeVariant::SError, +Self::Multi(_) => TypeVariant::Multi, +Self::UnionKey(_) => TypeVariant::UnionKey, +Self::MyUnion(_) => TypeVariant::MyUnion, +Self::IntUnion(_) => TypeVariant::IntUnion, +Self::IntUnion2(_) => TypeVariant::IntUnion2, + } + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError(_) => "SError", - Self::Multi(_) => "Multi", - Self::UnionKey(_) => "UnionKey", - Self::MyUnion(_) => "MyUnion", - Self::IntUnion(_) => "IntUnion", - Self::IntUnion2(_) => "IntUnion2", + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::SError(_) => TypeVariant::SError, - Self::Multi(_) => TypeVariant::Multi, - Self::UnionKey(_) => TypeVariant::UnionKey, - Self::MyUnion(_) => TypeVariant::MyUnion, - Self::IntUnion(_) => TypeVariant::IntUnion, - Self::IntUnion2(_) => TypeVariant::IntUnion2, + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::SError(v) => v.write_xdr(w), - Self::Multi(v) => v.write_xdr(w), - Self::UnionKey(v) => v.write_xdr(w), - Self::MyUnion(v) => v.write_xdr(w), - Self::IntUnion(v) => v.write_xdr(w), - Self::IntUnion2(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::SError(v) => v.write_xdr(w), +Self::Multi(v) => v.write_xdr(w), +Self::UnionKey(v) => v.write_xdr(w), +Self::MyUnion(v) => v.write_xdr(w), +Self::IntUnion(v) => v.write_xdr(w), +Self::IntUnion2(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index 66aaeab58..b5de5241a 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/block_comments.x", - "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/block_comments.x", "e13131bc4134f38da17b9d5e9f67d2695a69ef98e3ef272833f4c18d0cc88a30") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2735,28 +2816,16 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum AccountFlags { - AuthRequiredFlag = 1, + AuthRequiredFlag = 1, } impl AccountFlags { - pub const VARIANTS: [AccountFlags; 1] = [AccountFlags::AuthRequiredFlag]; - pub const VARIANTS_STR: [&'static str; 1] = ["AuthRequiredFlag"]; + pub const VARIANTS: [AccountFlags; 1] = [ AccountFlags::AuthRequiredFlag, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AuthRequiredFlag", ]; #[must_use] pub const fn name(&self) -> &'static str { @@ -2835,26 +2904,18 @@ impl WriteXdr for AccountFlags { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") )] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum TypeVariant { AccountFlags, } impl TypeVariant { - pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; - pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; + pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; #[must_use] #[allow(clippy::too_many_lines)] @@ -2897,44 +2958,31 @@ impl core::str::FromStr for TypeVariant { #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), )] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum Type { AccountFlags(Box), } impl Type { - pub const VARIANTS: [TypeVariant; 1] = [TypeVariant::AccountFlags]; - pub const VARIANTS_STR: [&'static str; 1] = ["AccountFlags"]; + pub const VARIANTS: [TypeVariant; 1] = [ TypeVariant::AccountFlags, ]; + pub const VARIANTS_STR: [&'static str; 1] = [ "AccountFlags", ]; #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { match v { - TypeVariant::AccountFlags => r.with_limited_depth(|r| { - Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?))) - }), + TypeVariant::AccountFlags => r.with_limited_depth(|r| Ok(Self::AccountFlags(Box::new(AccountFlags::read_xdr(r)?)))), } } #[cfg(feature = "base64")] pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); let t = Self::read_xdr(v, &mut dec)?; Ok(t) } @@ -2953,54 +3001,33 @@ impl Type { #[cfg(feature = "base64")] pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new( - ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), - ), + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), } } #[cfg(feature = "std")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { match v { - TypeVariant::AccountFlags => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0)))), - ), + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t.0))))), } } #[cfg(feature = "base64")] #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); match v { - TypeVariant::AccountFlags => Box::new( - ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::AccountFlags(Box::new(t)))), - ), + TypeVariant::AccountFlags => Box::new(ReadXdrIter::<_, AccountFlags>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::AccountFlags(Box::new(t))))), } } @@ -3014,10 +3041,7 @@ impl Type { #[cfg(feature = "base64")] pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); let t = Self::read_xdr_to_end(v, &mut dec)?; Ok(t) } @@ -3026,9 +3050,7 @@ impl Type { #[allow(clippy::too_many_lines)] pub fn read_json(v: TypeVariant, r: impl Read) -> Result { match v { - TypeVariant::AccountFlags => { - Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))) - } + TypeVariant::AccountFlags => Ok(Self::AccountFlags(Box::new(serde_json::from_reader(r)?))), } } diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index b3a737966..ed83d1639 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/const.x", - "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/const.x", "0bff3b37592fcc16cad2fe10b9a72f5d39d033a114917c24e86a9ebd9cda9c37") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2745,281 +2826,229 @@ pub type TestArray = [i32; Foo]; /// typedef int TestArray2; /// ``` /// -pub type TestArray2 = VecM; - -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - TestArray, - TestArray2, -} +pub type TestArray2 = VecM::; + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + TestArray, +TestArray2, + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; - pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, +TypeVariant::TestArray2, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", +"TestArray2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray => "TestArray", +Self::TestArray2 => "TestArray2", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray => "TestArray", - Self::TestArray2 => "TestArray2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "TestArray" => Ok(Self::TestArray), +"TestArray2" => Ok(Self::TestArray2), + _ => Err(Error::Invalid), + } + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "TestArray" => Ok(Self::TestArray), - "TestArray2" => Ok(Self::TestArray2), - _ => Err(Error::Invalid), + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + TestArray(Box), +TestArray2(Box), } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - TestArray(Box), - TestArray2(Box), -} + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::TestArray, +TypeVariant::TestArray2, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "TestArray", +"TestArray2", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::TestArray, TypeVariant::TestArray2]; - pub const VARIANTS_STR: [&'static str; 2] = ["TestArray", "TestArray2"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::TestArray => r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))), +TypeVariant::TestArray2 => r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::TestArray => { - r.with_limited_depth(|r| Ok(Self::TestArray(Box::new(TestArray::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::TestArray2 => { - r.with_limited_depth(|r| Ok(Self::TestArray2(Box::new(TestArray2::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t.0))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t.0))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new( - ReadXdrIter::<_, TestArray>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), - ), - TypeVariant::TestArray2 => Box::new( - ReadXdrIter::<_, TestArray2>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::TestArray => Box::new(ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray(Box::new(t))))), +TypeVariant::TestArray2 => Box::new(ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::TestArray2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::TestArray => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray(Box::new(t.0)))), - ), - TypeVariant::TestArray2 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray2(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::TestArray => Box::new( - ReadXdrIter::<_, TestArray>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray(Box::new(t)))), - ), - TypeVariant::TestArray2 => Box::new( - ReadXdrIter::<_, TestArray2>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::TestArray2(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), +TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::TestArray(ref v) => v.as_ref(), +Self::TestArray2(ref v) => v.as_ref(), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::TestArray => Ok(Self::TestArray(Box::new(serde_json::from_reader(r)?))), - TypeVariant::TestArray2 => Ok(Self::TestArray2(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::TestArray(_) => "TestArray", +Self::TestArray2(_) => "TestArray2", + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::TestArray(ref v) => v.as_ref(), - Self::TestArray2(ref v) => v.as_ref(), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::TestArray(_) => "TestArray", - Self::TestArray2(_) => "TestArray2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::TestArray(_) => TypeVariant::TestArray, +Self::TestArray2(_) => TypeVariant::TestArray2, + } + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::TestArray(_) => TypeVariant::TestArray, - Self::TestArray2(_) => TypeVariant::TestArray2, + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::TestArray(v) => v.write_xdr(w), - Self::TestArray2(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::TestArray(v) => v.write_xdr(w), +Self::TestArray2(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index c5fa0ec22..3757516c0 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/enum.x", - "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/enum.x", "35cf5e97e2057039640ed260e8b38bb2733a3c3ca8529c93877bdec02a999d7f") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2731,19 +2812,19 @@ mod test { /// ERROR_MSG, /// HELLO, /// DONT_HAVE, -/// +/// /// GET_PEERS, // gets a list of peers this guy knows about /// PEERS, -/// +/// /// GET_TX_SET, // gets a particular txset by hash /// TX_SET, -/// +/// /// GET_VALIDATIONS, // gets validations for a given ledger hash /// VALIDATIONS, -/// +/// /// TRANSACTION, //pass on a tx you have heard about /// JSON_TRANSACTION, -/// +/// /// // FBA /// GET_FBA_QUORUMSET, /// FBA_QUORUMSET, @@ -2754,172 +2835,156 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum MessageType { - ErrorMsg = 0, - Hello = 1, - DontHave = 2, - GetPeers = 3, - Peers = 4, - GetTxSet = 5, - TxSet = 6, - GetValidations = 7, - Validations = 8, - Transaction = 9, - JsonTransaction = 10, - GetFbaQuorumset = 11, - FbaQuorumset = 12, - FbaMessage = 13, -} - -impl MessageType { - pub const VARIANTS: [MessageType; 14] = [ - MessageType::ErrorMsg, - MessageType::Hello, - MessageType::DontHave, - MessageType::GetPeers, - MessageType::Peers, - MessageType::GetTxSet, - MessageType::TxSet, - MessageType::GetValidations, - MessageType::Validations, - MessageType::Transaction, - MessageType::JsonTransaction, - MessageType::GetFbaQuorumset, - MessageType::FbaQuorumset, - MessageType::FbaMessage, - ]; - pub const VARIANTS_STR: [&'static str; 14] = [ - "ErrorMsg", - "Hello", - "DontHave", - "GetPeers", - "Peers", - "GetTxSet", - "TxSet", - "GetValidations", - "Validations", - "Transaction", - "JsonTransaction", - "GetFbaQuorumset", - "FbaQuorumset", - "FbaMessage", - ]; + ErrorMsg = 0, + Hello = 1, + DontHave = 2, + GetPeers = 3, + Peers = 4, + GetTxSet = 5, + TxSet = 6, + GetValidations = 7, + Validations = 8, + Transaction = 9, + JsonTransaction = 10, + GetFbaQuorumset = 11, + FbaQuorumset = 12, + FbaMessage = 13, +} + + impl MessageType { + pub const VARIANTS: [MessageType; 14] = [ MessageType::ErrorMsg, +MessageType::Hello, +MessageType::DontHave, +MessageType::GetPeers, +MessageType::Peers, +MessageType::GetTxSet, +MessageType::TxSet, +MessageType::GetValidations, +MessageType::Validations, +MessageType::Transaction, +MessageType::JsonTransaction, +MessageType::GetFbaQuorumset, +MessageType::FbaQuorumset, +MessageType::FbaMessage, ]; + pub const VARIANTS_STR: [&'static str; 14] = [ "ErrorMsg", +"Hello", +"DontHave", +"GetPeers", +"Peers", +"GetTxSet", +"TxSet", +"GetValidations", +"Validations", +"Transaction", +"JsonTransaction", +"GetFbaQuorumset", +"FbaQuorumset", +"FbaMessage", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::ErrorMsg => "ErrorMsg", +Self::Hello => "Hello", +Self::DontHave => "DontHave", +Self::GetPeers => "GetPeers", +Self::Peers => "Peers", +Self::GetTxSet => "GetTxSet", +Self::TxSet => "TxSet", +Self::GetValidations => "GetValidations", +Self::Validations => "Validations", +Self::Transaction => "Transaction", +Self::JsonTransaction => "JsonTransaction", +Self::GetFbaQuorumset => "GetFbaQuorumset", +Self::FbaQuorumset => "FbaQuorumset", +Self::FbaMessage => "FbaMessage", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::ErrorMsg => "ErrorMsg", - Self::Hello => "Hello", - Self::DontHave => "DontHave", - Self::GetPeers => "GetPeers", - Self::Peers => "Peers", - Self::GetTxSet => "GetTxSet", - Self::TxSet => "TxSet", - Self::GetValidations => "GetValidations", - Self::Validations => "Validations", - Self::Transaction => "Transaction", - Self::JsonTransaction => "JsonTransaction", - Self::GetFbaQuorumset => "GetFbaQuorumset", - Self::FbaQuorumset => "FbaQuorumset", - Self::FbaMessage => "FbaMessage", + #[must_use] + pub const fn variants() -> [MessageType; 14] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn variants() -> [MessageType; 14] { - Self::VARIANTS - } -} - -impl Name for MessageType { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for MessageType { - fn variants() -> slice::Iter<'static, MessageType> { - Self::VARIANTS.iter() - } -} + impl Name for MessageType { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Enum for MessageType {} + impl Variants for MessageType { + fn variants() -> slice::Iter<'static, MessageType> { + Self::VARIANTS.iter() + } + } -impl fmt::Display for MessageType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl Enum for MessageType {} -impl TryFrom for MessageType { - type Error = Error; + impl fmt::Display for MessageType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } - fn try_from(i: i32) -> Result { - let e = match i { - 0 => MessageType::ErrorMsg, - 1 => MessageType::Hello, - 2 => MessageType::DontHave, - 3 => MessageType::GetPeers, - 4 => MessageType::Peers, - 5 => MessageType::GetTxSet, - 6 => MessageType::TxSet, - 7 => MessageType::GetValidations, - 8 => MessageType::Validations, - 9 => MessageType::Transaction, - 10 => MessageType::JsonTransaction, - 11 => MessageType::GetFbaQuorumset, - 12 => MessageType::FbaQuorumset, - 13 => MessageType::FbaMessage, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + impl TryFrom for MessageType { + type Error = Error; + + fn try_from(i: i32) -> Result { + let e = match i { + 0 => MessageType::ErrorMsg, +1 => MessageType::Hello, +2 => MessageType::DontHave, +3 => MessageType::GetPeers, +4 => MessageType::Peers, +5 => MessageType::GetTxSet, +6 => MessageType::TxSet, +7 => MessageType::GetValidations, +8 => MessageType::Validations, +9 => MessageType::Transaction, +10 => MessageType::JsonTransaction, +11 => MessageType::GetFbaQuorumset, +12 => MessageType::FbaQuorumset, +13 => MessageType::FbaMessage, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: MessageType) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: MessageType) -> Self { + e as Self + } + } -impl ReadXdr for MessageType { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for MessageType { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for MessageType { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for MessageType { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// Color is an XDR Enum defines as: /// @@ -2934,109 +2999,101 @@ impl WriteXdr for MessageType { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color { - Red = 0, - Green = 1, - Blue = 2, -} - -impl Color { - pub const VARIANTS: [Color; 3] = [Color::Red, Color::Green, Color::Blue]; - pub const VARIANTS_STR: [&'static str; 3] = ["Red", "Green", "Blue"]; + Red = 0, + Green = 1, + Blue = 2, +} + + impl Color { + pub const VARIANTS: [Color; 3] = [ Color::Red, +Color::Green, +Color::Blue, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "Red", +"Green", +"Blue", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red => "Red", +Self::Green => "Green", +Self::Blue => "Blue", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red => "Red", - Self::Green => "Green", - Self::Blue => "Blue", + #[must_use] + pub const fn variants() -> [Color; 3] { + Self::VARIANTS + } } - } - - #[must_use] - pub const fn variants() -> [Color; 3] { - Self::VARIANTS - } -} -impl Name for Color { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for Color { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for Color { - fn variants() -> slice::Iter<'static, Color> { - Self::VARIANTS.iter() - } -} + impl Variants for Color { + fn variants() -> slice::Iter<'static, Color> { + Self::VARIANTS.iter() + } + } -impl Enum for Color {} + impl Enum for Color {} -impl fmt::Display for Color { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl fmt::Display for Color { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } -impl TryFrom for Color { - type Error = Error; + impl TryFrom for Color { + type Error = Error; - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color::Red, - 1 => Color::Green, - 2 => Color::Blue, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color::Red, +1 => Color::Green, +2 => Color::Blue, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: Color) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: Color) -> Self { + e as Self + } + } -impl ReadXdr for Color { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for Color { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for Color { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for Color { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// Color2 is an XDR Enum defines as: /// @@ -3051,416 +3108,340 @@ impl WriteXdr for Color { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum Color2 { - Red2 = 0, - Green2 = 1, - Blue2 = 2, -} - -impl Color2 { - pub const VARIANTS: [Color2; 3] = [Color2::Red2, Color2::Green2, Color2::Blue2]; - pub const VARIANTS_STR: [&'static str; 3] = ["Red2", "Green2", "Blue2"]; + Red2 = 0, + Green2 = 1, + Blue2 = 2, +} + + impl Color2 { + pub const VARIANTS: [Color2; 3] = [ Color2::Red2, +Color2::Green2, +Color2::Blue2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "Red2", +"Green2", +"Blue2", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Red2 => "Red2", +Self::Green2 => "Green2", +Self::Blue2 => "Blue2", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Red2 => "Red2", - Self::Green2 => "Green2", - Self::Blue2 => "Blue2", + #[must_use] + pub const fn variants() -> [Color2; 3] { + Self::VARIANTS + } } - } - - #[must_use] - pub const fn variants() -> [Color2; 3] { - Self::VARIANTS - } -} -impl Name for Color2 { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for Color2 { - fn variants() -> slice::Iter<'static, Color2> { - Self::VARIANTS.iter() - } -} + impl Name for Color2 { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Enum for Color2 {} + impl Variants for Color2 { + fn variants() -> slice::Iter<'static, Color2> { + Self::VARIANTS.iter() + } + } -impl fmt::Display for Color2 { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl Enum for Color2 {} -impl TryFrom for Color2 { - type Error = Error; + impl fmt::Display for Color2 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } - fn try_from(i: i32) -> Result { - let e = match i { - 0 => Color2::Red2, - 1 => Color2::Green2, - 2 => Color2::Blue2, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + impl TryFrom for Color2 { + type Error = Error; -impl From for i32 { - #[must_use] - fn from(e: Color2) -> Self { - e as Self - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 0 => Color2::Red2, +1 => Color2::Green2, +2 => Color2::Blue2, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl ReadXdr for Color2 { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl From for i32 { + #[must_use] + fn from(e: Color2) -> Self { + e as Self + } + } -impl WriteXdr for Color2 { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl ReadXdr for Color2 { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - MessageType, - Color, - Color2, -} + impl WriteXdr for Color2 { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 3] = [ - TypeVariant::MessageType, - TypeVariant::Color, - TypeVariant::Color2, - ]; - pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + MessageType, +Color, +Color2, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, +TypeVariant::Color, +TypeVariant::Color2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", +"Color", +"Color2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType => "MessageType", +Self::Color => "Color", +Self::Color2 => "Color2", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType => "MessageType", - Self::Color => "Color", - Self::Color2 => "Color2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS - } -} - -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "MessageType" => Ok(Self::MessageType), - "Color" => Ok(Self::Color), - "Color2" => Ok(Self::Color2), - _ => Err(Error::Invalid), + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "MessageType" => Ok(Self::MessageType), +"Color" => Ok(Self::Color), +"Color2" => Ok(Self::Color2), + _ => Err(Error::Invalid), + } + } } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - MessageType(Box), - Color(Box), - Color2(Box), -} + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + MessageType(Box), +Color(Box), +Color2(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 3] = [ TypeVariant::MessageType, +TypeVariant::Color, +TypeVariant::Color2, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "MessageType", +"Color", +"Color2", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 3] = [ - TypeVariant::MessageType, - TypeVariant::Color, - TypeVariant::Color2, - ]; - pub const VARIANTS_STR: [&'static str; 3] = ["MessageType", "Color", "Color2"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::MessageType => r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))), +TypeVariant::Color => r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))), +TypeVariant::Color2 => r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::MessageType => { - r.with_limited_depth(|r| Ok(Self::MessageType(Box::new(MessageType::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::Color => { - r.with_limited_depth(|r| Ok(Self::Color(Box::new(Color::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - TypeVariant::Color2 => { - r.with_limited_depth(|r| Ok(Self::Color2(Box::new(Color2::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t.0))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t.0))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t.0))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::MessageType => Box::new(ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MessageType(Box::new(t))))), +TypeVariant::Color => Box::new(ReadXdrIter::<_, Color>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color(Box::new(t))))), +TypeVariant::Color2 => Box::new(ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Color2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new( - ReadXdrIter::<_, MessageType>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), - ), - TypeVariant::Color => Box::new( - ReadXdrIter::<_, Color>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color(Box::new(t)))), - ), - TypeVariant::Color2 => Box::new( - ReadXdrIter::<_, Color2>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color2(Box::new(t)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::MessageType => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MessageType(Box::new(t.0)))), - ), - TypeVariant::Color => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color(Box::new(t.0)))), - ), - TypeVariant::Color2 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Color2(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::MessageType => Box::new( - ReadXdrIter::<_, MessageType>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MessageType(Box::new(t)))), - ), - TypeVariant::Color => Box::new( - ReadXdrIter::<_, Color>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Color(Box::new(t)))), - ), - TypeVariant::Color2 => Box::new( - ReadXdrIter::<_, Color2>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Color2(Box::new(t)))), - ), - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::MessageType => Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::MessageType(ref v) => v.as_ref(), +Self::Color(ref v) => v.as_ref(), +Self::Color2(ref v) => v.as_ref(), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::MessageType(_) => "MessageType", +Self::Color(_) => "Color", +Self::Color2(_) => "Color2", + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::MessageType => { - Ok(Self::MessageType(Box::new(serde_json::from_reader(r)?))) + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 3] { + Self::VARIANTS } - TypeVariant::Color => Ok(Self::Color(Box::new(serde_json::from_reader(r)?))), - TypeVariant::Color2 => Ok(Self::Color2(Box::new(serde_json::from_reader(r)?))), - } - } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::MessageType(ref v) => v.as_ref(), - Self::Color(ref v) => v.as_ref(), - Self::Color2(ref v) => v.as_ref(), + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::MessageType(_) => TypeVariant::MessageType, +Self::Color(_) => TypeVariant::Color, +Self::Color2(_) => TypeVariant::Color2, + } + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::MessageType(_) => "MessageType", - Self::Color(_) => "Color", - Self::Color2(_) => "Color2", + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 3] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::MessageType(_) => TypeVariant::MessageType, - Self::Color(_) => TypeVariant::Color, - Self::Color2(_) => TypeVariant::Color2, + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::MessageType(v) => v.write_xdr(w), - Self::Color(v) => v.write_xdr(w), - Self::Color2(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::MessageType(v) => v.write_xdr(w), +Self::Color(v) => v.write_xdr(w), +Self::Color2(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 31994e1f6..9a75889d5 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/nesting.x", - "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/nesting.x", "5537949272c11f1bd09cf613a3751668b5018d686a1c2aaa3baa91183ca18f6a") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2736,108 +2817,101 @@ mod test { // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { - One = 1, - Two = 2, - Offer = 3, -} - -impl UnionKey { - pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; - pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; + One = 1, + Two = 2, + Offer = 3, +} + + impl UnionKey { + pub const VARIANTS: [UnionKey; 3] = [ UnionKey::One, +UnionKey::Two, +UnionKey::Offer, ]; + pub const VARIANTS_STR: [&'static str; 3] = [ "One", +"Two", +"Offer", ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One => "One", +Self::Two => "Two", +Self::Offer => "Offer", + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One => "One", - Self::Two => "Two", - Self::Offer => "Offer", + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } -} -impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Enum for UnionKey {} + impl Enum for UnionKey {} -impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } -impl TryFrom for UnionKey { - type Error = Error; + impl TryFrom for UnionKey { + type Error = Error; - fn try_from(i: i32) -> Result { - let e = match i { - 1 => UnionKey::One, - 2 => UnionKey::Two, - 3 => UnionKey::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 1 => UnionKey::One, +2 => UnionKey::Two, +3 => UnionKey::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } + } -impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// Foo is an XDR Typedef defines as: /// @@ -2857,30 +2931,18 @@ pub type Foo = i32; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyUnionOne { - pub some_int: i32, + pub some_int: i32, } impl ReadXdr for MyUnionOne { #[cfg(feature = "std")] fn read_xdr(r: &mut Limited) -> Result { r.with_limited_depth(|r| { - Ok(Self { - some_int: i32::read_xdr(r)?, + Ok(Self{ + some_int: i32::read_xdr(r)?, }) }) } @@ -2907,47 +2969,35 @@ impl WriteXdr for MyUnionOne { /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyUnionTwo { - pub some_int: i32, - pub foo: i32, + pub some_int: i32, + pub foo: i32, } -impl ReadXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self { - some_int: i32::read_xdr(r)?, - foo: i32::read_xdr(r)?, - }) - }) - } -} + impl ReadXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + some_int: i32::read_xdr(r)?, +foo: i32::read_xdr(r)?, + }) + }) + } + } -impl WriteXdr for MyUnionTwo { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; - self.foo.write_xdr(w)?; - Ok(()) - }) - } -} + impl WriteXdr for MyUnionTwo { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; +self.foo.write_xdr(w)?; + Ok(()) + }) + } + } /// MyUnion is an XDR Union defines as: /// @@ -2958,13 +3008,13 @@ impl WriteXdr for MyUnionTwo { /// struct { /// int someInt; /// } one; -/// +/// /// case TWO: /// struct { /// int someInt; /// Foo foo; /// } two; -/// +/// /// case OFFER: /// void; /// }; @@ -2973,470 +3023,380 @@ impl WriteXdr for MyUnionTwo { // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - One(MyUnionOne), - Two(MyUnionTwo), - Offer, -} + One(MyUnionOne), + Two(MyUnionTwo), + Offer, +} + + impl MyUnion { + pub const VARIANTS: [UnionKey; 3] = [ + UnionKey::One, +UnionKey::Two, +UnionKey::Offer, + ]; + pub const VARIANTS_STR: [&'static str; 3] = [ + "One", +"Two", +"Offer", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::One(_) => "One", +Self::Two(_) => "Two", +Self::Offer => "Offer", + } + } -impl MyUnion { - pub const VARIANTS: [UnionKey; 3] = [UnionKey::One, UnionKey::Two, UnionKey::Offer]; - pub const VARIANTS_STR: [&'static str; 3] = ["One", "Two", "Offer"]; + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::One(_) => UnionKey::One, +Self::Two(_) => UnionKey::Two, +Self::Offer => UnionKey::Offer, + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::One(_) => "One", - Self::Two(_) => "Two", - Self::Offer => "Offer", + #[must_use] + pub const fn variants() -> [UnionKey; 3] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::One(_) => UnionKey::One, - Self::Two(_) => UnionKey::Two, - Self::Offer => UnionKey::Offer, + impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 3] { - Self::VARIANTS - } -} -impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } -} + impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } + } -impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Union for MyUnion {} + impl Union for MyUnion {} -impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), - UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), - UnionKey::Offer => Self::Offer, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } -} + impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::One => Self::One(MyUnionOne::read_xdr(r)?), +UnionKey::Two => Self::Two(MyUnionTwo::read_xdr(r)?), +UnionKey::Offer => Self::Offer, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } -impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::One(v) => v.write_xdr(w)?, - Self::Two(v) => v.write_xdr(w)?, - Self::Offer => ().write_xdr(w)?, - }; - Ok(()) - }) - } -} + impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::One(v) => v.write_xdr(w)?, +Self::Two(v) => v.write_xdr(w)?, +Self::Offer => ().write_xdr(w)?, + }; + Ok(()) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - UnionKey, - Foo, - MyUnion, - MyUnionOne, - MyUnionTwo, -} - -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 5] = [ - TypeVariant::UnionKey, - TypeVariant::Foo, - TypeVariant::MyUnion, - TypeVariant::MyUnionOne, - TypeVariant::MyUnionTwo, - ]; - pub const VARIANTS_STR: [&'static str; 5] = - ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + UnionKey, +Foo, +MyUnion, +MyUnionOne, +MyUnionTwo, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, +TypeVariant::Foo, +TypeVariant::MyUnion, +TypeVariant::MyUnionOne, +TypeVariant::MyUnionTwo, ]; + pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", +"Foo", +"MyUnion", +"MyUnionOne", +"MyUnionTwo", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey => "UnionKey", +Self::Foo => "Foo", +Self::MyUnion => "MyUnion", +Self::MyUnionOne => "MyUnionOne", +Self::MyUnionTwo => "MyUnionTwo", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey => "UnionKey", - Self::Foo => "Foo", - Self::MyUnion => "MyUnion", - Self::MyUnionOne => "MyUnionOne", - Self::MyUnionTwo => "MyUnionTwo", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } -} - -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "UnionKey" => Ok(Self::UnionKey), - "Foo" => Ok(Self::Foo), - "MyUnion" => Ok(Self::MyUnion), - "MyUnionOne" => Ok(Self::MyUnionOne), - "MyUnionTwo" => Ok(Self::MyUnionTwo), - _ => Err(Error::Invalid), + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "UnionKey" => Ok(Self::UnionKey), +"Foo" => Ok(Self::Foo), +"MyUnion" => Ok(Self::MyUnion), +"MyUnionOne" => Ok(Self::MyUnionOne), +"MyUnionTwo" => Ok(Self::MyUnionTwo), + _ => Err(Error::Invalid), + } + } } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - UnionKey(Box), - Foo(Box), - MyUnion(Box), - MyUnionOne(Box), - MyUnionTwo(Box), -} - -impl Type { - pub const VARIANTS: [TypeVariant; 5] = [ - TypeVariant::UnionKey, - TypeVariant::Foo, - TypeVariant::MyUnion, - TypeVariant::MyUnionOne, - TypeVariant::MyUnionTwo, - ]; - pub const VARIANTS_STR: [&'static str; 5] = - ["UnionKey", "Foo", "MyUnion", "MyUnionOne", "MyUnionTwo"]; + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + UnionKey(Box), +Foo(Box), +MyUnion(Box), +MyUnionOne(Box), +MyUnionTwo(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 5] = [ TypeVariant::UnionKey, +TypeVariant::Foo, +TypeVariant::MyUnion, +TypeVariant::MyUnionOne, +TypeVariant::MyUnionTwo, ]; + pub const VARIANTS_STR: [&'static str; 5] = [ "UnionKey", +"Foo", +"MyUnion", +"MyUnionOne", +"MyUnionTwo", ]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::UnionKey => { - r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) - } - TypeVariant::Foo => { - r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))) + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), +TypeVariant::Foo => r.with_limited_depth(|r| Ok(Self::Foo(Box::new(Foo::read_xdr(r)?)))), +TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), +TypeVariant::MyUnionOne => r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))), +TypeVariant::MyUnionTwo => r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))), + } } - TypeVariant::MyUnion => { - r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::MyUnionOne => { - r.with_limited_depth(|r| Ok(Self::MyUnionOne(Box::new(MyUnionOne::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - TypeVariant::MyUnionTwo => { - r.with_limited_depth(|r| Ok(Self::MyUnionTwo(Box::new(MyUnionTwo::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), + } + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t.0))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::Foo => Box::new(ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Foo(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::MyUnionOne => Box::new(ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionOne(Box::new(t))))), +TypeVariant::MyUnionTwo => Box::new(ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::Foo => Box::new( - ReadXdrIter::<_, Foo>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Foo(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::MyUnionOne => Box::new( - ReadXdrIter::<_, MyUnionOne>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), - ), - TypeVariant::MyUnionTwo => Box::new( - ReadXdrIter::<_, MyUnionTwo>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), - ), - TypeVariant::Foo => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Foo(Box::new(t.0)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), - ), - TypeVariant::MyUnionOne => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t.0)))), - ), - TypeVariant::MyUnionTwo => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::Foo => Box::new( - ReadXdrIter::<_, Foo>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Foo(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::MyUnionOne => Box::new( - ReadXdrIter::<_, MyUnionOne>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionOne(Box::new(t)))), - ), - TypeVariant::MyUnionTwo => Box::new( - ReadXdrIter::<_, MyUnionTwo>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnionTwo(Box::new(t)))), - ), - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::UnionKey(ref v) => v.as_ref(), +Self::Foo(ref v) => v.as_ref(), +Self::MyUnion(ref v) => v.as_ref(), +Self::MyUnionOne(ref v) => v.as_ref(), +Self::MyUnionTwo(ref v) => v.as_ref(), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::UnionKey(_) => "UnionKey", +Self::Foo(_) => "Foo", +Self::MyUnion(_) => "MyUnion", +Self::MyUnionOne(_) => "MyUnionOne", +Self::MyUnionTwo(_) => "MyUnionTwo", + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), - TypeVariant::Foo => Ok(Self::Foo(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnionOne => Ok(Self::MyUnionOne(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnionTwo => Ok(Self::MyUnionTwo(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 5] { + Self::VARIANTS + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::UnionKey(ref v) => v.as_ref(), - Self::Foo(ref v) => v.as_ref(), - Self::MyUnion(ref v) => v.as_ref(), - Self::MyUnionOne(ref v) => v.as_ref(), - Self::MyUnionTwo(ref v) => v.as_ref(), + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::UnionKey(_) => TypeVariant::UnionKey, +Self::Foo(_) => TypeVariant::Foo, +Self::MyUnion(_) => TypeVariant::MyUnion, +Self::MyUnionOne(_) => TypeVariant::MyUnionOne, +Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, + } + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::UnionKey(_) => "UnionKey", - Self::Foo(_) => "Foo", - Self::MyUnion(_) => "MyUnion", - Self::MyUnionOne(_) => "MyUnionOne", - Self::MyUnionTwo(_) => "MyUnionTwo", + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 5] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::UnionKey(_) => TypeVariant::UnionKey, - Self::Foo(_) => TypeVariant::Foo, - Self::MyUnion(_) => TypeVariant::MyUnion, - Self::MyUnionOne(_) => TypeVariant::MyUnionOne, - Self::MyUnionTwo(_) => TypeVariant::MyUnionTwo, + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} - -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::UnionKey(v) => v.write_xdr(w), - Self::Foo(v) => v.write_xdr(w), - Self::MyUnion(v) => v.write_xdr(w), - Self::MyUnionOne(v) => v.write_xdr(w), - Self::MyUnionTwo(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::UnionKey(v) => v.write_xdr(w), +Self::Foo(v) => v.write_xdr(w), +Self::MyUnion(v) => v.write_xdr(w), +Self::MyUnionOne(v) => v.write_xdr(w), +Self::MyUnionTwo(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index 0e2739141..50750f474 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/optional.x", - "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/optional.x", "3241e832fcf00bca4315ecb6c259621dafb0e302a63a993f5504b0b5cebb6bd7") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2744,323 +2825,260 @@ pub type Arr = [i32; 2]; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct HasOptions { - pub first_option: Option, - pub second_option: Option, - pub third_option: Option, + pub first_option: Option, + pub second_option: Option, + pub third_option: Option, } -impl ReadXdr for HasOptions { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self { - first_option: Option::::read_xdr(r)?, - second_option: Option::::read_xdr(r)?, - third_option: Option::::read_xdr(r)?, - }) - }) - } -} + impl ReadXdr for HasOptions { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + first_option: Option::::read_xdr(r)?, +second_option: Option::::read_xdr(r)?, +third_option: Option::::read_xdr(r)?, + }) + }) + } + } -impl WriteXdr for HasOptions { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.first_option.write_xdr(w)?; - self.second_option.write_xdr(w)?; - self.third_option.write_xdr(w)?; - Ok(()) - }) - } -} + impl WriteXdr for HasOptions { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.first_option.write_xdr(w)?; +self.second_option.write_xdr(w)?; +self.third_option.write_xdr(w)?; + Ok(()) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - Arr, - HasOptions, -} + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + Arr, +HasOptions, + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; - pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, +TypeVariant::HasOptions, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", +"HasOptions", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr => "Arr", +Self::HasOptions => "HasOptions", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr => "Arr", - Self::HasOptions => "HasOptions", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Arr" => Ok(Self::Arr), +"HasOptions" => Ok(Self::HasOptions), + _ => Err(Error::Invalid), + } + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Arr" => Ok(Self::Arr), - "HasOptions" => Ok(Self::HasOptions), - _ => Err(Error::Invalid), + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + Arr(Box), +HasOptions(Box), } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - Arr(Box), - HasOptions(Box), -} + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Arr, +TypeVariant::HasOptions, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Arr", +"HasOptions", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Arr, TypeVariant::HasOptions]; - pub const VARIANTS_STR: [&'static str; 2] = ["Arr", "HasOptions"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Arr => r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))), +TypeVariant::HasOptions => r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Arr => { - r.with_limited_depth(|r| Ok(Self::Arr(Box::new(Arr::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::HasOptions => { - r.with_limited_depth(|r| Ok(Self::HasOptions(Box::new(HasOptions::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t.0))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t.0))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new( - ReadXdrIter::<_, Arr>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Arr(Box::new(t)))), - ), - TypeVariant::HasOptions => Box::new( - ReadXdrIter::<_, HasOptions>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Arr => Box::new(ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Arr(Box::new(t))))), +TypeVariant::HasOptions => Box::new(ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::HasOptions(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Arr => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Arr(Box::new(t.0)))), - ), - TypeVariant::HasOptions => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::HasOptions(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Arr => Box::new( - ReadXdrIter::<_, Arr>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Arr(Box::new(t)))), - ), - TypeVariant::HasOptions => Box::new( - ReadXdrIter::<_, HasOptions>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::HasOptions(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), +TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Arr(ref v) => v.as_ref(), +Self::HasOptions(ref v) => v.as_ref(), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Arr => Ok(Self::Arr(Box::new(serde_json::from_reader(r)?))), - TypeVariant::HasOptions => Ok(Self::HasOptions(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Arr(_) => "Arr", +Self::HasOptions(_) => "HasOptions", + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Arr(ref v) => v.as_ref(), - Self::HasOptions(ref v) => v.as_ref(), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Arr(_) => "Arr", - Self::HasOptions(_) => "HasOptions", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Arr(_) => TypeVariant::Arr, +Self::HasOptions(_) => TypeVariant::HasOptions, + } + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Arr(_) => TypeVariant::Arr, - Self::HasOptions(_) => TypeVariant::HasOptions, + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Arr(v) => v.write_xdr(w), - Self::HasOptions(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Arr(v) => v.write_xdr(w), +Self::HasOptions(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index a6fb8906a..36ba22dfc 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/struct.x", - "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/struct.x", "c6911a83390e3b499c078fd0c579132eacce88a4a0538d3b8b5e57747a58db4a") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2746,329 +2827,266 @@ pub type Int64 = i64; /// #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct MyStruct { - pub some_int: i32, - pub a_big_int: i64, - pub some_opaque: [u8; 10], - pub some_string: StringM, - pub max_string: StringM<100>, + pub some_int: i32, + pub a_big_int: i64, + pub some_opaque: [u8; 10], + pub some_string: StringM, + pub max_string: StringM::<100>, } -impl ReadXdr for MyStruct { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - Ok(Self { - some_int: i32::read_xdr(r)?, - a_big_int: i64::read_xdr(r)?, - some_opaque: <[u8; 10]>::read_xdr(r)?, - some_string: StringM::read_xdr(r)?, - max_string: StringM::<100>::read_xdr(r)?, - }) - }) - } -} + impl ReadXdr for MyStruct { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + Ok(Self{ + some_int: i32::read_xdr(r)?, +a_big_int: i64::read_xdr(r)?, +some_opaque: <[u8; 10]>::read_xdr(r)?, +some_string: StringM::read_xdr(r)?, +max_string: StringM::<100>::read_xdr(r)?, + }) + }) + } + } -impl WriteXdr for MyStruct { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.some_int.write_xdr(w)?; - self.a_big_int.write_xdr(w)?; - self.some_opaque.write_xdr(w)?; - self.some_string.write_xdr(w)?; - self.max_string.write_xdr(w)?; - Ok(()) - }) - } -} + impl WriteXdr for MyStruct { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.some_int.write_xdr(w)?; +self.a_big_int.write_xdr(w)?; +self.some_opaque.write_xdr(w)?; +self.some_string.write_xdr(w)?; +self.max_string.write_xdr(w)?; + Ok(()) + }) + } + } -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - Int64, - MyStruct, -} + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + Int64, +MyStruct, + } -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; - pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, +TypeVariant::MyStruct, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", +"MyStruct", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64 => "Int64", +Self::MyStruct => "MyStruct", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64 => "Int64", - Self::MyStruct => "MyStruct", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "Int64" => Ok(Self::Int64), +"MyStruct" => Ok(Self::MyStruct), + _ => Err(Error::Invalid), + } + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "Int64" => Ok(Self::Int64), - "MyStruct" => Ok(Self::MyStruct), - _ => Err(Error::Invalid), + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + Int64(Box), +MyStruct(Box), } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - Int64(Box), - MyStruct(Box), -} + impl Type { + pub const VARIANTS: [TypeVariant; 2] = [ TypeVariant::Int64, +TypeVariant::MyStruct, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Int64", +"MyStruct", ]; -impl Type { - pub const VARIANTS: [TypeVariant; 2] = [TypeVariant::Int64, TypeVariant::MyStruct]; - pub const VARIANTS_STR: [&'static str; 2] = ["Int64", "MyStruct"]; + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::Int64 => r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))), +TypeVariant::MyStruct => r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::Int64 => { - r.with_limited_depth(|r| Ok(Self::Int64(Box::new(Int64::read_xdr(r)?)))) + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::MyStruct => { - r.with_limited_depth(|r| Ok(Self::MyStruct(Box::new(MyStruct::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t.0))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t.0))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new( - ReadXdrIter::<_, Int64>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Int64(Box::new(t)))), - ), - TypeVariant::MyStruct => Box::new( - ReadXdrIter::<_, MyStruct>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::Int64 => Box::new(ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Int64(Box::new(t))))), +TypeVariant::MyStruct => Box::new(ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyStruct(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::Int64 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Int64(Box::new(t.0)))), - ), - TypeVariant::MyStruct => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyStruct(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::Int64 => Box::new( - ReadXdrIter::<_, Int64>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Int64(Box::new(t)))), - ), - TypeVariant::MyStruct => Box::new( - ReadXdrIter::<_, MyStruct>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyStruct(Box::new(t)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::Int64(ref v) => v.as_ref(), +Self::MyStruct(ref v) => v.as_ref(), + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::Int64 => Ok(Self::Int64(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyStruct => Ok(Self::MyStruct(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::Int64(_) => "Int64", +Self::MyStruct(_) => "MyStruct", + } + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::Int64(ref v) => v.as_ref(), - Self::MyStruct(ref v) => v.as_ref(), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 2] { + Self::VARIANTS + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::Int64(_) => "Int64", - Self::MyStruct(_) => "MyStruct", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::Int64(_) => TypeVariant::Int64, +Self::MyStruct(_) => TypeVariant::MyStruct, + } + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 2] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::Int64(_) => TypeVariant::Int64, - Self::MyStruct(_) => TypeVariant::MyStruct, + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::Int64(v) => v.write_xdr(w), - Self::MyStruct(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::Int64(v) => v.write_xdr(w), +Self::MyStruct(v) => v.write_xdr(w), + } + } } - } -} diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index 2036ac271..7e41b6201 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -874,7 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -899,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1282,7 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1335,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1664,7 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1724,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2036,11 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2065,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2730,6 +2844,36 @@ impl core::str::FromStr for Uint512 { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +impl schemars::JsonSchema for Uint512 { + fn schema_name() -> String { + "Uint512".to_string() + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: SOME(MAX * 2), + min_length: SOME(MAX * 2), + ..string + }) + } else { + schema_ + } + } +} impl From for [u8; 64] { #[must_use] fn from(x: Uint512) -> Self { @@ -3254,6 +3398,36 @@ impl core::str::FromStr for Hash { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +impl schemars::JsonSchema for Hash { + fn schema_name() -> String { + "Hash".to_string() + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: SOME(MAX * 2), + min_length: SOME(MAX * 2), + ..string + }) + } else { + schema_ + } + } +} impl From for [u8; 32] { #[must_use] fn from(x: Hash) -> Self { @@ -4327,7 +4501,7 @@ self.nested_union.write_xdr(w)?; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] @@ -4491,7 +4665,7 @@ Self::NesterNestedUnion => "NesterNestedUnion", #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), + derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"), serde(untagged), )] diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index 0a72f6a15..d1bf85279 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -4,10 +4,9 @@ #![allow(clippy::missing_errors_doc, clippy::unreadable_literal)] /// `XDR_FILES_SHA256` is a list of pairs of source files and their SHA256 hashes. -pub const XDR_FILES_SHA256: [(&str, &str); 1] = [( - "spec/fixtures/generator/union.x", - "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41", -)]; +pub const XDR_FILES_SHA256: [(&str, &str); 1] = [ + ("spec/fixtures/generator/union.x", "c251258d967223b341ebcf2d5bb0718e9a039b46232cb743865d9acd0c4bbe41") +]; use core::{array::TryFromSliceError, fmt, fmt::Debug, marker::Sized, ops::Deref, slice}; @@ -875,15 +874,6 @@ impl WriteXdr for [T; N] { #[cfg(feature = "alloc")] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct VecM(Vec); @@ -908,6 +898,26 @@ impl Default for VecM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for VecM { + fn schema_name() -> String { + format!("VecM<{}, {}>", T::schema_name(), MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_array(Vec::::json_schema(gen), |array| { + schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..array + } + }) + } +} + impl VecM { pub const MAX_LEN: usize = { MAX as usize }; @@ -1291,15 +1301,6 @@ impl WriteXdr for VecM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct BytesM(Vec); @@ -1352,6 +1353,38 @@ impl Deref for BytesM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for BytesM { + fn schema_name() -> String { + format!("BytesM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let schema_ = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema_ { + schema.extensions.insert( + "contentEncoding".to_owned(), + serde_json::Value::String("hex".to_string()), + ); + schema.extensions.insert( + "contentMediaType".to_owned(), + serde_json::Value::String("application/binary".to_string()), + ); + mut_string(schema.into(), |string| schemars::schema::StringValidation { + max_length: Some(MAX * 2), + min_length: None, + ..string + }) + } else { + schema_ + } + } +} + impl Default for BytesM { fn default() -> Self { Self(Vec::default()) @@ -1681,15 +1714,6 @@ impl WriteXdr for BytesM { feature = "serde", derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] pub struct StringM(Vec); @@ -1749,6 +1773,26 @@ impl Default for StringM { } } +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for StringM { + fn schema_name() -> String { + format!("StringM<{}>", MAX) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + mut_string(String::json_schema(gen), |string| { + schemars::schema::StringValidation { + max_length: Some(MAX), + ..string + } + }) + } +} + impl StringM { pub const MAX_LEN: usize = { MAX as usize }; @@ -2061,19 +2105,25 @@ impl WriteXdr for StringM { derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case") )] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] pub struct Frame(pub T) where T: ReadXdr; +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for Frame { + fn schema_name() -> String { + format!("Frame<{}>", T::schema_name()) + } + + fn is_referenceable() -> bool { + false + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + T::json_schema(gen) + } +} + impl ReadXdr for Frame where T: ReadXdr, @@ -2098,6 +2148,37 @@ where } } +#[cfg(feature = "schemars")] +fn mut_array( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(f(*array))); + } + schema.into() + } else { + schema + } +} + +#[cfg(feature = "schemars")] +fn mut_string( + schema: schemars::schema::Schema, + f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, +) -> schemars::schema::Schema { + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + let s = f(string); + schema.string = Some(Box::new(s)); + + schema.into() + } else { + schema + } +} + #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2751,105 +2832,96 @@ pub type Multi = i32; // enum #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[repr(i32)] pub enum UnionKey { - Error = 0, - Multi = 1, + Error = 0, + Multi = 1, } -impl UnionKey { - pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; - pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; + impl UnionKey { + pub const VARIANTS: [UnionKey; 2] = [ UnionKey::Error, +UnionKey::Multi, ]; + pub const VARIANTS_STR: [&'static str; 2] = [ "Error", +"Multi", ]; - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error => "Error", - Self::Multi => "Multi", - } - } + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error => "Error", +Self::Multi => "Multi", + } + } - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } -} + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } + } -impl Name for UnionKey { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for UnionKey { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for UnionKey { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for UnionKey { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Enum for UnionKey {} + impl Enum for UnionKey {} -impl fmt::Display for UnionKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.name()) - } -} + impl fmt::Display for UnionKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.name()) + } + } -impl TryFrom for UnionKey { - type Error = Error; + impl TryFrom for UnionKey { + type Error = Error; - fn try_from(i: i32) -> Result { - let e = match i { - 0 => UnionKey::Error, - 1 => UnionKey::Multi, - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(e) - } -} + fn try_from(i: i32) -> Result { + let e = match i { + 0 => UnionKey::Error, +1 => UnionKey::Multi, + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(e) + } + } -impl From for i32 { - #[must_use] - fn from(e: UnionKey) -> Self { - e as Self - } -} + impl From for i32 { + #[must_use] + fn from(e: UnionKey) -> Self { + e as Self + } + } -impl ReadXdr for UnionKey { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let e = i32::read_xdr(r)?; - let v: Self = e.try_into()?; - Ok(v) - }) - } -} + impl ReadXdr for UnionKey { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let e = i32::read_xdr(r)?; + let v: Self = e.try_into()?; + Ok(v) + }) + } + } -impl WriteXdr for UnionKey { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - let i: i32 = (*self).into(); - i.write_xdr(w) - }) - } -} + impl WriteXdr for UnionKey { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + let i: i32 = (*self).into(); + i.write_xdr(w) + }) + } + } /// MyUnion is an XDR Union defines as: /// @@ -2860,113 +2932,108 @@ impl WriteXdr for UnionKey { /// Error error; /// case MULTI: /// Multi things<>; -/// -/// +/// +/// /// }; /// ``` /// // union with discriminant UnionKey #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum MyUnion { - Error(i32), - Multi(VecM), -} + Error(i32), + Multi(VecM::), +} + + impl MyUnion { + pub const VARIANTS: [UnionKey; 2] = [ + UnionKey::Error, +UnionKey::Multi, + ]; + pub const VARIANTS_STR: [&'static str; 2] = [ + "Error", +"Multi", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::Error(_) => "Error", +Self::Multi(_) => "Multi", + } + } -impl MyUnion { - pub const VARIANTS: [UnionKey; 2] = [UnionKey::Error, UnionKey::Multi]; - pub const VARIANTS_STR: [&'static str; 2] = ["Error", "Multi"]; + #[must_use] + pub const fn discriminant(&self) -> UnionKey { + #[allow(clippy::match_same_arms)] + match self { + Self::Error(_) => UnionKey::Error, +Self::Multi(_) => UnionKey::Multi, + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::Error(_) => "Error", - Self::Multi(_) => "Multi", + #[must_use] + pub const fn variants() -> [UnionKey; 2] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn discriminant(&self) -> UnionKey { - #[allow(clippy::match_same_arms)] - match self { - Self::Error(_) => UnionKey::Error, - Self::Multi(_) => UnionKey::Multi, + impl Name for MyUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - pub const fn variants() -> [UnionKey; 2] { - Self::VARIANTS - } -} - -impl Name for MyUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} -impl Discriminant for MyUnion { - #[must_use] - fn discriminant(&self) -> UnionKey { - Self::discriminant(self) - } -} + impl Discriminant for MyUnion { + #[must_use] + fn discriminant(&self) -> UnionKey { + Self::discriminant(self) + } + } -impl Variants for MyUnion { - fn variants() -> slice::Iter<'static, UnionKey> { - Self::VARIANTS.iter() - } -} + impl Variants for MyUnion { + fn variants() -> slice::Iter<'static, UnionKey> { + Self::VARIANTS.iter() + } + } -impl Union for MyUnion {} + impl Union for MyUnion {} -impl ReadXdr for MyUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: UnionKey = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - UnionKey::Error => Self::Error(i32::read_xdr(r)?), - UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } -} + impl ReadXdr for MyUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: UnionKey = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + UnionKey::Error => Self::Error(i32::read_xdr(r)?), +UnionKey::Multi => Self::Multi(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } -impl WriteXdr for MyUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::Error(v) => v.write_xdr(w)?, - Self::Multi(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } -} + impl WriteXdr for MyUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::Error(v) => v.write_xdr(w)?, +Self::Multi(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } + } /// IntUnion is an XDR Union defines as: /// @@ -2977,113 +3044,107 @@ impl WriteXdr for MyUnion { /// Error error; /// case 1: /// Multi things<>; -/// +/// /// }; /// ``` /// // union with discriminant i32 #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[allow(clippy::large_enum_variant)] pub enum IntUnion { - V0(i32), - V1(VecM), -} + V0(i32), + V1(VecM::), +} + + impl IntUnion { + pub const VARIANTS: [i32; 2] = [ + 0, +1, + ]; + pub const VARIANTS_STR: [&'static str; 2] = [ + "V0", +"V1", + ]; + + #[must_use] + pub const fn name(&self) -> &'static str { + match self { + Self::V0(_) => "V0", +Self::V1(_) => "V1", + } + } -impl IntUnion { - pub const VARIANTS: [i32; 2] = [0, 1]; - pub const VARIANTS_STR: [&'static str; 2] = ["V0", "V1"]; + #[must_use] + pub const fn discriminant(&self) -> i32 { + #[allow(clippy::match_same_arms)] + match self { + Self::V0(_) => 0, +Self::V1(_) => 1, + } + } - #[must_use] - pub const fn name(&self) -> &'static str { - match self { - Self::V0(_) => "V0", - Self::V1(_) => "V1", + #[must_use] + pub const fn variants() -> [i32; 2] { + Self::VARIANTS + } } - } - #[must_use] - pub const fn discriminant(&self) -> i32 { - #[allow(clippy::match_same_arms)] - match self { - Self::V0(_) => 0, - Self::V1(_) => 1, + impl Name for IntUnion { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - pub const fn variants() -> [i32; 2] { - Self::VARIANTS - } -} -impl Name for IntUnion { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Discriminant for IntUnion { - #[must_use] - fn discriminant(&self) -> i32 { - Self::discriminant(self) - } -} + impl Discriminant for IntUnion { + #[must_use] + fn discriminant(&self) -> i32 { + Self::discriminant(self) + } + } -impl Variants for IntUnion { - fn variants() -> slice::Iter<'static, i32> { - Self::VARIANTS.iter() - } -} + impl Variants for IntUnion { + fn variants() -> slice::Iter<'static, i32> { + Self::VARIANTS.iter() + } + } -impl Union for IntUnion {} + impl Union for IntUnion {} -impl ReadXdr for IntUnion { - #[cfg(feature = "std")] - fn read_xdr(r: &mut Limited) -> Result { - r.with_limited_depth(|r| { - let dv: i32 = ::read_xdr(r)?; - #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] - let v = match dv { - 0 => Self::V0(i32::read_xdr(r)?), - 1 => Self::V1(VecM::::read_xdr(r)?), - #[allow(unreachable_patterns)] - _ => return Err(Error::Invalid), - }; - Ok(v) - }) - } -} + impl ReadXdr for IntUnion { + #[cfg(feature = "std")] + fn read_xdr(r: &mut Limited) -> Result { + r.with_limited_depth(|r| { + let dv: i32 = ::read_xdr(r)?; + #[allow(clippy::match_same_arms, clippy::match_wildcard_for_single_variants)] + let v = match dv { + 0 => Self::V0(i32::read_xdr(r)?), +1 => Self::V1(VecM::::read_xdr(r)?), + #[allow(unreachable_patterns)] + _ => return Err(Error::Invalid), + }; + Ok(v) + }) + } + } -impl WriteXdr for IntUnion { - #[cfg(feature = "std")] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| { - self.discriminant().write_xdr(w)?; - #[allow(clippy::match_same_arms)] - match self { - Self::V0(v) => v.write_xdr(w)?, - Self::V1(v) => v.write_xdr(w)?, - }; - Ok(()) - }) - } -} + impl WriteXdr for IntUnion { + #[cfg(feature = "std")] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + w.with_limited_depth(|w| { + self.discriminant().write_xdr(w)?; + #[allow(clippy::match_same_arms)] + match self { + Self::V0(v) => v.write_xdr(w)?, +Self::V1(v) => v.write_xdr(w)?, + }; + Ok(()) + }) + } + } /// IntUnion2 is an XDR Typedef defines as: /// @@ -3093,20 +3154,8 @@ impl WriteXdr for IntUnion { /// #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] +#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[derive(Debug)] pub struct IntUnion2(pub IntUnion); @@ -3145,407 +3194,299 @@ impl ReadXdr for IntUnion2 { impl WriteXdr for IntUnion2 { #[cfg(feature = "std")] fn write_xdr(&self, w: &mut Limited) -> Result<()> { - w.with_limited_depth(|w| self.0.write_xdr(w)) - } -} - -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case") -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum TypeVariant { - SError, - Multi, - UnionKey, - MyUnion, - IntUnion, - IntUnion2, -} - -impl TypeVariant { - pub const VARIANTS: [TypeVariant; 6] = [ - TypeVariant::SError, - TypeVariant::Multi, - TypeVariant::UnionKey, - TypeVariant::MyUnion, - TypeVariant::IntUnion, - TypeVariant::IntUnion2, - ]; - pub const VARIANTS_STR: [&'static str; 6] = [ - "SError", - "Multi", - "UnionKey", - "MyUnion", - "IntUnion", - "IntUnion2", - ]; + w.with_limited_depth(|w|{ self.0.write_xdr(w) }) + } +} + + #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum TypeVariant { + SError, +Multi, +UnionKey, +MyUnion, +IntUnion, +IntUnion2, + } + + impl TypeVariant { + pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, +TypeVariant::Multi, +TypeVariant::UnionKey, +TypeVariant::MyUnion, +TypeVariant::IntUnion, +TypeVariant::IntUnion2, ]; + pub const VARIANTS_STR: [&'static str; 6] = [ "SError", +"Multi", +"UnionKey", +"MyUnion", +"IntUnion", +"IntUnion2", ]; + + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError => "SError", +Self::Multi => "Multi", +Self::UnionKey => "UnionKey", +Self::MyUnion => "MyUnion", +Self::IntUnion => "IntUnion", +Self::IntUnion2 => "IntUnion2", + } + } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError => "SError", - Self::Multi => "Multi", - Self::UnionKey => "UnionKey", - Self::MyUnion => "MyUnion", - Self::IntUnion => "IntUnion", - Self::IntUnion2 => "IntUnion2", + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } -} -impl Name for TypeVariant { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} + impl Name for TypeVariant { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } + } -impl Variants for TypeVariant { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} + impl Variants for TypeVariant { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } + } -impl core::str::FromStr for TypeVariant { - type Err = Error; - #[allow(clippy::too_many_lines)] - fn from_str(s: &str) -> Result { - match s { - "SError" => Ok(Self::SError), - "Multi" => Ok(Self::Multi), - "UnionKey" => Ok(Self::UnionKey), - "MyUnion" => Ok(Self::MyUnion), - "IntUnion" => Ok(Self::IntUnion), - "IntUnion2" => Ok(Self::IntUnion2), - _ => Err(Error::Invalid), + impl core::str::FromStr for TypeVariant { + type Err = Error; + #[allow(clippy::too_many_lines)] + fn from_str(s: &str) -> Result { + match s { + "SError" => Ok(Self::SError), +"Multi" => Ok(Self::Multi), +"UnionKey" => Ok(Self::UnionKey), +"MyUnion" => Ok(Self::MyUnion), +"IntUnion" => Ok(Self::IntUnion), +"IntUnion2" => Ok(Self::IntUnion2), + _ => Err(Error::Invalid), + } + } } - } -} -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[cfg_attr( - all(feature = "serde", feature = "alloc"), - derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema), - serde(rename_all = "snake_case"), - serde(untagged) -)] -#[cfg_attr( - all( - feature = "schemars", - feature = "serde", - feature = "serde_json", - feature = "alloc" - ), - derive(schemars::JsonSchema) -)] -pub enum Type { - SError(Box), - Multi(Box), - UnionKey(Box), - MyUnion(Box), - IntUnion(Box), - IntUnion2(Box), -} - -impl Type { - pub const VARIANTS: [TypeVariant; 6] = [ - TypeVariant::SError, - TypeVariant::Multi, - TypeVariant::UnionKey, - TypeVariant::MyUnion, - TypeVariant::IntUnion, - TypeVariant::IntUnion2, - ]; - pub const VARIANTS_STR: [&'static str; 6] = [ - "SError", - "Multi", - "UnionKey", - "MyUnion", - "IntUnion", - "IntUnion2", - ]; + #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] + #[cfg_attr( + all(feature = "serde", feature = "alloc"), + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case"), + serde(untagged), + )] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub enum Type { + SError(Box), +Multi(Box), +UnionKey(Box), +MyUnion(Box), +IntUnion(Box), +IntUnion2(Box), + } + + impl Type { + pub const VARIANTS: [TypeVariant; 6] = [ TypeVariant::SError, +TypeVariant::Multi, +TypeVariant::UnionKey, +TypeVariant::MyUnion, +TypeVariant::IntUnion, +TypeVariant::IntUnion2, ]; + pub const VARIANTS_STR: [&'static str; 6] = [ "SError", +"Multi", +"UnionKey", +"MyUnion", +"IntUnion", +"IntUnion2", ]; - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { - match v { - TypeVariant::SError => { - r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))) - } - TypeVariant::Multi => { - r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))) - } - TypeVariant::UnionKey => { - r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))) + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr(v: TypeVariant, r: &mut Limited) -> Result { + match v { + TypeVariant::SError => r.with_limited_depth(|r| Ok(Self::SError(Box::new(SError::read_xdr(r)?)))), +TypeVariant::Multi => r.with_limited_depth(|r| Ok(Self::Multi(Box::new(Multi::read_xdr(r)?)))), +TypeVariant::UnionKey => r.with_limited_depth(|r| Ok(Self::UnionKey(Box::new(UnionKey::read_xdr(r)?)))), +TypeVariant::MyUnion => r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))), +TypeVariant::IntUnion => r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))), +TypeVariant::IntUnion2 => r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))), + } } - TypeVariant::MyUnion => { - r.with_limited_depth(|r| Ok(Self::MyUnion(Box::new(MyUnion::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr(v, &mut dec)?; + Ok(t) } - TypeVariant::IntUnion => { - r.with_limited_depth(|r| Ok(Self::IntUnion(Box::new(IntUnion::read_xdr(r)?)))) + + #[cfg(feature = "std")] + pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let s = Self::read_xdr(v, r)?; + // Check that any further reads, such as this read of one byte, read no + // data, indicating EOF. If a byte is read the data is invalid. + if r.read(&mut [0u8; 1])? == 0 { + Ok(s) + } else { + Err(Error::Invalid) + } } - TypeVariant::IntUnion2 => { - r.with_limited_depth(|r| Ok(Self::IntUnion2(Box::new(IntUnion2::read_xdr(r)?)))) + + #[cfg(feature = "base64")] + pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), r.limits.clone()); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) } - } - } - #[cfg(feature = "base64")] - pub fn read_xdr_base64(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - pub fn read_xdr_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let s = Self::read_xdr(v, r)?; - // Check that any further reads, such as this read of one byte, read no - // data, indicating EOF. If a byte is read the data is invalid. - if r.read(&mut [0u8; 1])? == 0 { - Ok(s) - } else { - Err(Error::Invalid) - } - } + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_framed_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t.0))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t.0))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t.0))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t.0))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t.0))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0))))), + } + } - #[cfg(feature = "base64")] - pub fn read_xdr_base64_to_end(v: TypeVariant, r: &mut Limited) -> Result { - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD), - r.limits.clone(), - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[cfg(feature = "base64")] + #[allow(clippy::too_many_lines)] + pub fn read_xdr_base64_iter(v: TypeVariant, r: &mut Limited) -> Box> + '_> { + let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); + match v { + TypeVariant::SError => Box::new(ReadXdrIter::<_, SError>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::SError(Box::new(t))))), +TypeVariant::Multi => Box::new(ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::Multi(Box::new(t))))), +TypeVariant::UnionKey => Box::new(ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::UnionKey(Box::new(t))))), +TypeVariant::MyUnion => Box::new(ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::MyUnion(Box::new(t))))), +TypeVariant::IntUnion => Box::new(ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion(Box::new(t))))), +TypeVariant::IntUnion2 => Box::new(ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()).map(|r| r.map(|t| Self::IntUnion2(Box::new(t))))), + } + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new( - ReadXdrIter::<_, SError>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::SError(Box::new(t)))), - ), - TypeVariant::Multi => Box::new( - ReadXdrIter::<_, Multi>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Multi(Box::new(t)))), - ), - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::IntUnion => Box::new( - ReadXdrIter::<_, IntUnion>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), - ), - TypeVariant::IntUnion2 => Box::new( - ReadXdrIter::<_, IntUnion2>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), - ), - } - } + #[cfg(feature = "std")] + pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { + let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); + let t = Self::read_xdr_to_end(v, &mut cursor)?; + Ok(t) + } - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_framed_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - match v { - TypeVariant::SError => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::SError(Box::new(t.0)))), - ), - TypeVariant::Multi => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::Multi(Box::new(t.0)))), - ), - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t.0)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t.0)))), - ), - TypeVariant::IntUnion => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion(Box::new(t.0)))), - ), - TypeVariant::IntUnion2 => Box::new( - ReadXdrIter::<_, Frame>::new(&mut r.inner, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion2(Box::new(t.0)))), - ), - } - } + #[cfg(feature = "base64")] + pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { + let mut b64_reader = Cursor::new(b64); + let mut dec = Limited::new(base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), limits); + let t = Self::read_xdr_to_end(v, &mut dec)?; + Ok(t) + } - #[cfg(feature = "base64")] - #[allow(clippy::too_many_lines)] - pub fn read_xdr_base64_iter( - v: TypeVariant, - r: &mut Limited, - ) -> Box> + '_> { - let dec = base64::read::DecoderReader::new(&mut r.inner, base64::STANDARD); - match v { - TypeVariant::SError => Box::new( - ReadXdrIter::<_, SError>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::SError(Box::new(t)))), - ), - TypeVariant::Multi => Box::new( - ReadXdrIter::<_, Multi>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::Multi(Box::new(t)))), - ), - TypeVariant::UnionKey => Box::new( - ReadXdrIter::<_, UnionKey>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::UnionKey(Box::new(t)))), - ), - TypeVariant::MyUnion => Box::new( - ReadXdrIter::<_, MyUnion>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::MyUnion(Box::new(t)))), - ), - TypeVariant::IntUnion => Box::new( - ReadXdrIter::<_, IntUnion>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion(Box::new(t)))), - ), - TypeVariant::IntUnion2 => Box::new( - ReadXdrIter::<_, IntUnion2>::new(dec, r.limits.clone()) - .map(|r| r.map(|t| Self::IntUnion2(Box::new(t)))), - ), - } - } + #[cfg(all(feature = "std", feature = "serde_json"))] + #[allow(clippy::too_many_lines)] + pub fn read_json(v: TypeVariant, r: impl Read) -> Result { + match v { + TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), +TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), +TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), +TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), +TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), + } + } - #[cfg(feature = "std")] - pub fn from_xdr>(v: TypeVariant, bytes: B, limits: Limits) -> Result { - let mut cursor = Limited::new(Cursor::new(bytes.as_ref()), limits); - let t = Self::read_xdr_to_end(v, &mut cursor)?; - Ok(t) - } + #[cfg(feature = "alloc")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn value(&self) -> &dyn core::any::Any { + #[allow(clippy::match_same_arms)] + match self { + Self::SError(ref v) => v.as_ref(), +Self::Multi(ref v) => v.as_ref(), +Self::UnionKey(ref v) => v.as_ref(), +Self::MyUnion(ref v) => v.as_ref(), +Self::IntUnion(ref v) => v.as_ref(), +Self::IntUnion2(ref v) => v.as_ref(), + } + } - #[cfg(feature = "base64")] - pub fn from_xdr_base64(v: TypeVariant, b64: impl AsRef<[u8]>, limits: Limits) -> Result { - let mut b64_reader = Cursor::new(b64); - let mut dec = Limited::new( - base64::read::DecoderReader::new(&mut b64_reader, base64::STANDARD), - limits, - ); - let t = Self::read_xdr_to_end(v, &mut dec)?; - Ok(t) - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn name(&self) -> &'static str { + match self { + Self::SError(_) => "SError", +Self::Multi(_) => "Multi", +Self::UnionKey(_) => "UnionKey", +Self::MyUnion(_) => "MyUnion", +Self::IntUnion(_) => "IntUnion", +Self::IntUnion2(_) => "IntUnion2", + } + } - #[cfg(all(feature = "std", feature = "serde_json"))] - #[allow(clippy::too_many_lines)] - pub fn read_json(v: TypeVariant, r: impl Read) -> Result { - match v { - TypeVariant::SError => Ok(Self::SError(Box::new(serde_json::from_reader(r)?))), - TypeVariant::Multi => Ok(Self::Multi(Box::new(serde_json::from_reader(r)?))), - TypeVariant::UnionKey => Ok(Self::UnionKey(Box::new(serde_json::from_reader(r)?))), - TypeVariant::MyUnion => Ok(Self::MyUnion(Box::new(serde_json::from_reader(r)?))), - TypeVariant::IntUnion => Ok(Self::IntUnion(Box::new(serde_json::from_reader(r)?))), - TypeVariant::IntUnion2 => Ok(Self::IntUnion2(Box::new(serde_json::from_reader(r)?))), - } - } + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variants() -> [TypeVariant; 6] { + Self::VARIANTS + } - #[cfg(feature = "alloc")] - #[must_use] - #[allow(clippy::too_many_lines)] - pub fn value(&self) -> &dyn core::any::Any { - #[allow(clippy::match_same_arms)] - match self { - Self::SError(ref v) => v.as_ref(), - Self::Multi(ref v) => v.as_ref(), - Self::UnionKey(ref v) => v.as_ref(), - Self::MyUnion(ref v) => v.as_ref(), - Self::IntUnion(ref v) => v.as_ref(), - Self::IntUnion2(ref v) => v.as_ref(), + #[must_use] + #[allow(clippy::too_many_lines)] + pub const fn variant(&self) -> TypeVariant { + match self { + Self::SError(_) => TypeVariant::SError, +Self::Multi(_) => TypeVariant::Multi, +Self::UnionKey(_) => TypeVariant::UnionKey, +Self::MyUnion(_) => TypeVariant::MyUnion, +Self::IntUnion(_) => TypeVariant::IntUnion, +Self::IntUnion2(_) => TypeVariant::IntUnion2, + } + } } - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn name(&self) -> &'static str { - match self { - Self::SError(_) => "SError", - Self::Multi(_) => "Multi", - Self::UnionKey(_) => "UnionKey", - Self::MyUnion(_) => "MyUnion", - Self::IntUnion(_) => "IntUnion", - Self::IntUnion2(_) => "IntUnion2", + impl Name for Type { + #[must_use] + fn name(&self) -> &'static str { + Self::name(self) + } } - } - - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variants() -> [TypeVariant; 6] { - Self::VARIANTS - } - #[must_use] - #[allow(clippy::too_many_lines)] - pub const fn variant(&self) -> TypeVariant { - match self { - Self::SError(_) => TypeVariant::SError, - Self::Multi(_) => TypeVariant::Multi, - Self::UnionKey(_) => TypeVariant::UnionKey, - Self::MyUnion(_) => TypeVariant::MyUnion, - Self::IntUnion(_) => TypeVariant::IntUnion, - Self::IntUnion2(_) => TypeVariant::IntUnion2, + impl Variants for Type { + fn variants() -> slice::Iter<'static, TypeVariant> { + Self::VARIANTS.iter() + } } - } -} - -impl Name for Type { - #[must_use] - fn name(&self) -> &'static str { - Self::name(self) - } -} - -impl Variants for Type { - fn variants() -> slice::Iter<'static, TypeVariant> { - Self::VARIANTS.iter() - } -} -impl WriteXdr for Type { - #[cfg(feature = "std")] - #[allow(clippy::too_many_lines)] - fn write_xdr(&self, w: &mut Limited) -> Result<()> { - match self { - Self::SError(v) => v.write_xdr(w), - Self::Multi(v) => v.write_xdr(w), - Self::UnionKey(v) => v.write_xdr(w), - Self::MyUnion(v) => v.write_xdr(w), - Self::IntUnion(v) => v.write_xdr(w), - Self::IntUnion2(v) => v.write_xdr(w), + impl WriteXdr for Type { + #[cfg(feature = "std")] + #[allow(clippy::too_many_lines)] + fn write_xdr(&self, w: &mut Limited) -> Result<()> { + match self { + Self::SError(v) => v.write_xdr(w), +Self::Multi(v) => v.write_xdr(w), +Self::UnionKey(v) => v.write_xdr(w), +Self::MyUnion(v) => v.write_xdr(w), +Self::IntUnion(v) => v.write_xdr(w), +Self::IntUnion2(v) => v.write_xdr(w), + } + } } - } -} From 5106ff6773ac8ebfb9e5cd14cb0677bb47178f30 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 8 Mar 2024 21:33:20 +1000 Subject: [PATCH 08/20] fix cas --- lib/xdrgen/generators/rust.rb | 4 ++-- spec/output/generator_spec_rust/test.x/MyXDR.rs | 8 ++++---- .../test.x/MyXDR.rs | 8 ++++---- .../generator_spec_rust_custom_str_impls/test.x/MyXDR.rs | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index a5fc1a8af..f94225ec5 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -756,8 +756,8 @@ def render_typedef(out, typedef) serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: SOME(MAX * 2), - min_length: SOME(MAX * 2), + max_length: Some(MAX * 2), + min_length: Some(MAX * 2), ..string }) } else { diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index 6e98de668..b73d8cc3d 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -2865,8 +2865,8 @@ impl schemars::JsonSchema for Uint512 { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: SOME(MAX * 2), - min_length: SOME(MAX * 2), + max_length: Some(MAX * 2), + min_length: Some(MAX * 2), ..string }) } else { @@ -3419,8 +3419,8 @@ impl schemars::JsonSchema for Hash { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: SOME(MAX * 2), - min_length: SOME(MAX * 2), + max_length: Some(MAX * 2), + min_length: Some(MAX * 2), ..string }) } else { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index 8565c0653..ffc885351 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -2865,8 +2865,8 @@ impl schemars::JsonSchema for Uint512 { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: SOME(MAX * 2), - min_length: SOME(MAX * 2), + max_length: Some(MAX * 2), + min_length: Some(MAX * 2), ..string }) } else { @@ -3419,8 +3419,8 @@ impl schemars::JsonSchema for Hash { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: SOME(MAX * 2), - min_length: SOME(MAX * 2), + max_length: Some(MAX * 2), + min_length: Some(MAX * 2), ..string }) } else { diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index 7e41b6201..9ea880770 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -2865,8 +2865,8 @@ impl schemars::JsonSchema for Uint512 { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: SOME(MAX * 2), - min_length: SOME(MAX * 2), + max_length: Some(MAX * 2), + min_length: Some(MAX * 2), ..string }) } else { @@ -3419,8 +3419,8 @@ impl schemars::JsonSchema for Hash { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: SOME(MAX * 2), - min_length: SOME(MAX * 2), + max_length: Some(MAX * 2), + min_length: Some(MAX * 2), ..string }) } else { From c95a5bd7f9dff8dff53cadcef3014ceb69ab7088 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:36:17 +1000 Subject: [PATCH 09/20] fix --- lib/xdrgen/generators/rust.rb | 13 ++++++++++--- lib/xdrgen/generators/rust/src/types.rs | 4 ++-- .../block_comments.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/const.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/enum.x/MyXDR.rs | 4 ++-- .../generator_spec_rust/nesting.x/MyXDR.rs | 4 ++-- .../generator_spec_rust/optional.x/MyXDR.rs | 4 ++-- .../output/generator_spec_rust/struct.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/test.x/MyXDR.rs | 16 ++++++++-------- spec/output/generator_spec_rust/union.x/MyXDR.rs | 4 ++-- .../block_comments.x/MyXDR.rs | 4 ++-- .../const.x/MyXDR.rs | 4 ++-- .../enum.x/MyXDR.rs | 4 ++-- .../nesting.x/MyXDR.rs | 4 ++-- .../optional.x/MyXDR.rs | 4 ++-- .../struct.x/MyXDR.rs | 4 ++-- .../test.x/MyXDR.rs | 16 ++++++++-------- .../union.x/MyXDR.rs | 4 ++-- .../block_comments.x/MyXDR.rs | 4 ++-- .../const.x/MyXDR.rs | 4 ++-- .../enum.x/MyXDR.rs | 4 ++-- .../nesting.x/MyXDR.rs | 4 ++-- .../optional.x/MyXDR.rs | 4 ++-- .../struct.x/MyXDR.rs | 4 ++-- .../test.x/MyXDR.rs | 16 ++++++++-------- .../union.x/MyXDR.rs | 4 ++-- 26 files changed, 78 insertions(+), 71 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index f94225ec5..cad86baeb 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -689,7 +689,7 @@ def render_typedef(out, typedef) else out.puts %{#[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]} end - if !@options[:rust_types_custom_jsonschema_impl].include?(name typedef) + if !is_fixed_array_opaque(typedef.type) && !@options[:rust_types_custom_jsonschema_impl].include?(name typedef) out.puts %{#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]} end if !is_fixed_array_opaque(typedef.type) @@ -735,6 +735,7 @@ def render_typedef(out, typedef) end if is_fixed_array_opaque(typedef.type) && !@options[:rust_types_custom_jsonschema_impl].include?(name typedef) out.puts <<-EOS.strip_heredoc + #[cfg(feature = "schemars")] impl schemars::JsonSchema for #{name typedef} { fn schema_name() -> String { "#{name typedef}".to_string() @@ -756,8 +757,8 @@ def render_typedef(out, typedef) serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), - min_length: Some(MAX * 2), + max_length: Some(#{typedef.type.size} * 2), + min_length: Some(#{typedef.type.size} * 2), ..string }) } else { @@ -979,6 +980,12 @@ def base_reference(type) end end + def array_size(type) + _, size = type.array_size + size = name @top.find_definition(size) if is_named + size + end + def reference(parent, type) base_ref = base_reference type diff --git a/lib/xdrgen/generators/rust/src/types.rs b/lib/xdrgen/generators/rust/src/types.rs index 68544dcda..370853486 100644 --- a/lib/xdrgen/generators/rust/src/types.rs +++ b/lib/xdrgen/generators/rust/src/types.rs @@ -1346,7 +1346,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1766,7 +1766,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index b5de5241a..91eb32065 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index ed83d1639..f4a88a37e 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index 9467d91ad..d73214e63 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 7a7cbe5e2..3096221a9 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 89b4e1caa..b07ca1435 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index 8dc15e900..804b728a1 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index b73d8cc3d..3015f9fd8 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { @@ -2813,7 +2813,6 @@ mod test { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2844,6 +2843,7 @@ impl core::str::FromStr for Uint512 { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +#[cfg(feature = "schemars")] impl schemars::JsonSchema for Uint512 { fn schema_name() -> String { "Uint512".to_string() @@ -2865,8 +2865,8 @@ impl schemars::JsonSchema for Uint512 { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), - min_length: Some(MAX * 2), + max_length: Some(64 * 2), + min_length: Some(64 * 2), ..string }) } else { @@ -3367,7 +3367,6 @@ impl AsRef<[u8]> for Str2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3398,6 +3397,7 @@ impl core::str::FromStr for Hash { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +#[cfg(feature = "schemars")] impl schemars::JsonSchema for Hash { fn schema_name() -> String { "Hash".to_string() @@ -3419,8 +3419,8 @@ impl schemars::JsonSchema for Hash { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), - min_length: Some(MAX * 2), + max_length: Some(32 * 2), + min_length: Some(32 * 2), ..string }) } else { diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 85f23b584..810912533 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index b5de5241a..91eb32065 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index ed83d1639..f4a88a37e 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index a3e12de51..b84df5bd0 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index 4ee0a2ef2..5ed0789cd 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index 3e1fc448d..f60216665 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index 734f1a959..ab528732c 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index ffc885351..5cb56a201 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { @@ -2813,7 +2813,6 @@ mod test { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2844,6 +2843,7 @@ impl core::str::FromStr for Uint512 { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +#[cfg(feature = "schemars")] impl schemars::JsonSchema for Uint512 { fn schema_name() -> String { "Uint512".to_string() @@ -2865,8 +2865,8 @@ impl schemars::JsonSchema for Uint512 { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), - min_length: Some(MAX * 2), + max_length: Some(64 * 2), + min_length: Some(64 * 2), ..string }) } else { @@ -3367,7 +3367,6 @@ impl AsRef<[u8]> for Str2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3398,6 +3397,7 @@ impl core::str::FromStr for Hash { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +#[cfg(feature = "schemars")] impl schemars::JsonSchema for Hash { fn schema_name() -> String { "Hash".to_string() @@ -3419,8 +3419,8 @@ impl schemars::JsonSchema for Hash { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), - min_length: Some(MAX * 2), + max_length: Some(32 * 2), + min_length: Some(32 * 2), ..string }) } else { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index 43fb37cc8..6894b7691 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index b5de5241a..91eb32065 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index ed83d1639..f4a88a37e 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index 3757516c0..a579b3353 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 9a75889d5..b59888bcd 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index 50750f474..79b37e0cf 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index 36ba22dfc..9c99ec99e 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index 9ea880770..623ec6e59 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { @@ -2813,7 +2813,6 @@ mod test { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Uint512(pub [u8; 64]); impl core::fmt::Debug for Uint512 { @@ -2844,6 +2843,7 @@ impl core::str::FromStr for Uint512 { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +#[cfg(feature = "schemars")] impl schemars::JsonSchema for Uint512 { fn schema_name() -> String { "Uint512".to_string() @@ -2865,8 +2865,8 @@ impl schemars::JsonSchema for Uint512 { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), - min_length: Some(MAX * 2), + max_length: Some(64 * 2), + min_length: Some(64 * 2), ..string }) } else { @@ -3367,7 +3367,6 @@ impl AsRef<[u8]> for Str2 { #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "arbitrary", derive(Arbitrary))] #[cfg_attr(all(feature = "serde", feature = "alloc"), derive(serde_with::SerializeDisplay, serde_with::DeserializeFromStr))] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Hash(pub [u8; 32]); impl core::fmt::Debug for Hash { @@ -3398,6 +3397,7 @@ impl core::str::FromStr for Hash { hex::decode(s).map_err(|_| Error::InvalidHex)?.try_into() } } +#[cfg(feature = "schemars")] impl schemars::JsonSchema for Hash { fn schema_name() -> String { "Hash".to_string() @@ -3419,8 +3419,8 @@ impl schemars::JsonSchema for Hash { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), - min_length: Some(MAX * 2), + max_length: Some(32 * 2), + min_length: Some(32 * 2), ..string }) } else { diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index d1bf85279..3cb27654b 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -1356,7 +1356,7 @@ impl Deref for BytesM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for BytesM { fn schema_name() -> String { - format!("BytesM<{}>", MAX) + format!("BytesM<{MAX}>") } fn is_referenceable() -> bool { @@ -1776,7 +1776,7 @@ impl Default for StringM { #[cfg(feature = "schemars")] impl schemars::JsonSchema for StringM { fn schema_name() -> String { - format!("StringM<{}>", MAX) + format!("StringM<{MAX}>") } fn is_referenceable() -> bool { From 3f37191c1b26b39a4a8265a3824df6c3236cb120 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sat, 9 Mar 2024 01:28:29 +1000 Subject: [PATCH 10/20] fix --- lib/xdrgen/generators/rust.rb | 4 ++-- lib/xdrgen/generators/rust/src/types.rs | 2 +- .../generator_spec_rust/block_comments.x/MyXDR.rs | 2 +- spec/output/generator_spec_rust/const.x/MyXDR.rs | 2 +- spec/output/generator_spec_rust/enum.x/MyXDR.rs | 2 +- spec/output/generator_spec_rust/nesting.x/MyXDR.rs | 2 +- spec/output/generator_spec_rust/optional.x/MyXDR.rs | 2 +- spec/output/generator_spec_rust/struct.x/MyXDR.rs | 2 +- spec/output/generator_spec_rust/test.x/MyXDR.rs | 10 +++++----- spec/output/generator_spec_rust/union.x/MyXDR.rs | 2 +- .../block_comments.x/MyXDR.rs | 2 +- .../const.x/MyXDR.rs | 2 +- .../enum.x/MyXDR.rs | 2 +- .../nesting.x/MyXDR.rs | 2 +- .../optional.x/MyXDR.rs | 2 +- .../struct.x/MyXDR.rs | 2 +- .../test.x/MyXDR.rs | 10 +++++----- .../union.x/MyXDR.rs | 2 +- .../block_comments.x/MyXDR.rs | 2 +- .../const.x/MyXDR.rs | 2 +- .../enum.x/MyXDR.rs | 2 +- .../nesting.x/MyXDR.rs | 2 +- .../optional.x/MyXDR.rs | 2 +- .../struct.x/MyXDR.rs | 2 +- .../test.x/MyXDR.rs | 10 +++++----- .../union.x/MyXDR.rs | 2 +- 26 files changed, 39 insertions(+), 39 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index cad86baeb..6f099e8ff 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -757,8 +757,8 @@ def render_typedef(out, typedef) serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(#{typedef.type.size} * 2), - min_length: Some(#{typedef.type.size} * 2), + max_length: #{typedef.type.size}_u32.checked_mul(2).map(Some).unwrap_or_default(), + min_length: #{typedef.type.size}_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string }) } else { diff --git a/lib/xdrgen/generators/rust/src/types.rs b/lib/xdrgen/generators/rust/src/types.rs index 370853486..b05ad3545 100644 --- a/lib/xdrgen/generators/rust/src/types.rs +++ b/lib/xdrgen/generators/rust/src/types.rs @@ -1365,7 +1365,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index 91eb32065..0e0b7430d 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index f4a88a37e..97a9a2842 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index d73214e63..8d932017b 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 3096221a9..1bbde146f 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index b07ca1435..3e88019ba 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index 804b728a1..8654cb413 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index 3015f9fd8..b05276e28 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) @@ -2865,8 +2865,8 @@ impl schemars::JsonSchema for Uint512 { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(64 * 2), - min_length: Some(64 * 2), + max_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), + min_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string }) } else { @@ -3419,8 +3419,8 @@ impl schemars::JsonSchema for Hash { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(32 * 2), - min_length: Some(32 * 2), + max_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), + min_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string }) } else { diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 810912533..6f270fddf 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index 91eb32065..0e0b7430d 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index f4a88a37e..97a9a2842 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index b84df5bd0..2e1e79efd 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index 5ed0789cd..ccfd3f37d 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index f60216665..2e112ddb6 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index ab528732c..062d1a5f0 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index 5cb56a201..c9acfff5e 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) @@ -2865,8 +2865,8 @@ impl schemars::JsonSchema for Uint512 { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(64 * 2), - min_length: Some(64 * 2), + max_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), + min_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string }) } else { @@ -3419,8 +3419,8 @@ impl schemars::JsonSchema for Hash { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(32 * 2), - min_length: Some(32 * 2), + max_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), + min_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string }) } else { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index 6894b7691..4c627c402 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index 91eb32065..0e0b7430d 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index f4a88a37e..97a9a2842 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index a579b3353..cde29d5f7 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index b59888bcd..3e635339c 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index 79b37e0cf..6adea8224 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index 9c99ec99e..9d38eb31e 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index 623ec6e59..df29abfe4 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) @@ -2865,8 +2865,8 @@ impl schemars::JsonSchema for Uint512 { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(64 * 2), - min_length: Some(64 * 2), + max_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), + min_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string }) } else { @@ -3419,8 +3419,8 @@ impl schemars::JsonSchema for Hash { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(32 * 2), - min_length: Some(32 * 2), + max_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), + min_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string }) } else { diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index 3cb27654b..6cb7ea3ce 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -1375,7 +1375,7 @@ impl schemars::JsonSchema for BytesM { serde_json::Value::String("application/binary".to_string()), ); mut_string(schema.into(), |string| schemars::schema::StringValidation { - max_length: Some(MAX * 2), + max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string }) From 87d633c780260e2a30a28d7dc9571a790f5138fa Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 13 Mar 2024 22:11:30 +1000 Subject: [PATCH 11/20] add type macro --- lib/xdrgen/generators/rust.rb | 21 +++++++++++++++++++++ lib/xdrgen/output.rb | 14 ++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index 6f099e8ff..a548640ea 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -16,6 +16,7 @@ def generate render_top_matter(out) render_lib(out) render_definitions(out, @top) + render_type_macro(out, @types) render_enum_of_all_types(out, @types) out.break end @@ -94,6 +95,26 @@ def render_lib(out) out.break end + def render_type_macro(out, types) + out.puts <<-EOS.strip_heredoc + #[doc(hidden)] + #[macro_export] + macro_rules! _call_macro_with_each_type_#{@output.inputs_hash} { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + #{types.map do |t| + <<-EOS + $macro_to_call_back!(#{t}, $($context),*); + EOS + end.join("\n")} + + }}; + } + pub use _call_macro_with_each_type_#{@output.inputs_hash} as call_macro_with_each_type; + EOS + end + def render_enum_of_all_types(out, types) out.puts <<-EOS.strip_heredoc #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] diff --git a/lib/xdrgen/output.rb b/lib/xdrgen/output.rb index 412f7247c..4f598406d 100644 --- a/lib/xdrgen/output.rb +++ b/lib/xdrgen/output.rb @@ -13,6 +13,16 @@ def initialize(source_paths, output_dir) @files = {} end + def inputs_hash + Digest::SHA256.hexdigest( + [ + Digest::SHA256.hexdigest(relative_source_paths.map { |p| Digest::SHA256.file(p).hexdigest }.join), + Digest::SHA256.hexdigest(@source_paths.map { |p| Digest::SHA256.hexdigest(p) }.join), + Digest::SHA256.hexdigest(@output_dir), + ].join + ) + end + def relative_source_paths @source_paths.map { |p| Pathname.new(p).expand_path.relative_path_from(Dir.pwd).to_s }.sort end @@ -21,6 +31,10 @@ def relative_source_path_sha256_hashes relative_source_paths.map { |p| [p, Digest::SHA256.file(p).hexdigest] }.to_h end + def relative_source_path_sha256_hash + Digest::SHA256.hexdigest(relative_source_paths.map { |p| Digest::SHA256.file(p).hexdigest }.join) + end + def open(child_path) if @files.has_key?(child_path) raise Xdrgen::DuplicateFileError, "Cannot open #{child_path} twice" From 4ea81a540e25623567badd1f7dd649cc46cf9f21 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 13 Mar 2024 23:01:29 +1000 Subject: [PATCH 12/20] add simple methnod for generating json schema --- lib/xdrgen/generators/rust.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index a548640ea..e6ae79fae 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -145,6 +145,15 @@ def render_enum_of_all_types(out, types) pub const fn variants() -> [TypeVariant; #{types.count}] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + #{types.map { |t| "Self::#{t} => gen.into_root_schema_for::<#{t}>()," }.join("\n")} + } + } } impl Name for TypeVariant { From 20635799f4e8fd9628f744bfffa02d6875670ce5 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 14 Mar 2024 13:09:53 +1000 Subject: [PATCH 13/20] upd tests --- .../block_comments.x/MyXDR.rs | 21 +++++ .../generator_spec_rust/const.x/MyXDR.rs | 24 +++++ .../generator_spec_rust/enum.x/MyXDR.rs | 27 ++++++ .../generator_spec_rust/nesting.x/MyXDR.rs | 33 +++++++ .../generator_spec_rust/optional.x/MyXDR.rs | 24 +++++ .../generator_spec_rust/struct.x/MyXDR.rs | 24 +++++ .../generator_spec_rust/test.x/MyXDR.rs | 87 +++++++++++++++++++ .../generator_spec_rust/union.x/MyXDR.rs | 36 ++++++++ .../block_comments.x/MyXDR.rs | 21 +++++ .../const.x/MyXDR.rs | 24 +++++ .../enum.x/MyXDR.rs | 27 ++++++ .../nesting.x/MyXDR.rs | 33 +++++++ .../optional.x/MyXDR.rs | 24 +++++ .../struct.x/MyXDR.rs | 24 +++++ .../test.x/MyXDR.rs | 87 +++++++++++++++++++ .../union.x/MyXDR.rs | 36 ++++++++ .../block_comments.x/MyXDR.rs | 21 +++++ .../const.x/MyXDR.rs | 24 +++++ .../enum.x/MyXDR.rs | 27 ++++++ .../nesting.x/MyXDR.rs | 33 +++++++ .../optional.x/MyXDR.rs | 24 +++++ .../struct.x/MyXDR.rs | 24 +++++ .../test.x/MyXDR.rs | 87 +++++++++++++++++++ .../union.x/MyXDR.rs | 36 ++++++++ 24 files changed, 828 insertions(+) diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index 0e0b7430d..cfde7507d 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -2902,6 +2902,18 @@ impl WriteXdr for AccountFlags { } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_9d0f06a028d93fff5280b1251f38188afa3499e5f6893a4152f411801a4981fa { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(AccountFlags, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_9d0f06a028d93fff5280b1251f38188afa3499e5f6893a4152f411801a4981fa as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2930,6 +2942,15 @@ impl TypeVariant { pub const fn variants() -> [TypeVariant; 1] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::AccountFlags => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index 97a9a2842..e39eb0f92 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -2828,6 +2828,20 @@ pub type TestArray = [i32; Foo]; /// pub type TestArray2 = VecM::; +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_3373f465eb9c507fb16aa111a9fc228f7fdfff3a0de270501ce7ef48da570cfa { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(TestArray, $($context),*); + + $macro_to_call_back!(TestArray2, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_3373f465eb9c507fb16aa111a9fc228f7fdfff3a0de270501ce7ef48da570cfa as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2860,6 +2874,16 @@ Self::TestArray2 => "TestArray2", pub const fn variants() -> [TypeVariant; 2] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::TestArray => gen.into_root_schema_for::(), +Self::TestArray2 => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index 8d932017b..15b6014f4 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -3204,6 +3204,22 @@ Self::Blue2 => "Blue2", } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_6464a311fbf60d0635e1c3edc07e7e3c9750359880073715f0339ef4ad397b35 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(MessageType, $($context),*); + + $macro_to_call_back!(Color, $($context),*); + + $macro_to_call_back!(Color2, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_6464a311fbf60d0635e1c3edc07e7e3c9750359880073715f0339ef4ad397b35 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -3240,6 +3256,17 @@ Self::Color2 => "Color2", pub const fn variants() -> [TypeVariant; 3] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::MessageType => gen.into_root_schema_for::(), +Self::Color => gen.into_root_schema_for::(), +Self::Color2 => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 1bbde146f..f3c5be433 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -3125,6 +3125,26 @@ Self::Offer => ().write_xdr(w)?, } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_b56a2637c7d9c5cca50c3bd448f8bb94137deedc856160163057efb0521c7013 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(UnionKey, $($context),*); + + $macro_to_call_back!(Foo, $($context),*); + + $macro_to_call_back!(MyUnion, $($context),*); + + $macro_to_call_back!(MyUnionOne, $($context),*); + + $macro_to_call_back!(MyUnionTwo, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_b56a2637c7d9c5cca50c3bd448f8bb94137deedc856160163057efb0521c7013 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -3169,6 +3189,19 @@ Self::MyUnionTwo => "MyUnionTwo", pub const fn variants() -> [TypeVariant; 5] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::UnionKey => gen.into_root_schema_for::(), +Self::Foo => gen.into_root_schema_for::(), +Self::MyUnion => gen.into_root_schema_for::(), +Self::MyUnionOne => gen.into_root_schema_for::(), +Self::MyUnionTwo => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 3e88019ba..4c46a2fd7 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -2858,6 +2858,20 @@ self.third_option.write_xdr(w)?; } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_668dde37e4c931c713dfe57c75ebb9ab815d63b338bf20f3e31962cb552044d5 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(Arr, $($context),*); + + $macro_to_call_back!(HasOptions, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_668dde37e4c931c713dfe57c75ebb9ab815d63b338bf20f3e31962cb552044d5 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2890,6 +2904,16 @@ Self::HasOptions => "HasOptions", pub const fn variants() -> [TypeVariant; 2] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::Arr => gen.into_root_schema_for::(), +Self::HasOptions => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index 8654cb413..8d931b7bd 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -2866,6 +2866,20 @@ self.max_string.write_xdr(w)?; } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_affa3aa4c3210bb4d49be3717cdef1248f6ac8a7666a47223fe1f0619caea7f3 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(Int64, $($context),*); + + $macro_to_call_back!(MyStruct, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_affa3aa4c3210bb4d49be3717cdef1248f6ac8a7666a47223fe1f0619caea7f3 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2898,6 +2912,16 @@ Self::MyStruct => "MyStruct", pub const fn variants() -> [TypeVariant; 2] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::Int64 => gen.into_root_schema_for::(), +Self::MyStruct => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index b05276e28..22fbe5795 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -4498,6 +4498,62 @@ self.nested_union.write_xdr(w)?; } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_451cf50fb89e1944017262c2b763549aab1ebdaf504672a21cbf6787d7478a32 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(Uint512, $($context),*); + + $macro_to_call_back!(Uint513, $($context),*); + + $macro_to_call_back!(Uint514, $($context),*); + + $macro_to_call_back!(Str, $($context),*); + + $macro_to_call_back!(Str2, $($context),*); + + $macro_to_call_back!(Hash, $($context),*); + + $macro_to_call_back!(Hashes1, $($context),*); + + $macro_to_call_back!(Hashes2, $($context),*); + + $macro_to_call_back!(Hashes3, $($context),*); + + $macro_to_call_back!(OptHash1, $($context),*); + + $macro_to_call_back!(OptHash2, $($context),*); + + $macro_to_call_back!(Int1, $($context),*); + + $macro_to_call_back!(Int2, $($context),*); + + $macro_to_call_back!(Int3, $($context),*); + + $macro_to_call_back!(Int4, $($context),*); + + $macro_to_call_back!(MyStruct, $($context),*); + + $macro_to_call_back!(LotsOfMyStructs, $($context),*); + + $macro_to_call_back!(HasStuff, $($context),*); + + $macro_to_call_back!(Color, $($context),*); + + $macro_to_call_back!(Nester, $($context),*); + + $macro_to_call_back!(NesterNestedEnum, $($context),*); + + $macro_to_call_back!(NesterNestedStruct, $($context),*); + + $macro_to_call_back!(NesterNestedUnion, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_451cf50fb89e1944017262c2b763549aab1ebdaf504672a21cbf6787d7478a32 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -4614,6 +4670,37 @@ Self::NesterNestedUnion => "NesterNestedUnion", pub const fn variants() -> [TypeVariant; 23] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::Uint512 => gen.into_root_schema_for::(), +Self::Uint513 => gen.into_root_schema_for::(), +Self::Uint514 => gen.into_root_schema_for::(), +Self::Str => gen.into_root_schema_for::(), +Self::Str2 => gen.into_root_schema_for::(), +Self::Hash => gen.into_root_schema_for::(), +Self::Hashes1 => gen.into_root_schema_for::(), +Self::Hashes2 => gen.into_root_schema_for::(), +Self::Hashes3 => gen.into_root_schema_for::(), +Self::OptHash1 => gen.into_root_schema_for::(), +Self::OptHash2 => gen.into_root_schema_for::(), +Self::Int1 => gen.into_root_schema_for::(), +Self::Int2 => gen.into_root_schema_for::(), +Self::Int3 => gen.into_root_schema_for::(), +Self::Int4 => gen.into_root_schema_for::(), +Self::MyStruct => gen.into_root_schema_for::(), +Self::LotsOfMyStructs => gen.into_root_schema_for::(), +Self::HasStuff => gen.into_root_schema_for::(), +Self::Color => gen.into_root_schema_for::(), +Self::Nester => gen.into_root_schema_for::(), +Self::NesterNestedEnum => gen.into_root_schema_for::(), +Self::NesterNestedStruct => gen.into_root_schema_for::(), +Self::NesterNestedUnion => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 6f270fddf..44dd0f02c 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -3198,6 +3198,28 @@ impl WriteXdr for IntUnion2 { } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_cf2189e72b36e8da6a835f58066d44ad912af644eb6f7ff7bd1dc29e99685861 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(SError, $($context),*); + + $macro_to_call_back!(Multi, $($context),*); + + $macro_to_call_back!(UnionKey, $($context),*); + + $macro_to_call_back!(MyUnion, $($context),*); + + $macro_to_call_back!(IntUnion, $($context),*); + + $macro_to_call_back!(IntUnion2, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_cf2189e72b36e8da6a835f58066d44ad912af644eb6f7ff7bd1dc29e99685861 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -3246,6 +3268,20 @@ Self::IntUnion2 => "IntUnion2", pub const fn variants() -> [TypeVariant; 6] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::SError => gen.into_root_schema_for::(), +Self::Multi => gen.into_root_schema_for::(), +Self::UnionKey => gen.into_root_schema_for::(), +Self::MyUnion => gen.into_root_schema_for::(), +Self::IntUnion => gen.into_root_schema_for::(), +Self::IntUnion2 => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index 0e0b7430d..4eec70936 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -2902,6 +2902,18 @@ impl WriteXdr for AccountFlags { } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_7319176558878d16553d6bc15fca9327d2a54ec2e1565fb25d3f81de4cee570a { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(AccountFlags, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_7319176558878d16553d6bc15fca9327d2a54ec2e1565fb25d3f81de4cee570a as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2930,6 +2942,15 @@ impl TypeVariant { pub const fn variants() -> [TypeVariant; 1] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::AccountFlags => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index 97a9a2842..195fc7ce2 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -2828,6 +2828,20 @@ pub type TestArray = [i32; Foo]; /// pub type TestArray2 = VecM::; +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_4da6180f6517f6f748e1847f40ed89463e846e387bc9701ed570b06c80378705 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(TestArray, $($context),*); + + $macro_to_call_back!(TestArray2, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_4da6180f6517f6f748e1847f40ed89463e846e387bc9701ed570b06c80378705 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2860,6 +2874,16 @@ Self::TestArray2 => "TestArray2", pub const fn variants() -> [TypeVariant; 2] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::TestArray => gen.into_root_schema_for::(), +Self::TestArray2 => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index 2e1e79efd..cc6d1bfcb 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -3203,6 +3203,22 @@ Self::Blue2 => "Blue2", } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_2555ba55683c0fc19ce5d524ac9784aeaef6d71bb871d05562c3e2f1b0771058 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(MessageType, $($context),*); + + $macro_to_call_back!(Color, $($context),*); + + $macro_to_call_back!(Color2, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_2555ba55683c0fc19ce5d524ac9784aeaef6d71bb871d05562c3e2f1b0771058 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -3239,6 +3255,17 @@ Self::Color2 => "Color2", pub const fn variants() -> [TypeVariant; 3] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::MessageType => gen.into_root_schema_for::(), +Self::Color => gen.into_root_schema_for::(), +Self::Color2 => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index ccfd3f37d..b9d2efe7d 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -3123,6 +3123,26 @@ Self::Offer => ().write_xdr(w)?, } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_b6c1a18b09f1b468f7fe474905bf186701a2515d5ea621cc2976a8857507759c { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(UnionKey, $($context),*); + + $macro_to_call_back!(Foo, $($context),*); + + $macro_to_call_back!(MyUnion, $($context),*); + + $macro_to_call_back!(MyUnionOne, $($context),*); + + $macro_to_call_back!(MyUnionTwo, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_b6c1a18b09f1b468f7fe474905bf186701a2515d5ea621cc2976a8857507759c as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -3167,6 +3187,19 @@ Self::MyUnionTwo => "MyUnionTwo", pub const fn variants() -> [TypeVariant; 5] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::UnionKey => gen.into_root_schema_for::(), +Self::Foo => gen.into_root_schema_for::(), +Self::MyUnion => gen.into_root_schema_for::(), +Self::MyUnionOne => gen.into_root_schema_for::(), +Self::MyUnionTwo => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index 2e112ddb6..f6633b05f 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -2857,6 +2857,20 @@ self.third_option.write_xdr(w)?; } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_58d86cd68e84cb99c63b6fed86028cacc66ababc6b700b8a3c3f037f3eb2649b { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(Arr, $($context),*); + + $macro_to_call_back!(HasOptions, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_58d86cd68e84cb99c63b6fed86028cacc66ababc6b700b8a3c3f037f3eb2649b as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2889,6 +2903,16 @@ Self::HasOptions => "HasOptions", pub const fn variants() -> [TypeVariant; 2] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::Arr => gen.into_root_schema_for::(), +Self::HasOptions => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index 062d1a5f0..a6bd1b7f3 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -2865,6 +2865,20 @@ self.max_string.write_xdr(w)?; } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_6c6fcf0d09aabf041e68a1515efab2c7a4d8b74d95f4af21a71c061ef03a25af { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(Int64, $($context),*); + + $macro_to_call_back!(MyStruct, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_6c6fcf0d09aabf041e68a1515efab2c7a4d8b74d95f4af21a71c061ef03a25af as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2897,6 +2911,16 @@ Self::MyStruct => "MyStruct", pub const fn variants() -> [TypeVariant; 2] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::Int64 => gen.into_root_schema_for::(), +Self::MyStruct => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index c9acfff5e..5e6679050 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -4496,6 +4496,62 @@ self.nested_union.write_xdr(w)?; } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_814ad56babac15349641febbae8212a8ab3f83bc8efd0a9328b52708a120645a { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(Uint512, $($context),*); + + $macro_to_call_back!(Uint513, $($context),*); + + $macro_to_call_back!(Uint514, $($context),*); + + $macro_to_call_back!(Str, $($context),*); + + $macro_to_call_back!(Str2, $($context),*); + + $macro_to_call_back!(Hash, $($context),*); + + $macro_to_call_back!(Hashes1, $($context),*); + + $macro_to_call_back!(Hashes2, $($context),*); + + $macro_to_call_back!(Hashes3, $($context),*); + + $macro_to_call_back!(OptHash1, $($context),*); + + $macro_to_call_back!(OptHash2, $($context),*); + + $macro_to_call_back!(Int1, $($context),*); + + $macro_to_call_back!(Int2, $($context),*); + + $macro_to_call_back!(Int3, $($context),*); + + $macro_to_call_back!(Int4, $($context),*); + + $macro_to_call_back!(MyStruct, $($context),*); + + $macro_to_call_back!(LotsOfMyStructs, $($context),*); + + $macro_to_call_back!(HasStuff, $($context),*); + + $macro_to_call_back!(Color, $($context),*); + + $macro_to_call_back!(Nester, $($context),*); + + $macro_to_call_back!(NesterNestedEnum, $($context),*); + + $macro_to_call_back!(NesterNestedStruct, $($context),*); + + $macro_to_call_back!(NesterNestedUnion, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_814ad56babac15349641febbae8212a8ab3f83bc8efd0a9328b52708a120645a as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -4612,6 +4668,37 @@ Self::NesterNestedUnion => "NesterNestedUnion", pub const fn variants() -> [TypeVariant; 23] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::Uint512 => gen.into_root_schema_for::(), +Self::Uint513 => gen.into_root_schema_for::(), +Self::Uint514 => gen.into_root_schema_for::(), +Self::Str => gen.into_root_schema_for::(), +Self::Str2 => gen.into_root_schema_for::(), +Self::Hash => gen.into_root_schema_for::(), +Self::Hashes1 => gen.into_root_schema_for::(), +Self::Hashes2 => gen.into_root_schema_for::(), +Self::Hashes3 => gen.into_root_schema_for::(), +Self::OptHash1 => gen.into_root_schema_for::(), +Self::OptHash2 => gen.into_root_schema_for::(), +Self::Int1 => gen.into_root_schema_for::(), +Self::Int2 => gen.into_root_schema_for::(), +Self::Int3 => gen.into_root_schema_for::(), +Self::Int4 => gen.into_root_schema_for::(), +Self::MyStruct => gen.into_root_schema_for::(), +Self::LotsOfMyStructs => gen.into_root_schema_for::(), +Self::HasStuff => gen.into_root_schema_for::(), +Self::Color => gen.into_root_schema_for::(), +Self::Nester => gen.into_root_schema_for::(), +Self::NesterNestedEnum => gen.into_root_schema_for::(), +Self::NesterNestedStruct => gen.into_root_schema_for::(), +Self::NesterNestedUnion => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index 4c627c402..ef21c20a1 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -3196,6 +3196,28 @@ impl WriteXdr for IntUnion2 { } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_41faaa1c6389c8da953ba6dc1a385b706e137b93cf4363ad6a999215fcfdb0bc { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(SError, $($context),*); + + $macro_to_call_back!(Multi, $($context),*); + + $macro_to_call_back!(UnionKey, $($context),*); + + $macro_to_call_back!(MyUnion, $($context),*); + + $macro_to_call_back!(IntUnion, $($context),*); + + $macro_to_call_back!(IntUnion2, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_41faaa1c6389c8da953ba6dc1a385b706e137b93cf4363ad6a999215fcfdb0bc as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -3244,6 +3266,20 @@ Self::IntUnion2 => "IntUnion2", pub const fn variants() -> [TypeVariant; 6] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::SError => gen.into_root_schema_for::(), +Self::Multi => gen.into_root_schema_for::(), +Self::UnionKey => gen.into_root_schema_for::(), +Self::MyUnion => gen.into_root_schema_for::(), +Self::IntUnion => gen.into_root_schema_for::(), +Self::IntUnion2 => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index 0e0b7430d..6a81a8ff8 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -2902,6 +2902,18 @@ impl WriteXdr for AccountFlags { } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_c00f0c7ee3472652a59efe54781c8e9a11a055003909f57ad84267ac05008abd { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(AccountFlags, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_c00f0c7ee3472652a59efe54781c8e9a11a055003909f57ad84267ac05008abd as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2930,6 +2942,15 @@ impl TypeVariant { pub const fn variants() -> [TypeVariant; 1] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::AccountFlags => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index 97a9a2842..716798cf4 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -2828,6 +2828,20 @@ pub type TestArray = [i32; Foo]; /// pub type TestArray2 = VecM::; +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_ab32b5b14733c592876e16ba870dfa31ed9dc87909b0b43d41b53b0153792e75 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(TestArray, $($context),*); + + $macro_to_call_back!(TestArray2, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_ab32b5b14733c592876e16ba870dfa31ed9dc87909b0b43d41b53b0153792e75 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2860,6 +2874,16 @@ Self::TestArray2 => "TestArray2", pub const fn variants() -> [TypeVariant; 2] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::TestArray => gen.into_root_schema_for::(), +Self::TestArray2 => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index cde29d5f7..600fdce06 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -3204,6 +3204,22 @@ Self::Blue2 => "Blue2", } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_03c2a103be81d5866909c1a9b63857b87b586004b71facdd64b932a7aa688b72 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(MessageType, $($context),*); + + $macro_to_call_back!(Color, $($context),*); + + $macro_to_call_back!(Color2, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_03c2a103be81d5866909c1a9b63857b87b586004b71facdd64b932a7aa688b72 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -3240,6 +3256,17 @@ Self::Color2 => "Color2", pub const fn variants() -> [TypeVariant; 3] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::MessageType => gen.into_root_schema_for::(), +Self::Color => gen.into_root_schema_for::(), +Self::Color2 => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 3e635339c..619f2043e 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -3125,6 +3125,26 @@ Self::Offer => ().write_xdr(w)?, } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_2d97ab60593aae65366cedbc8d7c1166dd446746434b62f3f7cb8f28310f9cf4 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(UnionKey, $($context),*); + + $macro_to_call_back!(Foo, $($context),*); + + $macro_to_call_back!(MyUnion, $($context),*); + + $macro_to_call_back!(MyUnionOne, $($context),*); + + $macro_to_call_back!(MyUnionTwo, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_2d97ab60593aae65366cedbc8d7c1166dd446746434b62f3f7cb8f28310f9cf4 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -3169,6 +3189,19 @@ Self::MyUnionTwo => "MyUnionTwo", pub const fn variants() -> [TypeVariant; 5] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::UnionKey => gen.into_root_schema_for::(), +Self::Foo => gen.into_root_schema_for::(), +Self::MyUnion => gen.into_root_schema_for::(), +Self::MyUnionOne => gen.into_root_schema_for::(), +Self::MyUnionTwo => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index 6adea8224..e9216b6b6 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -2858,6 +2858,20 @@ self.third_option.write_xdr(w)?; } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_59540777b0327956eb5415514add930c472e7de4e37184dfa74795d616f9875d { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(Arr, $($context),*); + + $macro_to_call_back!(HasOptions, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_59540777b0327956eb5415514add930c472e7de4e37184dfa74795d616f9875d as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2890,6 +2904,16 @@ Self::HasOptions => "HasOptions", pub const fn variants() -> [TypeVariant; 2] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::Arr => gen.into_root_schema_for::(), +Self::HasOptions => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index 9d38eb31e..a7d143eb8 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -2866,6 +2866,20 @@ self.max_string.write_xdr(w)?; } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_7d7dc5bf933bd4adb4a67c9e209bd5500d3ac07d52dc3146e1bd5383519fc342 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(Int64, $($context),*); + + $macro_to_call_back!(MyStruct, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_7d7dc5bf933bd4adb4a67c9e209bd5500d3ac07d52dc3146e1bd5383519fc342 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -2898,6 +2912,16 @@ Self::MyStruct => "MyStruct", pub const fn variants() -> [TypeVariant; 2] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::Int64 => gen.into_root_schema_for::(), +Self::MyStruct => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index df29abfe4..b0fb7ecee 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -4498,6 +4498,62 @@ self.nested_union.write_xdr(w)?; } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_adebb4692a0fdd71aa2cc2e351c611b05c64f4d636e21458996122e823978a61 { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(Uint512, $($context),*); + + $macro_to_call_back!(Uint513, $($context),*); + + $macro_to_call_back!(Uint514, $($context),*); + + $macro_to_call_back!(Str, $($context),*); + + $macro_to_call_back!(Str2, $($context),*); + + $macro_to_call_back!(Hash, $($context),*); + + $macro_to_call_back!(Hashes1, $($context),*); + + $macro_to_call_back!(Hashes2, $($context),*); + + $macro_to_call_back!(Hashes3, $($context),*); + + $macro_to_call_back!(OptHash1, $($context),*); + + $macro_to_call_back!(OptHash2, $($context),*); + + $macro_to_call_back!(Int1, $($context),*); + + $macro_to_call_back!(Int2, $($context),*); + + $macro_to_call_back!(Int3, $($context),*); + + $macro_to_call_back!(Int4, $($context),*); + + $macro_to_call_back!(MyStruct, $($context),*); + + $macro_to_call_back!(LotsOfMyStructs, $($context),*); + + $macro_to_call_back!(HasStuff, $($context),*); + + $macro_to_call_back!(Color, $($context),*); + + $macro_to_call_back!(Nester, $($context),*); + + $macro_to_call_back!(NesterNestedEnum, $($context),*); + + $macro_to_call_back!(NesterNestedStruct, $($context),*); + + $macro_to_call_back!(NesterNestedUnion, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_adebb4692a0fdd71aa2cc2e351c611b05c64f4d636e21458996122e823978a61 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -4614,6 +4670,37 @@ Self::NesterNestedUnion => "NesterNestedUnion", pub const fn variants() -> [TypeVariant; 23] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::Uint512 => gen.into_root_schema_for::(), +Self::Uint513 => gen.into_root_schema_for::(), +Self::Uint514 => gen.into_root_schema_for::(), +Self::Str => gen.into_root_schema_for::(), +Self::Str2 => gen.into_root_schema_for::(), +Self::Hash => gen.into_root_schema_for::(), +Self::Hashes1 => gen.into_root_schema_for::(), +Self::Hashes2 => gen.into_root_schema_for::(), +Self::Hashes3 => gen.into_root_schema_for::(), +Self::OptHash1 => gen.into_root_schema_for::(), +Self::OptHash2 => gen.into_root_schema_for::(), +Self::Int1 => gen.into_root_schema_for::(), +Self::Int2 => gen.into_root_schema_for::(), +Self::Int3 => gen.into_root_schema_for::(), +Self::Int4 => gen.into_root_schema_for::(), +Self::MyStruct => gen.into_root_schema_for::(), +Self::LotsOfMyStructs => gen.into_root_schema_for::(), +Self::HasStuff => gen.into_root_schema_for::(), +Self::Color => gen.into_root_schema_for::(), +Self::Nester => gen.into_root_schema_for::(), +Self::NesterNestedEnum => gen.into_root_schema_for::(), +Self::NesterNestedStruct => gen.into_root_schema_for::(), +Self::NesterNestedUnion => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index 6cb7ea3ce..6d566261d 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -3198,6 +3198,28 @@ impl WriteXdr for IntUnion2 { } } +#[doc(hidden)] +#[macro_export] +macro_rules! _call_macro_with_each_type_d63f5de629d12eba02922f123f0547e9eff5460d475c54163bb76b57be65e30d { + // The x-macro takes a single ident, the name of a macro to call ... + ($macro_to_call_back:ident, $($context:tt),*) => {{ + // ... and calls it back, once for each XDR type. + $macro_to_call_back!(SError, $($context),*); + + $macro_to_call_back!(Multi, $($context),*); + + $macro_to_call_back!(UnionKey, $($context),*); + + $macro_to_call_back!(MyUnion, $($context),*); + + $macro_to_call_back!(IntUnion, $($context),*); + + $macro_to_call_back!(IntUnion2, $($context),*); + + + }}; +} +pub use _call_macro_with_each_type_d63f5de629d12eba02922f123f0547e9eff5460d475c54163bb76b57be65e30d as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), @@ -3246,6 +3268,20 @@ Self::IntUnion2 => "IntUnion2", pub const fn variants() -> [TypeVariant; 6] { Self::VARIANTS } + + #[cfg(feature = "schemars")] + #[must_use] + #[allow(clippy::too_many_lines)] + pub fn json_schema(&self, gen: schemars::gen::SchemaGenerator) -> schemars::schema::RootSchema { + match self { + Self::SError => gen.into_root_schema_for::(), +Self::Multi => gen.into_root_schema_for::(), +Self::UnionKey => gen.into_root_schema_for::(), +Self::MyUnion => gen.into_root_schema_for::(), +Self::IntUnion => gen.into_root_schema_for::(), +Self::IntUnion2 => gen.into_root_schema_for::(), + } + } } impl Name for TypeVariant { From 0a2611a2bc6b6f6bceacb72fe9321b0cb4d8ccd5 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 15 Mar 2024 23:11:33 +1000 Subject: [PATCH 14/20] simplified the fns --- lib/xdrgen/generators/rust.rb | 12 +-- lib/xdrgen/generators/rust/src/types.rs | 80 +++++++------------ .../generator_spec_rust/test.x/MyXDR.rs | 8 -- .../test.x/MyXDR.rs | 8 -- .../test.x/MyXDR.rs | 8 -- 5 files changed, 34 insertions(+), 82 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index e6ae79fae..2a44cff75 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -776,8 +776,8 @@ def render_typedef(out, typedef) } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -786,13 +786,15 @@ def render_typedef(out, typedef) "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: #{typedef.type.size}_u32.checked_mul(2).map(Some).unwrap_or_default(), min_length: #{typedef.type.size}_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string - }) + })); + schema.into() } else { - schema_ + schema } } } diff --git a/lib/xdrgen/generators/rust/src/types.rs b/lib/xdrgen/generators/rust/src/types.rs index b05ad3545..13a36c004 100644 --- a/lib/xdrgen/generators/rust/src/types.rs +++ b/lib/xdrgen/generators/rust/src/types.rs @@ -899,12 +899,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1354,8 +1360,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1364,13 +1370,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1769,17 +1777,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2105,10 +2114,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2138,37 +2143,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index 22fbe5795..4bf1b48e9 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -2849,10 +2849,6 @@ impl schemars::JsonSchema for Uint512 { "Uint512".to_string() } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { let schema_ = String::json_schema(gen); if let schemars::schema::Schema::Object(mut schema) = schema_ { @@ -3403,10 +3399,6 @@ impl schemars::JsonSchema for Hash { "Hash".to_string() } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { let schema_ = String::json_schema(gen); if let schemars::schema::Schema::Object(mut schema) = schema_ { diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index 5e6679050..252ab1b2c 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -2849,10 +2849,6 @@ impl schemars::JsonSchema for Uint512 { "Uint512".to_string() } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { let schema_ = String::json_schema(gen); if let schemars::schema::Schema::Object(mut schema) = schema_ { @@ -3403,10 +3399,6 @@ impl schemars::JsonSchema for Hash { "Hash".to_string() } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { let schema_ = String::json_schema(gen); if let schemars::schema::Schema::Object(mut schema) = schema_ { diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index b0fb7ecee..cb4ed3b1a 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -2849,10 +2849,6 @@ impl schemars::JsonSchema for Uint512 { "Uint512".to_string() } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { let schema_ = String::json_schema(gen); if let schemars::schema::Schema::Object(mut schema) = schema_ { @@ -3403,10 +3399,6 @@ impl schemars::JsonSchema for Hash { "Hash".to_string() } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { let schema_ = String::json_schema(gen); if let schemars::schema::Schema::Object(mut schema) = schema_ { From 9e8531ca45d43686fe779047fc5609aa1460ebf3 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 9 Apr 2024 21:32:42 +1000 Subject: [PATCH 15/20] fix tests --- .../block_comments.x/MyXDR.rs | 80 +++++-------- .../generator_spec_rust/const.x/MyXDR.rs | 80 +++++-------- .../generator_spec_rust/enum.x/MyXDR.rs | 82 +++++-------- .../generator_spec_rust/nesting.x/MyXDR.rs | 80 +++++-------- .../generator_spec_rust/optional.x/MyXDR.rs | 80 +++++-------- .../generator_spec_rust/struct.x/MyXDR.rs | 80 +++++-------- .../generator_spec_rust/test.x/MyXDR.rs | 112 ++++++++---------- .../generator_spec_rust/union.x/MyXDR.rs | 82 +++++-------- .../block_comments.x/MyXDR.rs | 80 +++++-------- .../const.x/MyXDR.rs | 80 +++++-------- .../enum.x/MyXDR.rs | 82 +++++-------- .../nesting.x/MyXDR.rs | 80 +++++-------- .../optional.x/MyXDR.rs | 80 +++++-------- .../struct.x/MyXDR.rs | 80 +++++-------- .../test.x/MyXDR.rs | 112 ++++++++---------- .../union.x/MyXDR.rs | 82 +++++-------- .../block_comments.x/MyXDR.rs | 80 +++++-------- .../const.x/MyXDR.rs | 80 +++++-------- .../enum.x/MyXDR.rs | 82 +++++-------- .../nesting.x/MyXDR.rs | 80 +++++-------- .../optional.x/MyXDR.rs | 80 +++++-------- .../struct.x/MyXDR.rs | 80 +++++-------- .../test.x/MyXDR.rs | 112 ++++++++---------- .../union.x/MyXDR.rs | 82 +++++-------- 24 files changed, 720 insertions(+), 1308 deletions(-) diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index cfde7507d..a89d7cb07 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index e39eb0f92..900754bda 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index 15b6014f4..3eead8b7c 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array - } - }) + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); + } + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index f3c5be433..4bba59334 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 4c46a2fd7..8f28ce00e 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index 8d931b7bd..418358b49 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index 4bf1b48e9..bfd0f67c0 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2849,9 +2823,13 @@ impl schemars::JsonSchema for Uint512 { "Uint512".to_string() } + fn is_referenceable() -> bool { + false + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -2860,13 +2838,15 @@ impl schemars::JsonSchema for Uint512 { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), min_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -3399,9 +3379,13 @@ impl schemars::JsonSchema for Hash { "Hash".to_string() } + fn is_referenceable() -> bool { + false + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -3410,13 +3394,15 @@ impl schemars::JsonSchema for Hash { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), min_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string - }) + })); + schema.into() } else { - schema_ + schema } } } diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 44dd0f02c..e6ef4ffe7 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array - } - }) + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); + } + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index 4eec70936..eed050c3f 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index 195fc7ce2..f92463a5d 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index cc6d1bfcb..0d66eebab 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array - } - }) + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); + } + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index b9d2efe7d..d077ca027 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index f6633b05f..8356d31f6 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index a6bd1b7f3..db683011b 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index 252ab1b2c..9b22468a1 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2849,9 +2823,13 @@ impl schemars::JsonSchema for Uint512 { "Uint512".to_string() } + fn is_referenceable() -> bool { + false + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -2860,13 +2838,15 @@ impl schemars::JsonSchema for Uint512 { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), min_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -3399,9 +3379,13 @@ impl schemars::JsonSchema for Hash { "Hash".to_string() } + fn is_referenceable() -> bool { + false + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -3410,13 +3394,15 @@ impl schemars::JsonSchema for Hash { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), min_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string - }) + })); + schema.into() } else { - schema_ + schema } } } diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index ef21c20a1..9ad8b737b 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array - } - }) + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); + } + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index 6a81a8ff8..b141afc7c 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index 716798cf4..c94acc546 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index 600fdce06..cb409d13d 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array - } - }) + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); + } + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 619f2043e..7abffbf79 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index e9216b6b6..004d0523a 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index a7d143eb8..ef4d0e73f 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index cb4ed3b1a..ea5a53701 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); } - }) + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; @@ -2849,9 +2823,13 @@ impl schemars::JsonSchema for Uint512 { "Uint512".to_string() } + fn is_referenceable() -> bool { + false + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -2860,13 +2838,15 @@ impl schemars::JsonSchema for Uint512 { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), min_length: 64_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -3399,9 +3379,13 @@ impl schemars::JsonSchema for Hash { "Hash".to_string() } + fn is_referenceable() -> bool { + false + } + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -3410,13 +3394,15 @@ impl schemars::JsonSchema for Hash { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), min_length: 32_u32.checked_mul(2).map(Some).unwrap_or_default(), ..string - }) + })); + schema.into() } else { - schema_ + schema } } } diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index 6d566261d..fbbf52cec 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -909,12 +909,18 @@ impl schemars::JsonSchema for VecM schemars::schema::Schema { - mut_array(Vec::::json_schema(gen), |array| { - schemars::schema::ArrayValidation { - max_items: Some(MAX), - ..array - } - }) + let schema = Vec::::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + if let Some(array) = schema.array.clone() { + schema.array = Some(Box::new(schemars::schema::ArrayValidation { + max_items: Some(MAX), + ..*array + })); + } + schema.into() + } else { + schema + } } } @@ -1364,8 +1370,8 @@ impl schemars::JsonSchema for BytesM { } fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - let schema_ = String::json_schema(gen); - if let schemars::schema::Schema::Object(mut schema) = schema_ { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { schema.extensions.insert( "contentEncoding".to_owned(), serde_json::Value::String("hex".to_string()), @@ -1374,13 +1380,15 @@ impl schemars::JsonSchema for BytesM { "contentMediaType".to_owned(), serde_json::Value::String("application/binary".to_string()), ); - mut_string(schema.into(), |string| schemars::schema::StringValidation { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: MAX.checked_mul(2).map(Some).unwrap_or_default(), min_length: None, ..string - }) + })); + schema.into() } else { - schema_ + schema } } } @@ -1779,17 +1787,18 @@ impl schemars::JsonSchema for StringM { format!("StringM<{MAX}>") } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - mut_string(String::json_schema(gen), |string| { - schemars::schema::StringValidation { + let schema = String::json_schema(gen); + if let schemars::schema::Schema::Object(mut schema) = schema { + let string = *schema.string.unwrap_or_default().clone(); + schema.string = Some(Box::new(schemars::schema::StringValidation { max_length: Some(MAX), ..string - } - }) + })); + schema.into() + } else { + schema + } } } @@ -2115,10 +2124,6 @@ impl schemars::JsonSchema for Frame { format!("Frame<{}>", T::schema_name()) } - fn is_referenceable() -> bool { - false - } - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { T::json_schema(gen) } @@ -2148,37 +2153,6 @@ where } } -#[cfg(feature = "schemars")] -fn mut_array( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::ArrayValidation) -> schemars::schema::ArrayValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - if let Some(array) = schema.array.clone() { - schema.array = Some(Box::new(f(*array))); - } - schema.into() - } else { - schema - } -} - -#[cfg(feature = "schemars")] -fn mut_string( - schema: schemars::schema::Schema, - f: impl FnOnce(schemars::schema::StringValidation) -> schemars::schema::StringValidation, -) -> schemars::schema::Schema { - if let schemars::schema::Schema::Object(mut schema) = schema { - let string = *schema.string.unwrap_or_default().clone(); - let s = f(string); - schema.string = Some(Box::new(s)); - - schema.into() - } else { - schema - } -} - #[cfg(all(test, feature = "std"))] mod tests { use std::io::Cursor; From 527fda3f04a36c86789a0f2e012f753183409ec4 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 9 Apr 2024 21:40:47 +1000 Subject: [PATCH 16/20] fix --- spec/output/generator_spec_rust/block_comments.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/const.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/enum.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/nesting.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/optional.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/struct.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/test.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/union.x/MyXDR.rs | 4 ++-- .../block_comments.x/MyXDR.rs | 4 ++-- .../const.x/MyXDR.rs | 4 ++-- .../enum.x/MyXDR.rs | 4 ++-- .../nesting.x/MyXDR.rs | 4 ++-- .../optional.x/MyXDR.rs | 4 ++-- .../struct.x/MyXDR.rs | 4 ++-- .../test.x/MyXDR.rs | 4 ++-- .../union.x/MyXDR.rs | 4 ++-- .../block_comments.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/const.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/test.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/union.x/MyXDR.rs | 4 ++-- spec/spec_helper.rb | 2 +- 25 files changed, 49 insertions(+), 49 deletions(-) diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index a89d7cb07..a20b0d6b8 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -2878,7 +2878,7 @@ impl WriteXdr for AccountFlags { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_9d0f06a028d93fff5280b1251f38188afa3499e5f6893a4152f411801a4981fa { +macro_rules! _call_macro_with_each_type_74ae33c5a9c08460c7f65c74189bedd1ebf8e378c272e3e934d34e7c4d0e1e21 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2887,7 +2887,7 @@ macro_rules! _call_macro_with_each_type_9d0f06a028d93fff5280b1251f38188afa3499e5 }}; } -pub use _call_macro_with_each_type_9d0f06a028d93fff5280b1251f38188afa3499e5f6893a4152f411801a4981fa as call_macro_with_each_type; +pub use _call_macro_with_each_type_74ae33c5a9c08460c7f65c74189bedd1ebf8e378c272e3e934d34e7c4d0e1e21 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index 900754bda..1a75e4d7b 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -2804,7 +2804,7 @@ pub type TestArray2 = VecM::; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_3373f465eb9c507fb16aa111a9fc228f7fdfff3a0de270501ce7ef48da570cfa { +macro_rules! _call_macro_with_each_type_e4fedcf76f096d35fa1f6198342d56f66e4f6f3a5cab26a4fd29a7e52d470238 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2815,7 +2815,7 @@ macro_rules! _call_macro_with_each_type_3373f465eb9c507fb16aa111a9fc228f7fdfff3a }}; } -pub use _call_macro_with_each_type_3373f465eb9c507fb16aa111a9fc228f7fdfff3a0de270501ce7ef48da570cfa as call_macro_with_each_type; +pub use _call_macro_with_each_type_e4fedcf76f096d35fa1f6198342d56f66e4f6f3a5cab26a4fd29a7e52d470238 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index 3eead8b7c..c81e789c1 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -3180,7 +3180,7 @@ Self::Blue2 => "Blue2", #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_6464a311fbf60d0635e1c3edc07e7e3c9750359880073715f0339ef4ad397b35 { +macro_rules! _call_macro_with_each_type_c4a7f685cb1d6ff0896b8e545a2b8b977f8d962c5d5966b3ba96291609022cf3 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_6464a311fbf60d0635e1c3edc07e7e3c97503598 }}; } -pub use _call_macro_with_each_type_6464a311fbf60d0635e1c3edc07e7e3c9750359880073715f0339ef4ad397b35 as call_macro_with_each_type; +pub use _call_macro_with_each_type_c4a7f685cb1d6ff0896b8e545a2b8b977f8d962c5d5966b3ba96291609022cf3 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 4bba59334..37df9acde 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -3101,7 +3101,7 @@ Self::Offer => ().write_xdr(w)?, #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_b56a2637c7d9c5cca50c3bd448f8bb94137deedc856160163057efb0521c7013 { +macro_rules! _call_macro_with_each_type_d0ff637ead9d76881519748c5751596952f7ad41e9fc1fd713666af21d0b2402 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3118,7 +3118,7 @@ macro_rules! _call_macro_with_each_type_b56a2637c7d9c5cca50c3bd448f8bb94137deedc }}; } -pub use _call_macro_with_each_type_b56a2637c7d9c5cca50c3bd448f8bb94137deedc856160163057efb0521c7013 as call_macro_with_each_type; +pub use _call_macro_with_each_type_d0ff637ead9d76881519748c5751596952f7ad41e9fc1fd713666af21d0b2402 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 8f28ce00e..0e83acd19 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -2834,7 +2834,7 @@ self.third_option.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_668dde37e4c931c713dfe57c75ebb9ab815d63b338bf20f3e31962cb552044d5 { +macro_rules! _call_macro_with_each_type_fecabbf83b11ef8308ffd4c2f6f07db3ecc043ea692e9216792ccfb7da5dbb97 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2845,7 +2845,7 @@ macro_rules! _call_macro_with_each_type_668dde37e4c931c713dfe57c75ebb9ab815d63b3 }}; } -pub use _call_macro_with_each_type_668dde37e4c931c713dfe57c75ebb9ab815d63b338bf20f3e31962cb552044d5 as call_macro_with_each_type; +pub use _call_macro_with_each_type_fecabbf83b11ef8308ffd4c2f6f07db3ecc043ea692e9216792ccfb7da5dbb97 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index 418358b49..0fedfac5e 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -2842,7 +2842,7 @@ self.max_string.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_affa3aa4c3210bb4d49be3717cdef1248f6ac8a7666a47223fe1f0619caea7f3 { +macro_rules! _call_macro_with_each_type_a215be981ee6741a031d48dc3a3e519f8d70545b67b3f5707b9a33af8636c8d6 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2853,7 +2853,7 @@ macro_rules! _call_macro_with_each_type_affa3aa4c3210bb4d49be3717cdef1248f6ac8a7 }}; } -pub use _call_macro_with_each_type_affa3aa4c3210bb4d49be3717cdef1248f6ac8a7666a47223fe1f0619caea7f3 as call_macro_with_each_type; +pub use _call_macro_with_each_type_a215be981ee6741a031d48dc3a3e519f8d70545b67b3f5707b9a33af8636c8d6 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index bfd0f67c0..ae8fdf837 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -4478,7 +4478,7 @@ self.nested_union.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_451cf50fb89e1944017262c2b763549aab1ebdaf504672a21cbf6787d7478a32 { +macro_rules! _call_macro_with_each_type_e24b0e9c3b4b66eafcd77916658ca28e1d60d143481be4d82bf8cce4463a7367 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -4531,7 +4531,7 @@ macro_rules! _call_macro_with_each_type_451cf50fb89e1944017262c2b763549aab1ebdaf }}; } -pub use _call_macro_with_each_type_451cf50fb89e1944017262c2b763549aab1ebdaf504672a21cbf6787d7478a32 as call_macro_with_each_type; +pub use _call_macro_with_each_type_e24b0e9c3b4b66eafcd77916658ca28e1d60d143481be4d82bf8cce4463a7367 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index e6ef4ffe7..258804b13 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -3174,7 +3174,7 @@ impl WriteXdr for IntUnion2 { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_cf2189e72b36e8da6a835f58066d44ad912af644eb6f7ff7bd1dc29e99685861 { +macro_rules! _call_macro_with_each_type_3cf7b400d9d6ac9daa98597b9f72302fa5fab52590401d883ccbd8420cda36fa { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_cf2189e72b36e8da6a835f58066d44ad912af644 }}; } -pub use _call_macro_with_each_type_cf2189e72b36e8da6a835f58066d44ad912af644eb6f7ff7bd1dc29e99685861 as call_macro_with_each_type; +pub use _call_macro_with_each_type_3cf7b400d9d6ac9daa98597b9f72302fa5fab52590401d883ccbd8420cda36fa as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index eed050c3f..654cf5e64 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -2878,7 +2878,7 @@ impl WriteXdr for AccountFlags { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_7319176558878d16553d6bc15fca9327d2a54ec2e1565fb25d3f81de4cee570a { +macro_rules! _call_macro_with_each_type_315c3ec204e8759c65e2143522758b394627f663209ed117a1bdeb1b461fc5d8 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2887,7 +2887,7 @@ macro_rules! _call_macro_with_each_type_7319176558878d16553d6bc15fca9327d2a54ec2 }}; } -pub use _call_macro_with_each_type_7319176558878d16553d6bc15fca9327d2a54ec2e1565fb25d3f81de4cee570a as call_macro_with_each_type; +pub use _call_macro_with_each_type_315c3ec204e8759c65e2143522758b394627f663209ed117a1bdeb1b461fc5d8 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index f92463a5d..fc1cd118b 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -2804,7 +2804,7 @@ pub type TestArray2 = VecM::; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_4da6180f6517f6f748e1847f40ed89463e846e387bc9701ed570b06c80378705 { +macro_rules! _call_macro_with_each_type_cc81650d8e35ad6a04efc88604011939a9121acf12701e7b66fed5ea301835c1 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2815,7 +2815,7 @@ macro_rules! _call_macro_with_each_type_4da6180f6517f6f748e1847f40ed89463e846e38 }}; } -pub use _call_macro_with_each_type_4da6180f6517f6f748e1847f40ed89463e846e387bc9701ed570b06c80378705 as call_macro_with_each_type; +pub use _call_macro_with_each_type_cc81650d8e35ad6a04efc88604011939a9121acf12701e7b66fed5ea301835c1 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index 0d66eebab..5ef06ee3c 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -3179,7 +3179,7 @@ Self::Blue2 => "Blue2", #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_2555ba55683c0fc19ce5d524ac9784aeaef6d71bb871d05562c3e2f1b0771058 { +macro_rules! _call_macro_with_each_type_3c6b545072b61bac61c15b38aea09349377b6516a09c130fc4365b6b3879fe6f { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3192,7 +3192,7 @@ macro_rules! _call_macro_with_each_type_2555ba55683c0fc19ce5d524ac9784aeaef6d71b }}; } -pub use _call_macro_with_each_type_2555ba55683c0fc19ce5d524ac9784aeaef6d71bb871d05562c3e2f1b0771058 as call_macro_with_each_type; +pub use _call_macro_with_each_type_3c6b545072b61bac61c15b38aea09349377b6516a09c130fc4365b6b3879fe6f as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index d077ca027..da4cb5541 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -3099,7 +3099,7 @@ Self::Offer => ().write_xdr(w)?, #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_b6c1a18b09f1b468f7fe474905bf186701a2515d5ea621cc2976a8857507759c { +macro_rules! _call_macro_with_each_type_ea152ece0f1c4feff54daa63f53e0d91745566c5c0bceea506d1f37f11fa32e5 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3116,7 +3116,7 @@ macro_rules! _call_macro_with_each_type_b6c1a18b09f1b468f7fe474905bf186701a2515d }}; } -pub use _call_macro_with_each_type_b6c1a18b09f1b468f7fe474905bf186701a2515d5ea621cc2976a8857507759c as call_macro_with_each_type; +pub use _call_macro_with_each_type_ea152ece0f1c4feff54daa63f53e0d91745566c5c0bceea506d1f37f11fa32e5 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index 8356d31f6..ad01cdfe3 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -2833,7 +2833,7 @@ self.third_option.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_58d86cd68e84cb99c63b6fed86028cacc66ababc6b700b8a3c3f037f3eb2649b { +macro_rules! _call_macro_with_each_type_2bf087756706b56f8b38928bbba40f9eedcf69145a972ba9e374824f7fbaf75e { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2844,7 +2844,7 @@ macro_rules! _call_macro_with_each_type_58d86cd68e84cb99c63b6fed86028cacc66ababc }}; } -pub use _call_macro_with_each_type_58d86cd68e84cb99c63b6fed86028cacc66ababc6b700b8a3c3f037f3eb2649b as call_macro_with_each_type; +pub use _call_macro_with_each_type_2bf087756706b56f8b38928bbba40f9eedcf69145a972ba9e374824f7fbaf75e as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index db683011b..e2c7e0682 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -2841,7 +2841,7 @@ self.max_string.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_6c6fcf0d09aabf041e68a1515efab2c7a4d8b74d95f4af21a71c061ef03a25af { +macro_rules! _call_macro_with_each_type_3b6fdd9b312bfe9bbcd01bad924ec53bffd659b9fdfa0b891080493cfc2dd251 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2852,7 +2852,7 @@ macro_rules! _call_macro_with_each_type_6c6fcf0d09aabf041e68a1515efab2c7a4d8b74d }}; } -pub use _call_macro_with_each_type_6c6fcf0d09aabf041e68a1515efab2c7a4d8b74d95f4af21a71c061ef03a25af as call_macro_with_each_type; +pub use _call_macro_with_each_type_3b6fdd9b312bfe9bbcd01bad924ec53bffd659b9fdfa0b891080493cfc2dd251 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index 9b22468a1..99d5621a8 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -4476,7 +4476,7 @@ self.nested_union.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_814ad56babac15349641febbae8212a8ab3f83bc8efd0a9328b52708a120645a { +macro_rules! _call_macro_with_each_type_2a40f4dfbf0c23f84fa588220f7239e5cd052655abe5872449f20bbf435b8787 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -4529,7 +4529,7 @@ macro_rules! _call_macro_with_each_type_814ad56babac15349641febbae8212a8ab3f83bc }}; } -pub use _call_macro_with_each_type_814ad56babac15349641febbae8212a8ab3f83bc8efd0a9328b52708a120645a as call_macro_with_each_type; +pub use _call_macro_with_each_type_2a40f4dfbf0c23f84fa588220f7239e5cd052655abe5872449f20bbf435b8787 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index 9ad8b737b..af171ed3f 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -3172,7 +3172,7 @@ impl WriteXdr for IntUnion2 { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_41faaa1c6389c8da953ba6dc1a385b706e137b93cf4363ad6a999215fcfdb0bc { +macro_rules! _call_macro_with_each_type_b06755bf4a58cdc4ade236802a924cf482872054d0374f81a9fa92e7788e9ec9 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3191,7 +3191,7 @@ macro_rules! _call_macro_with_each_type_41faaa1c6389c8da953ba6dc1a385b706e137b93 }}; } -pub use _call_macro_with_each_type_41faaa1c6389c8da953ba6dc1a385b706e137b93cf4363ad6a999215fcfdb0bc as call_macro_with_each_type; +pub use _call_macro_with_each_type_b06755bf4a58cdc4ade236802a924cf482872054d0374f81a9fa92e7788e9ec9 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index b141afc7c..c08e41a20 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -2878,7 +2878,7 @@ impl WriteXdr for AccountFlags { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_c00f0c7ee3472652a59efe54781c8e9a11a055003909f57ad84267ac05008abd { +macro_rules! _call_macro_with_each_type_39aa2922012c38afdb400c9905f00f456c0254f690926f3df203f000eacd9a67 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2887,7 +2887,7 @@ macro_rules! _call_macro_with_each_type_c00f0c7ee3472652a59efe54781c8e9a11a05500 }}; } -pub use _call_macro_with_each_type_c00f0c7ee3472652a59efe54781c8e9a11a055003909f57ad84267ac05008abd as call_macro_with_each_type; +pub use _call_macro_with_each_type_39aa2922012c38afdb400c9905f00f456c0254f690926f3df203f000eacd9a67 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index c94acc546..ddfc021ab 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -2804,7 +2804,7 @@ pub type TestArray2 = VecM::; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_ab32b5b14733c592876e16ba870dfa31ed9dc87909b0b43d41b53b0153792e75 { +macro_rules! _call_macro_with_each_type_88d60636a6598f426862cda427140d12b4e8f5f64a6b7d0512361727afbabe77 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2815,7 +2815,7 @@ macro_rules! _call_macro_with_each_type_ab32b5b14733c592876e16ba870dfa31ed9dc879 }}; } -pub use _call_macro_with_each_type_ab32b5b14733c592876e16ba870dfa31ed9dc87909b0b43d41b53b0153792e75 as call_macro_with_each_type; +pub use _call_macro_with_each_type_88d60636a6598f426862cda427140d12b4e8f5f64a6b7d0512361727afbabe77 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index cb409d13d..7dd525581 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -3180,7 +3180,7 @@ Self::Blue2 => "Blue2", #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_03c2a103be81d5866909c1a9b63857b87b586004b71facdd64b932a7aa688b72 { +macro_rules! _call_macro_with_each_type_5dd8baea08297014cf6d9fee29d033253bed54eccb920a09737dd71d9e681b2f { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_03c2a103be81d5866909c1a9b63857b87b586004 }}; } -pub use _call_macro_with_each_type_03c2a103be81d5866909c1a9b63857b87b586004b71facdd64b932a7aa688b72 as call_macro_with_each_type; +pub use _call_macro_with_each_type_5dd8baea08297014cf6d9fee29d033253bed54eccb920a09737dd71d9e681b2f as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 7abffbf79..9b28d71ff 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -3101,7 +3101,7 @@ Self::Offer => ().write_xdr(w)?, #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_2d97ab60593aae65366cedbc8d7c1166dd446746434b62f3f7cb8f28310f9cf4 { +macro_rules! _call_macro_with_each_type_543036b3def58cfe3101b4ca34d2913104dc943115109bff981c0bee31722798 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3118,7 +3118,7 @@ macro_rules! _call_macro_with_each_type_2d97ab60593aae65366cedbc8d7c1166dd446746 }}; } -pub use _call_macro_with_each_type_2d97ab60593aae65366cedbc8d7c1166dd446746434b62f3f7cb8f28310f9cf4 as call_macro_with_each_type; +pub use _call_macro_with_each_type_543036b3def58cfe3101b4ca34d2913104dc943115109bff981c0bee31722798 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index 004d0523a..73f0e02a3 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -2834,7 +2834,7 @@ self.third_option.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_59540777b0327956eb5415514add930c472e7de4e37184dfa74795d616f9875d { +macro_rules! _call_macro_with_each_type_6b04f7509bb4f245927e9b1a85928b05f715cdfeed69f2a91b290104da1aa569 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2845,7 +2845,7 @@ macro_rules! _call_macro_with_each_type_59540777b0327956eb5415514add930c472e7de4 }}; } -pub use _call_macro_with_each_type_59540777b0327956eb5415514add930c472e7de4e37184dfa74795d616f9875d as call_macro_with_each_type; +pub use _call_macro_with_each_type_6b04f7509bb4f245927e9b1a85928b05f715cdfeed69f2a91b290104da1aa569 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index ef4d0e73f..b1060bf35 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -2842,7 +2842,7 @@ self.max_string.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_7d7dc5bf933bd4adb4a67c9e209bd5500d3ac07d52dc3146e1bd5383519fc342 { +macro_rules! _call_macro_with_each_type_6a4396189696ec818792e362343e8cadc0aed7bf759f8251345b30632755c02f { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2853,7 +2853,7 @@ macro_rules! _call_macro_with_each_type_7d7dc5bf933bd4adb4a67c9e209bd5500d3ac07d }}; } -pub use _call_macro_with_each_type_7d7dc5bf933bd4adb4a67c9e209bd5500d3ac07d52dc3146e1bd5383519fc342 as call_macro_with_each_type; +pub use _call_macro_with_each_type_6a4396189696ec818792e362343e8cadc0aed7bf759f8251345b30632755c02f as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index ea5a53701..fb5ac0ef1 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -4478,7 +4478,7 @@ self.nested_union.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_adebb4692a0fdd71aa2cc2e351c611b05c64f4d636e21458996122e823978a61 { +macro_rules! _call_macro_with_each_type_246650ec3da6a47fa9d98159f3b41c6a4c45dbaf68d6ad5cfad02b0101d4e983 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -4531,7 +4531,7 @@ macro_rules! _call_macro_with_each_type_adebb4692a0fdd71aa2cc2e351c611b05c64f4d6 }}; } -pub use _call_macro_with_each_type_adebb4692a0fdd71aa2cc2e351c611b05c64f4d636e21458996122e823978a61 as call_macro_with_each_type; +pub use _call_macro_with_each_type_246650ec3da6a47fa9d98159f3b41c6a4c45dbaf68d6ad5cfad02b0101d4e983 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index fbbf52cec..d4303eb08 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -3174,7 +3174,7 @@ impl WriteXdr for IntUnion2 { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_d63f5de629d12eba02922f123f0547e9eff5460d475c54163bb76b57be65e30d { +macro_rules! _call_macro_with_each_type_cd6e4f23ff27b6b5d2d930232808270230458251208274bd545652ec703bb921 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_d63f5de629d12eba02922f123f0547e9eff5460d }}; } -pub use _call_macro_with_each_type_d63f5de629d12eba02922f123f0547e9eff5460d475c54163bb76b57be65e30d as call_macro_with_each_type; +pub use _call_macro_with_each_type_cd6e4f23ff27b6b5d2d930232808270230458251208274bd545652ec703bb921 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 64a088134..33dfc4c2e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,7 +4,7 @@ require 'pry' require 'xdrgen' -SPEC_ROOT = __dir__ +SPEC_ROOT = 'spec/' Dir["#{__dir__}/support/**/*.rb"].each { |f| require f } From 4fcfbfb1192751b6c4996d97c242b9906835b6ac Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 9 Apr 2024 21:42:09 +1000 Subject: [PATCH 17/20] fix --- spec/output/generator_spec_rust/block_comments.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/const.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/enum.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/nesting.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/optional.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/struct.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/test.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/union.x/MyXDR.rs | 4 ++-- .../block_comments.x/MyXDR.rs | 4 ++-- .../const.x/MyXDR.rs | 4 ++-- .../enum.x/MyXDR.rs | 4 ++-- .../nesting.x/MyXDR.rs | 4 ++-- .../optional.x/MyXDR.rs | 4 ++-- .../struct.x/MyXDR.rs | 4 ++-- .../test.x/MyXDR.rs | 4 ++-- .../union.x/MyXDR.rs | 4 ++-- .../block_comments.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/const.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/test.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/union.x/MyXDR.rs | 4 ++-- spec/spec_helper.rb | 2 +- 25 files changed, 49 insertions(+), 49 deletions(-) diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index a20b0d6b8..968aafe61 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -2878,7 +2878,7 @@ impl WriteXdr for AccountFlags { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_74ae33c5a9c08460c7f65c74189bedd1ebf8e378c272e3e934d34e7c4d0e1e21 { +macro_rules! _call_macro_with_each_type_e007730ed15d1531aabb6a25bf1bf48ab7f36abe9ded1c26440302d011ace0ed { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2887,7 +2887,7 @@ macro_rules! _call_macro_with_each_type_74ae33c5a9c08460c7f65c74189bedd1ebf8e378 }}; } -pub use _call_macro_with_each_type_74ae33c5a9c08460c7f65c74189bedd1ebf8e378c272e3e934d34e7c4d0e1e21 as call_macro_with_each_type; +pub use _call_macro_with_each_type_e007730ed15d1531aabb6a25bf1bf48ab7f36abe9ded1c26440302d011ace0ed as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index 1a75e4d7b..5b8117351 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -2804,7 +2804,7 @@ pub type TestArray2 = VecM::; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_e4fedcf76f096d35fa1f6198342d56f66e4f6f3a5cab26a4fd29a7e52d470238 { +macro_rules! _call_macro_with_each_type_47738ab2d5942a92fcac595e660739e3975bbb8cb96f9e9613cf641bbfd6d910 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2815,7 +2815,7 @@ macro_rules! _call_macro_with_each_type_e4fedcf76f096d35fa1f6198342d56f66e4f6f3a }}; } -pub use _call_macro_with_each_type_e4fedcf76f096d35fa1f6198342d56f66e4f6f3a5cab26a4fd29a7e52d470238 as call_macro_with_each_type; +pub use _call_macro_with_each_type_47738ab2d5942a92fcac595e660739e3975bbb8cb96f9e9613cf641bbfd6d910 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index c81e789c1..a5e73c4bc 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -3180,7 +3180,7 @@ Self::Blue2 => "Blue2", #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_c4a7f685cb1d6ff0896b8e545a2b8b977f8d962c5d5966b3ba96291609022cf3 { +macro_rules! _call_macro_with_each_type_243de49c046908058144dd24e75fc05f4203e7c0f8c33660d61f82e97cdd2e17 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_c4a7f685cb1d6ff0896b8e545a2b8b977f8d962c }}; } -pub use _call_macro_with_each_type_c4a7f685cb1d6ff0896b8e545a2b8b977f8d962c5d5966b3ba96291609022cf3 as call_macro_with_each_type; +pub use _call_macro_with_each_type_243de49c046908058144dd24e75fc05f4203e7c0f8c33660d61f82e97cdd2e17 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 37df9acde..c5477ad80 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -3101,7 +3101,7 @@ Self::Offer => ().write_xdr(w)?, #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_d0ff637ead9d76881519748c5751596952f7ad41e9fc1fd713666af21d0b2402 { +macro_rules! _call_macro_with_each_type_8d54e1747822aa2bf8e8f494219e00cc8004118f46684ce4ca8ad7d8a5891778 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3118,7 +3118,7 @@ macro_rules! _call_macro_with_each_type_d0ff637ead9d76881519748c5751596952f7ad41 }}; } -pub use _call_macro_with_each_type_d0ff637ead9d76881519748c5751596952f7ad41e9fc1fd713666af21d0b2402 as call_macro_with_each_type; +pub use _call_macro_with_each_type_8d54e1747822aa2bf8e8f494219e00cc8004118f46684ce4ca8ad7d8a5891778 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 0e83acd19..696896287 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -2834,7 +2834,7 @@ self.third_option.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_fecabbf83b11ef8308ffd4c2f6f07db3ecc043ea692e9216792ccfb7da5dbb97 { +macro_rules! _call_macro_with_each_type_1dc64c2b3a296be67ded360981166a78e23ee700494f9bc0e82bcbba2cabd6fc { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2845,7 +2845,7 @@ macro_rules! _call_macro_with_each_type_fecabbf83b11ef8308ffd4c2f6f07db3ecc043ea }}; } -pub use _call_macro_with_each_type_fecabbf83b11ef8308ffd4c2f6f07db3ecc043ea692e9216792ccfb7da5dbb97 as call_macro_with_each_type; +pub use _call_macro_with_each_type_1dc64c2b3a296be67ded360981166a78e23ee700494f9bc0e82bcbba2cabd6fc as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index 0fedfac5e..cfc8846c1 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -2842,7 +2842,7 @@ self.max_string.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_a215be981ee6741a031d48dc3a3e519f8d70545b67b3f5707b9a33af8636c8d6 { +macro_rules! _call_macro_with_each_type_41b8c5f04975a88bf46b4b6c3694db3c2cba6a3aacfa418d0a29ce095620190e { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2853,7 +2853,7 @@ macro_rules! _call_macro_with_each_type_a215be981ee6741a031d48dc3a3e519f8d70545b }}; } -pub use _call_macro_with_each_type_a215be981ee6741a031d48dc3a3e519f8d70545b67b3f5707b9a33af8636c8d6 as call_macro_with_each_type; +pub use _call_macro_with_each_type_41b8c5f04975a88bf46b4b6c3694db3c2cba6a3aacfa418d0a29ce095620190e as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index ae8fdf837..a94ec0943 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -4478,7 +4478,7 @@ self.nested_union.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_e24b0e9c3b4b66eafcd77916658ca28e1d60d143481be4d82bf8cce4463a7367 { +macro_rules! _call_macro_with_each_type_255925477e5b5b432fca56b88729d20918d615736a78ab7f4b77e7478d05d189 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -4531,7 +4531,7 @@ macro_rules! _call_macro_with_each_type_e24b0e9c3b4b66eafcd77916658ca28e1d60d143 }}; } -pub use _call_macro_with_each_type_e24b0e9c3b4b66eafcd77916658ca28e1d60d143481be4d82bf8cce4463a7367 as call_macro_with_each_type; +pub use _call_macro_with_each_type_255925477e5b5b432fca56b88729d20918d615736a78ab7f4b77e7478d05d189 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 258804b13..7858d048a 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -3174,7 +3174,7 @@ impl WriteXdr for IntUnion2 { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_3cf7b400d9d6ac9daa98597b9f72302fa5fab52590401d883ccbd8420cda36fa { +macro_rules! _call_macro_with_each_type_217404a3f70e4c283a651abdfd38946e3e1f6bcb61ad0ffb4588bd9679271e70 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_3cf7b400d9d6ac9daa98597b9f72302fa5fab525 }}; } -pub use _call_macro_with_each_type_3cf7b400d9d6ac9daa98597b9f72302fa5fab52590401d883ccbd8420cda36fa as call_macro_with_each_type; +pub use _call_macro_with_each_type_217404a3f70e4c283a651abdfd38946e3e1f6bcb61ad0ffb4588bd9679271e70 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index 654cf5e64..4adaac0a7 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -2878,7 +2878,7 @@ impl WriteXdr for AccountFlags { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_315c3ec204e8759c65e2143522758b394627f663209ed117a1bdeb1b461fc5d8 { +macro_rules! _call_macro_with_each_type_94a67889111697663f7d5c84bc375f8405353b3b13bababdd38499098049f432 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2887,7 +2887,7 @@ macro_rules! _call_macro_with_each_type_315c3ec204e8759c65e2143522758b394627f663 }}; } -pub use _call_macro_with_each_type_315c3ec204e8759c65e2143522758b394627f663209ed117a1bdeb1b461fc5d8 as call_macro_with_each_type; +pub use _call_macro_with_each_type_94a67889111697663f7d5c84bc375f8405353b3b13bababdd38499098049f432 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index fc1cd118b..8c641b43f 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -2804,7 +2804,7 @@ pub type TestArray2 = VecM::; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_cc81650d8e35ad6a04efc88604011939a9121acf12701e7b66fed5ea301835c1 { +macro_rules! _call_macro_with_each_type_4bc279c626f9e2df4e2dd0b80f6ede0e8a072d549e5b8233b1801dcfd1cc6e42 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2815,7 +2815,7 @@ macro_rules! _call_macro_with_each_type_cc81650d8e35ad6a04efc88604011939a9121acf }}; } -pub use _call_macro_with_each_type_cc81650d8e35ad6a04efc88604011939a9121acf12701e7b66fed5ea301835c1 as call_macro_with_each_type; +pub use _call_macro_with_each_type_4bc279c626f9e2df4e2dd0b80f6ede0e8a072d549e5b8233b1801dcfd1cc6e42 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index 5ef06ee3c..eca38e9c1 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -3179,7 +3179,7 @@ Self::Blue2 => "Blue2", #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_3c6b545072b61bac61c15b38aea09349377b6516a09c130fc4365b6b3879fe6f { +macro_rules! _call_macro_with_each_type_cd89cb865ce945805a167bda105f81013bf2ee4c46de96e6b6fb64b100bc5d5e { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3192,7 +3192,7 @@ macro_rules! _call_macro_with_each_type_3c6b545072b61bac61c15b38aea09349377b6516 }}; } -pub use _call_macro_with_each_type_3c6b545072b61bac61c15b38aea09349377b6516a09c130fc4365b6b3879fe6f as call_macro_with_each_type; +pub use _call_macro_with_each_type_cd89cb865ce945805a167bda105f81013bf2ee4c46de96e6b6fb64b100bc5d5e as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index da4cb5541..948340830 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -3099,7 +3099,7 @@ Self::Offer => ().write_xdr(w)?, #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_ea152ece0f1c4feff54daa63f53e0d91745566c5c0bceea506d1f37f11fa32e5 { +macro_rules! _call_macro_with_each_type_7d7a423e447abad5c5397128eee812091eece2125038988ebd24e757311fc048 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3116,7 +3116,7 @@ macro_rules! _call_macro_with_each_type_ea152ece0f1c4feff54daa63f53e0d91745566c5 }}; } -pub use _call_macro_with_each_type_ea152ece0f1c4feff54daa63f53e0d91745566c5c0bceea506d1f37f11fa32e5 as call_macro_with_each_type; +pub use _call_macro_with_each_type_7d7a423e447abad5c5397128eee812091eece2125038988ebd24e757311fc048 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index ad01cdfe3..363aa4abd 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -2833,7 +2833,7 @@ self.third_option.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_2bf087756706b56f8b38928bbba40f9eedcf69145a972ba9e374824f7fbaf75e { +macro_rules! _call_macro_with_each_type_e0b9d387dfe232537f78f9bf84c7f559a192410d616486efcdc084aea557a625 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2844,7 +2844,7 @@ macro_rules! _call_macro_with_each_type_2bf087756706b56f8b38928bbba40f9eedcf6914 }}; } -pub use _call_macro_with_each_type_2bf087756706b56f8b38928bbba40f9eedcf69145a972ba9e374824f7fbaf75e as call_macro_with_each_type; +pub use _call_macro_with_each_type_e0b9d387dfe232537f78f9bf84c7f559a192410d616486efcdc084aea557a625 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index e2c7e0682..4166bcc9a 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -2841,7 +2841,7 @@ self.max_string.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_3b6fdd9b312bfe9bbcd01bad924ec53bffd659b9fdfa0b891080493cfc2dd251 { +macro_rules! _call_macro_with_each_type_a318934cc1b6518bb0d8aad20600d5ad974462c7ee987467db18d2cf796caa85 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2852,7 +2852,7 @@ macro_rules! _call_macro_with_each_type_3b6fdd9b312bfe9bbcd01bad924ec53bffd659b9 }}; } -pub use _call_macro_with_each_type_3b6fdd9b312bfe9bbcd01bad924ec53bffd659b9fdfa0b891080493cfc2dd251 as call_macro_with_each_type; +pub use _call_macro_with_each_type_a318934cc1b6518bb0d8aad20600d5ad974462c7ee987467db18d2cf796caa85 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index 99d5621a8..e64207a6a 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -4476,7 +4476,7 @@ self.nested_union.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_2a40f4dfbf0c23f84fa588220f7239e5cd052655abe5872449f20bbf435b8787 { +macro_rules! _call_macro_with_each_type_6e9ab457662d197443355ec0a2131a04caa3bff92205238a02de7182f9fbadaa { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -4529,7 +4529,7 @@ macro_rules! _call_macro_with_each_type_2a40f4dfbf0c23f84fa588220f7239e5cd052655 }}; } -pub use _call_macro_with_each_type_2a40f4dfbf0c23f84fa588220f7239e5cd052655abe5872449f20bbf435b8787 as call_macro_with_each_type; +pub use _call_macro_with_each_type_6e9ab457662d197443355ec0a2131a04caa3bff92205238a02de7182f9fbadaa as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index af171ed3f..b40455190 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -3172,7 +3172,7 @@ impl WriteXdr for IntUnion2 { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_b06755bf4a58cdc4ade236802a924cf482872054d0374f81a9fa92e7788e9ec9 { +macro_rules! _call_macro_with_each_type_f6bce9dd0735d7f21a39f7176b2bb745ffd13395288a084ce5eb8bd76de0c574 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3191,7 +3191,7 @@ macro_rules! _call_macro_with_each_type_b06755bf4a58cdc4ade236802a924cf482872054 }}; } -pub use _call_macro_with_each_type_b06755bf4a58cdc4ade236802a924cf482872054d0374f81a9fa92e7788e9ec9 as call_macro_with_each_type; +pub use _call_macro_with_each_type_f6bce9dd0735d7f21a39f7176b2bb745ffd13395288a084ce5eb8bd76de0c574 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index c08e41a20..225db99ea 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -2878,7 +2878,7 @@ impl WriteXdr for AccountFlags { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_39aa2922012c38afdb400c9905f00f456c0254f690926f3df203f000eacd9a67 { +macro_rules! _call_macro_with_each_type_b9cd3ee79c91f1522d550854e32be84eca5e570dfb925ae37c4d3dbb5654d932 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2887,7 +2887,7 @@ macro_rules! _call_macro_with_each_type_39aa2922012c38afdb400c9905f00f456c0254f6 }}; } -pub use _call_macro_with_each_type_39aa2922012c38afdb400c9905f00f456c0254f690926f3df203f000eacd9a67 as call_macro_with_each_type; +pub use _call_macro_with_each_type_b9cd3ee79c91f1522d550854e32be84eca5e570dfb925ae37c4d3dbb5654d932 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index ddfc021ab..94046a8b5 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -2804,7 +2804,7 @@ pub type TestArray2 = VecM::; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_88d60636a6598f426862cda427140d12b4e8f5f64a6b7d0512361727afbabe77 { +macro_rules! _call_macro_with_each_type_db8c7dc422c9b09a61cb4faf10abf954911365a83820915396f65b03fe2664ce { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2815,7 +2815,7 @@ macro_rules! _call_macro_with_each_type_88d60636a6598f426862cda427140d12b4e8f5f6 }}; } -pub use _call_macro_with_each_type_88d60636a6598f426862cda427140d12b4e8f5f64a6b7d0512361727afbabe77 as call_macro_with_each_type; +pub use _call_macro_with_each_type_db8c7dc422c9b09a61cb4faf10abf954911365a83820915396f65b03fe2664ce as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index 7dd525581..bf7a1d1de 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -3180,7 +3180,7 @@ Self::Blue2 => "Blue2", #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_5dd8baea08297014cf6d9fee29d033253bed54eccb920a09737dd71d9e681b2f { +macro_rules! _call_macro_with_each_type_aa19b80318b0b7d6b41ff992531f171f853eac9d20d41cb686f4e888a6eaa384 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_5dd8baea08297014cf6d9fee29d033253bed54ec }}; } -pub use _call_macro_with_each_type_5dd8baea08297014cf6d9fee29d033253bed54eccb920a09737dd71d9e681b2f as call_macro_with_each_type; +pub use _call_macro_with_each_type_aa19b80318b0b7d6b41ff992531f171f853eac9d20d41cb686f4e888a6eaa384 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 9b28d71ff..4086893f4 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -3101,7 +3101,7 @@ Self::Offer => ().write_xdr(w)?, #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_543036b3def58cfe3101b4ca34d2913104dc943115109bff981c0bee31722798 { +macro_rules! _call_macro_with_each_type_37d873f1badd12f5fb6d13139d9eccc769ecb171a460cc2a047c71043916ec92 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3118,7 +3118,7 @@ macro_rules! _call_macro_with_each_type_543036b3def58cfe3101b4ca34d2913104dc9431 }}; } -pub use _call_macro_with_each_type_543036b3def58cfe3101b4ca34d2913104dc943115109bff981c0bee31722798 as call_macro_with_each_type; +pub use _call_macro_with_each_type_37d873f1badd12f5fb6d13139d9eccc769ecb171a460cc2a047c71043916ec92 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index 73f0e02a3..df2e05ed4 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -2834,7 +2834,7 @@ self.third_option.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_6b04f7509bb4f245927e9b1a85928b05f715cdfeed69f2a91b290104da1aa569 { +macro_rules! _call_macro_with_each_type_8e5cc2f3c0250b3dfb8c1b526a989837796eeaec3325c182341c4d425642fd91 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2845,7 +2845,7 @@ macro_rules! _call_macro_with_each_type_6b04f7509bb4f245927e9b1a85928b05f715cdfe }}; } -pub use _call_macro_with_each_type_6b04f7509bb4f245927e9b1a85928b05f715cdfeed69f2a91b290104da1aa569 as call_macro_with_each_type; +pub use _call_macro_with_each_type_8e5cc2f3c0250b3dfb8c1b526a989837796eeaec3325c182341c4d425642fd91 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index b1060bf35..a241f93db 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -2842,7 +2842,7 @@ self.max_string.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_6a4396189696ec818792e362343e8cadc0aed7bf759f8251345b30632755c02f { +macro_rules! _call_macro_with_each_type_b9bfa046b276eafc1c4da35a004085c34eaeef3e48a85250ceb2755bca3c3d24 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2853,7 +2853,7 @@ macro_rules! _call_macro_with_each_type_6a4396189696ec818792e362343e8cadc0aed7bf }}; } -pub use _call_macro_with_each_type_6a4396189696ec818792e362343e8cadc0aed7bf759f8251345b30632755c02f as call_macro_with_each_type; +pub use _call_macro_with_each_type_b9bfa046b276eafc1c4da35a004085c34eaeef3e48a85250ceb2755bca3c3d24 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index fb5ac0ef1..3871f66e2 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -4478,7 +4478,7 @@ self.nested_union.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_246650ec3da6a47fa9d98159f3b41c6a4c45dbaf68d6ad5cfad02b0101d4e983 { +macro_rules! _call_macro_with_each_type_c106885159bca8210947544606f86998be0bb80a6cc6dd31e2372dacf74d2abd { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -4531,7 +4531,7 @@ macro_rules! _call_macro_with_each_type_246650ec3da6a47fa9d98159f3b41c6a4c45dbaf }}; } -pub use _call_macro_with_each_type_246650ec3da6a47fa9d98159f3b41c6a4c45dbaf68d6ad5cfad02b0101d4e983 as call_macro_with_each_type; +pub use _call_macro_with_each_type_c106885159bca8210947544606f86998be0bb80a6cc6dd31e2372dacf74d2abd as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index d4303eb08..3bf938489 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -3174,7 +3174,7 @@ impl WriteXdr for IntUnion2 { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_cd6e4f23ff27b6b5d2d930232808270230458251208274bd545652ec703bb921 { +macro_rules! _call_macro_with_each_type_d2878762de1bf72819ba8a40aeaf853b317aed2c304b1cb2e50a19df3a8323e1 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_cd6e4f23ff27b6b5d2d930232808270230458251 }}; } -pub use _call_macro_with_each_type_cd6e4f23ff27b6b5d2d930232808270230458251208274bd545652ec703bb921 as call_macro_with_each_type; +pub use _call_macro_with_each_type_d2878762de1bf72819ba8a40aeaf853b317aed2c304b1cb2e50a19df3a8323e1 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 33dfc4c2e..b38c824c9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,7 +4,7 @@ require 'pry' require 'xdrgen' -SPEC_ROOT = 'spec/' +SPEC_ROOT = 'spec' Dir["#{__dir__}/support/**/*.rb"].each { |f| require f } From 96cf5488cea3dd9cef0c8578c422a99500a45e5f Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 9 Apr 2024 21:57:47 +1000 Subject: [PATCH 18/20] test --- lib/xdrgen/generators/rust.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index 2a44cff75..e3027fcc4 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -96,6 +96,7 @@ def render_lib(out) end def render_type_macro(out, types) + puts "OUTPUT DIR: #{@output.output_dir}" out.puts <<-EOS.strip_heredoc #[doc(hidden)] #[macro_export] From 736398401ba08dfa8f5fcb577c1d7ed935cc51de Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 9 Apr 2024 22:26:49 +1000 Subject: [PATCH 19/20] fix --- lib/xdrgen/generators/rust.rb | 1 - lib/xdrgen/output.rb | 2 +- spec/output/generator_spec_rust/block_comments.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/const.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/enum.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/nesting.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/optional.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/struct.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/test.x/MyXDR.rs | 4 ++-- spec/output/generator_spec_rust/union.x/MyXDR.rs | 4 ++-- .../block_comments.x/MyXDR.rs | 4 ++-- .../const.x/MyXDR.rs | 4 ++-- .../enum.x/MyXDR.rs | 4 ++-- .../nesting.x/MyXDR.rs | 4 ++-- .../optional.x/MyXDR.rs | 4 ++-- .../struct.x/MyXDR.rs | 4 ++-- .../test.x/MyXDR.rs | 4 ++-- .../union.x/MyXDR.rs | 4 ++-- .../block_comments.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/const.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/test.x/MyXDR.rs | 4 ++-- .../generator_spec_rust_custom_str_impls/union.x/MyXDR.rs | 4 ++-- 26 files changed, 49 insertions(+), 50 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index e3027fcc4..2a44cff75 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -96,7 +96,6 @@ def render_lib(out) end def render_type_macro(out, types) - puts "OUTPUT DIR: #{@output.output_dir}" out.puts <<-EOS.strip_heredoc #[doc(hidden)] #[macro_export] diff --git a/lib/xdrgen/output.rb b/lib/xdrgen/output.rb index 4f598406d..e2af53533 100644 --- a/lib/xdrgen/output.rb +++ b/lib/xdrgen/output.rb @@ -17,7 +17,7 @@ def inputs_hash Digest::SHA256.hexdigest( [ Digest::SHA256.hexdigest(relative_source_paths.map { |p| Digest::SHA256.file(p).hexdigest }.join), - Digest::SHA256.hexdigest(@source_paths.map { |p| Digest::SHA256.hexdigest(p) }.join), + Digest::SHA256.hexdigest(relative_source_paths.map { |p| Digest::SHA256.hexdigest(p) }.join), Digest::SHA256.hexdigest(@output_dir), ].join ) diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index 968aafe61..4444409ca 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -2878,7 +2878,7 @@ impl WriteXdr for AccountFlags { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_e007730ed15d1531aabb6a25bf1bf48ab7f36abe9ded1c26440302d011ace0ed { +macro_rules! _call_macro_with_each_type_d7fc2f197127df606e7c3c22fa61d131623fb36d2be217c52672924969e49d0d { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2887,7 +2887,7 @@ macro_rules! _call_macro_with_each_type_e007730ed15d1531aabb6a25bf1bf48ab7f36abe }}; } -pub use _call_macro_with_each_type_e007730ed15d1531aabb6a25bf1bf48ab7f36abe9ded1c26440302d011ace0ed as call_macro_with_each_type; +pub use _call_macro_with_each_type_d7fc2f197127df606e7c3c22fa61d131623fb36d2be217c52672924969e49d0d as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index 5b8117351..6036d2f71 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -2804,7 +2804,7 @@ pub type TestArray2 = VecM::; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_47738ab2d5942a92fcac595e660739e3975bbb8cb96f9e9613cf641bbfd6d910 { +macro_rules! _call_macro_with_each_type_a7dae5f3a6aa197f11de2dc3b36eda238bc02a177a6148b110c1eba0f6e157d5 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2815,7 +2815,7 @@ macro_rules! _call_macro_with_each_type_47738ab2d5942a92fcac595e660739e3975bbb8c }}; } -pub use _call_macro_with_each_type_47738ab2d5942a92fcac595e660739e3975bbb8cb96f9e9613cf641bbfd6d910 as call_macro_with_each_type; +pub use _call_macro_with_each_type_a7dae5f3a6aa197f11de2dc3b36eda238bc02a177a6148b110c1eba0f6e157d5 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index a5e73c4bc..31c6ce9df 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -3180,7 +3180,7 @@ Self::Blue2 => "Blue2", #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_243de49c046908058144dd24e75fc05f4203e7c0f8c33660d61f82e97cdd2e17 { +macro_rules! _call_macro_with_each_type_1affe08901838b4233170cdc473594569da207fcd2eec4afbaac41075ecd4114 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_243de49c046908058144dd24e75fc05f4203e7c0 }}; } -pub use _call_macro_with_each_type_243de49c046908058144dd24e75fc05f4203e7c0f8c33660d61f82e97cdd2e17 as call_macro_with_each_type; +pub use _call_macro_with_each_type_1affe08901838b4233170cdc473594569da207fcd2eec4afbaac41075ecd4114 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index c5477ad80..763cfebfe 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -3101,7 +3101,7 @@ Self::Offer => ().write_xdr(w)?, #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_8d54e1747822aa2bf8e8f494219e00cc8004118f46684ce4ca8ad7d8a5891778 { +macro_rules! _call_macro_with_each_type_8980212b367c7fd7f6df3534c44d6e78b7e176e22d223cc4c95be74483a52986 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3118,7 +3118,7 @@ macro_rules! _call_macro_with_each_type_8d54e1747822aa2bf8e8f494219e00cc8004118f }}; } -pub use _call_macro_with_each_type_8d54e1747822aa2bf8e8f494219e00cc8004118f46684ce4ca8ad7d8a5891778 as call_macro_with_each_type; +pub use _call_macro_with_each_type_8980212b367c7fd7f6df3534c44d6e78b7e176e22d223cc4c95be74483a52986 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 696896287..735afa121 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -2834,7 +2834,7 @@ self.third_option.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_1dc64c2b3a296be67ded360981166a78e23ee700494f9bc0e82bcbba2cabd6fc { +macro_rules! _call_macro_with_each_type_bed2d289d7888b3cb894d83ee4181ed26bdc961d47b1e8d798885ce6c17dbcb1 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2845,7 +2845,7 @@ macro_rules! _call_macro_with_each_type_1dc64c2b3a296be67ded360981166a78e23ee700 }}; } -pub use _call_macro_with_each_type_1dc64c2b3a296be67ded360981166a78e23ee700494f9bc0e82bcbba2cabd6fc as call_macro_with_each_type; +pub use _call_macro_with_each_type_bed2d289d7888b3cb894d83ee4181ed26bdc961d47b1e8d798885ce6c17dbcb1 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index cfc8846c1..eaf3053cc 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -2842,7 +2842,7 @@ self.max_string.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_41b8c5f04975a88bf46b4b6c3694db3c2cba6a3aacfa418d0a29ce095620190e { +macro_rules! _call_macro_with_each_type_f5399816ab213168cc346c594e13cf5d33e915736bc78e2994eb1b8a86609391 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2853,7 +2853,7 @@ macro_rules! _call_macro_with_each_type_41b8c5f04975a88bf46b4b6c3694db3c2cba6a3a }}; } -pub use _call_macro_with_each_type_41b8c5f04975a88bf46b4b6c3694db3c2cba6a3aacfa418d0a29ce095620190e as call_macro_with_each_type; +pub use _call_macro_with_each_type_f5399816ab213168cc346c594e13cf5d33e915736bc78e2994eb1b8a86609391 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index a94ec0943..f944eb467 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -4478,7 +4478,7 @@ self.nested_union.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_255925477e5b5b432fca56b88729d20918d615736a78ab7f4b77e7478d05d189 { +macro_rules! _call_macro_with_each_type_0aa79ed8ae8b11603ed635818100b818a4877235c22ef7e7c0ff38389a4f36e2 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -4531,7 +4531,7 @@ macro_rules! _call_macro_with_each_type_255925477e5b5b432fca56b88729d20918d61573 }}; } -pub use _call_macro_with_each_type_255925477e5b5b432fca56b88729d20918d615736a78ab7f4b77e7478d05d189 as call_macro_with_each_type; +pub use _call_macro_with_each_type_0aa79ed8ae8b11603ed635818100b818a4877235c22ef7e7c0ff38389a4f36e2 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 7858d048a..50e50cbb8 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -3174,7 +3174,7 @@ impl WriteXdr for IntUnion2 { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_217404a3f70e4c283a651abdfd38946e3e1f6bcb61ad0ffb4588bd9679271e70 { +macro_rules! _call_macro_with_each_type_a9d35711d4349f79a937c021a1f34d9b6558af3b8fec8f44e84b08e37bc3bd23 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_217404a3f70e4c283a651abdfd38946e3e1f6bcb }}; } -pub use _call_macro_with_each_type_217404a3f70e4c283a651abdfd38946e3e1f6bcb61ad0ffb4588bd9679271e70 as call_macro_with_each_type; +pub use _call_macro_with_each_type_a9d35711d4349f79a937c021a1f34d9b6558af3b8fec8f44e84b08e37bc3bd23 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index 4adaac0a7..8b0868eb5 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -2878,7 +2878,7 @@ impl WriteXdr for AccountFlags { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_94a67889111697663f7d5c84bc375f8405353b3b13bababdd38499098049f432 { +macro_rules! _call_macro_with_each_type_65651c234257097d41984f20914dfd44f91c1a5f2c0050feb44611a0aa539177 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2887,7 +2887,7 @@ macro_rules! _call_macro_with_each_type_94a67889111697663f7d5c84bc375f8405353b3b }}; } -pub use _call_macro_with_each_type_94a67889111697663f7d5c84bc375f8405353b3b13bababdd38499098049f432 as call_macro_with_each_type; +pub use _call_macro_with_each_type_65651c234257097d41984f20914dfd44f91c1a5f2c0050feb44611a0aa539177 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index 8c641b43f..8b0f15666 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -2804,7 +2804,7 @@ pub type TestArray2 = VecM::; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_4bc279c626f9e2df4e2dd0b80f6ede0e8a072d549e5b8233b1801dcfd1cc6e42 { +macro_rules! _call_macro_with_each_type_3987b1b0da55480e72d9b9d05876aab566f3bd4b52c950bf1ace1cbcea0648dd { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2815,7 +2815,7 @@ macro_rules! _call_macro_with_each_type_4bc279c626f9e2df4e2dd0b80f6ede0e8a072d54 }}; } -pub use _call_macro_with_each_type_4bc279c626f9e2df4e2dd0b80f6ede0e8a072d549e5b8233b1801dcfd1cc6e42 as call_macro_with_each_type; +pub use _call_macro_with_each_type_3987b1b0da55480e72d9b9d05876aab566f3bd4b52c950bf1ace1cbcea0648dd as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index eca38e9c1..1165509fa 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -3179,7 +3179,7 @@ Self::Blue2 => "Blue2", #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_cd89cb865ce945805a167bda105f81013bf2ee4c46de96e6b6fb64b100bc5d5e { +macro_rules! _call_macro_with_each_type_5fc3f78c5d821b38fa85791cc5d5b6f50be338cb8b6342606b4d0d4362c8089d { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3192,7 +3192,7 @@ macro_rules! _call_macro_with_each_type_cd89cb865ce945805a167bda105f81013bf2ee4c }}; } -pub use _call_macro_with_each_type_cd89cb865ce945805a167bda105f81013bf2ee4c46de96e6b6fb64b100bc5d5e as call_macro_with_each_type; +pub use _call_macro_with_each_type_5fc3f78c5d821b38fa85791cc5d5b6f50be338cb8b6342606b4d0d4362c8089d as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index 948340830..99a211359 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -3099,7 +3099,7 @@ Self::Offer => ().write_xdr(w)?, #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_7d7a423e447abad5c5397128eee812091eece2125038988ebd24e757311fc048 { +macro_rules! _call_macro_with_each_type_06b17481d5959412d6c7ae97fb96d4db4d534057726369081b728de075be683c { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3116,7 +3116,7 @@ macro_rules! _call_macro_with_each_type_7d7a423e447abad5c5397128eee812091eece212 }}; } -pub use _call_macro_with_each_type_7d7a423e447abad5c5397128eee812091eece2125038988ebd24e757311fc048 as call_macro_with_each_type; +pub use _call_macro_with_each_type_06b17481d5959412d6c7ae97fb96d4db4d534057726369081b728de075be683c as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index 363aa4abd..1f484b484 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -2833,7 +2833,7 @@ self.third_option.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_e0b9d387dfe232537f78f9bf84c7f559a192410d616486efcdc084aea557a625 { +macro_rules! _call_macro_with_each_type_3170ead79299e6af1fa5ac44ee6992f7681cf7c80286dd1cbe2e6660db2ab0d9 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2844,7 +2844,7 @@ macro_rules! _call_macro_with_each_type_e0b9d387dfe232537f78f9bf84c7f559a192410d }}; } -pub use _call_macro_with_each_type_e0b9d387dfe232537f78f9bf84c7f559a192410d616486efcdc084aea557a625 as call_macro_with_each_type; +pub use _call_macro_with_each_type_3170ead79299e6af1fa5ac44ee6992f7681cf7c80286dd1cbe2e6660db2ab0d9 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index 4166bcc9a..bcabcd020 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -2841,7 +2841,7 @@ self.max_string.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_a318934cc1b6518bb0d8aad20600d5ad974462c7ee987467db18d2cf796caa85 { +macro_rules! _call_macro_with_each_type_49a18d13126431dabed30ae4a6c514a084df4a2c93a549318a517844eab20a40 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2852,7 +2852,7 @@ macro_rules! _call_macro_with_each_type_a318934cc1b6518bb0d8aad20600d5ad974462c7 }}; } -pub use _call_macro_with_each_type_a318934cc1b6518bb0d8aad20600d5ad974462c7ee987467db18d2cf796caa85 as call_macro_with_each_type; +pub use _call_macro_with_each_type_49a18d13126431dabed30ae4a6c514a084df4a2c93a549318a517844eab20a40 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index e64207a6a..1f7211a9d 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -4476,7 +4476,7 @@ self.nested_union.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_6e9ab457662d197443355ec0a2131a04caa3bff92205238a02de7182f9fbadaa { +macro_rules! _call_macro_with_each_type_c1547a0cbce873115f3f0aaad38902bdc99f3fe547440cafe94f2d702f7abc42 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -4529,7 +4529,7 @@ macro_rules! _call_macro_with_each_type_6e9ab457662d197443355ec0a2131a04caa3bff9 }}; } -pub use _call_macro_with_each_type_6e9ab457662d197443355ec0a2131a04caa3bff92205238a02de7182f9fbadaa as call_macro_with_each_type; +pub use _call_macro_with_each_type_c1547a0cbce873115f3f0aaad38902bdc99f3fe547440cafe94f2d702f7abc42 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index b40455190..80028a7e3 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -3172,7 +3172,7 @@ impl WriteXdr for IntUnion2 { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_f6bce9dd0735d7f21a39f7176b2bb745ffd13395288a084ce5eb8bd76de0c574 { +macro_rules! _call_macro_with_each_type_043b3282ddd717aa5167744c1f532017c69c5d20015a63c1e79d004b6daebfb6 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3191,7 +3191,7 @@ macro_rules! _call_macro_with_each_type_f6bce9dd0735d7f21a39f7176b2bb745ffd13395 }}; } -pub use _call_macro_with_each_type_f6bce9dd0735d7f21a39f7176b2bb745ffd13395288a084ce5eb8bd76de0c574 as call_macro_with_each_type; +pub use _call_macro_with_each_type_043b3282ddd717aa5167744c1f532017c69c5d20015a63c1e79d004b6daebfb6 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index 225db99ea..774f38738 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -2878,7 +2878,7 @@ impl WriteXdr for AccountFlags { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_b9cd3ee79c91f1522d550854e32be84eca5e570dfb925ae37c4d3dbb5654d932 { +macro_rules! _call_macro_with_each_type_258a538659d11cae025394f94e4aeb512957d32603f08c10d142c0e57bb7db98 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2887,7 +2887,7 @@ macro_rules! _call_macro_with_each_type_b9cd3ee79c91f1522d550854e32be84eca5e570d }}; } -pub use _call_macro_with_each_type_b9cd3ee79c91f1522d550854e32be84eca5e570dfb925ae37c4d3dbb5654d932 as call_macro_with_each_type; +pub use _call_macro_with_each_type_258a538659d11cae025394f94e4aeb512957d32603f08c10d142c0e57bb7db98 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index 94046a8b5..e457690d8 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -2804,7 +2804,7 @@ pub type TestArray2 = VecM::; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_db8c7dc422c9b09a61cb4faf10abf954911365a83820915396f65b03fe2664ce { +macro_rules! _call_macro_with_each_type_049e244dc4ffa0895d111b2d9da890f2808a4abc7645410179cf0554332daede { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2815,7 +2815,7 @@ macro_rules! _call_macro_with_each_type_db8c7dc422c9b09a61cb4faf10abf954911365a8 }}; } -pub use _call_macro_with_each_type_db8c7dc422c9b09a61cb4faf10abf954911365a83820915396f65b03fe2664ce as call_macro_with_each_type; +pub use _call_macro_with_each_type_049e244dc4ffa0895d111b2d9da890f2808a4abc7645410179cf0554332daede as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index bf7a1d1de..79f84af50 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -3180,7 +3180,7 @@ Self::Blue2 => "Blue2", #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_aa19b80318b0b7d6b41ff992531f171f853eac9d20d41cb686f4e888a6eaa384 { +macro_rules! _call_macro_with_each_type_ebf5b81aab52989060a7a2847c44fee53adec878dc6963b863dc1470575c89e2 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_aa19b80318b0b7d6b41ff992531f171f853eac9d }}; } -pub use _call_macro_with_each_type_aa19b80318b0b7d6b41ff992531f171f853eac9d20d41cb686f4e888a6eaa384 as call_macro_with_each_type; +pub use _call_macro_with_each_type_ebf5b81aab52989060a7a2847c44fee53adec878dc6963b863dc1470575c89e2 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index 4086893f4..ecb447818 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -3101,7 +3101,7 @@ Self::Offer => ().write_xdr(w)?, #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_37d873f1badd12f5fb6d13139d9eccc769ecb171a460cc2a047c71043916ec92 { +macro_rules! _call_macro_with_each_type_10628f231065b87fa0f02c49b563d2f0ef5dc4be25436fdacd487b9d6ca5715a { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3118,7 +3118,7 @@ macro_rules! _call_macro_with_each_type_37d873f1badd12f5fb6d13139d9eccc769ecb171 }}; } -pub use _call_macro_with_each_type_37d873f1badd12f5fb6d13139d9eccc769ecb171a460cc2a047c71043916ec92 as call_macro_with_each_type; +pub use _call_macro_with_each_type_10628f231065b87fa0f02c49b563d2f0ef5dc4be25436fdacd487b9d6ca5715a as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index df2e05ed4..e9057dbe0 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -2834,7 +2834,7 @@ self.third_option.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_8e5cc2f3c0250b3dfb8c1b526a989837796eeaec3325c182341c4d425642fd91 { +macro_rules! _call_macro_with_each_type_265be17b7cc3a2b3e82a1c941ba7edc1996a561d0c6c0116b00087c35fa94a90 { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2845,7 +2845,7 @@ macro_rules! _call_macro_with_each_type_8e5cc2f3c0250b3dfb8c1b526a989837796eeaec }}; } -pub use _call_macro_with_each_type_8e5cc2f3c0250b3dfb8c1b526a989837796eeaec3325c182341c4d425642fd91 as call_macro_with_each_type; +pub use _call_macro_with_each_type_265be17b7cc3a2b3e82a1c941ba7edc1996a561d0c6c0116b00087c35fa94a90 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index a241f93db..e59a9276c 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -2842,7 +2842,7 @@ self.max_string.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_b9bfa046b276eafc1c4da35a004085c34eaeef3e48a85250ceb2755bca3c3d24 { +macro_rules! _call_macro_with_each_type_1861ae43921a012efe0e2d02d3c1a1c1d170d28299209eeda078f658b096c1cf { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -2853,7 +2853,7 @@ macro_rules! _call_macro_with_each_type_b9bfa046b276eafc1c4da35a004085c34eaeef3e }}; } -pub use _call_macro_with_each_type_b9bfa046b276eafc1c4da35a004085c34eaeef3e48a85250ceb2755bca3c3d24 as call_macro_with_each_type; +pub use _call_macro_with_each_type_1861ae43921a012efe0e2d02d3c1a1c1d170d28299209eeda078f658b096c1cf as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index 3871f66e2..69a74b3b2 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -4478,7 +4478,7 @@ self.nested_union.write_xdr(w)?; #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_c106885159bca8210947544606f86998be0bb80a6cc6dd31e2372dacf74d2abd { +macro_rules! _call_macro_with_each_type_c6e2e3cb430678fd6861b5bc15e0e7c0659ed72f3cc50f4b316db382c9b5e7cc { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -4531,7 +4531,7 @@ macro_rules! _call_macro_with_each_type_c106885159bca8210947544606f86998be0bb80a }}; } -pub use _call_macro_with_each_type_c106885159bca8210947544606f86998be0bb80a6cc6dd31e2372dacf74d2abd as call_macro_with_each_type; +pub use _call_macro_with_each_type_c6e2e3cb430678fd6861b5bc15e0e7c0659ed72f3cc50f4b316db382c9b5e7cc as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index 3bf938489..f2444f507 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -3174,7 +3174,7 @@ impl WriteXdr for IntUnion2 { #[doc(hidden)] #[macro_export] -macro_rules! _call_macro_with_each_type_d2878762de1bf72819ba8a40aeaf853b317aed2c304b1cb2e50a19df3a8323e1 { +macro_rules! _call_macro_with_each_type_35506a40d62a2ac0f7dfce39b6fb2286d1aad5e84701d44c2b49ee5daca5320f { // The x-macro takes a single ident, the name of a macro to call ... ($macro_to_call_back:ident, $($context:tt),*) => {{ // ... and calls it back, once for each XDR type. @@ -3193,7 +3193,7 @@ macro_rules! _call_macro_with_each_type_d2878762de1bf72819ba8a40aeaf853b317aed2c }}; } -pub use _call_macro_with_each_type_d2878762de1bf72819ba8a40aeaf853b317aed2c304b1cb2e50a19df3a8323e1 as call_macro_with_each_type; +pub use _call_macro_with_each_type_35506a40d62a2ac0f7dfce39b6fb2286d1aad5e84701d44c2b49ee5daca5320f as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), From 10ff0396bf01cfb56c46b5eb20ce1614c5aa1301 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 15 May 2024 21:29:49 +1000 Subject: [PATCH 20/20] defer adding macro that isn't required by this pr --- lib/xdrgen/generators/rust.rb | 21 ------- .../block_comments.x/MyXDR.rs | 12 ---- .../generator_spec_rust/const.x/MyXDR.rs | 14 ----- .../generator_spec_rust/enum.x/MyXDR.rs | 16 ------ .../generator_spec_rust/nesting.x/MyXDR.rs | 20 ------- .../generator_spec_rust/optional.x/MyXDR.rs | 14 ----- .../generator_spec_rust/struct.x/MyXDR.rs | 14 ----- .../generator_spec_rust/test.x/MyXDR.rs | 56 ------------------- .../generator_spec_rust/union.x/MyXDR.rs | 22 -------- .../block_comments.x/MyXDR.rs | 12 ---- .../const.x/MyXDR.rs | 14 ----- .../enum.x/MyXDR.rs | 16 ------ .../nesting.x/MyXDR.rs | 20 ------- .../optional.x/MyXDR.rs | 14 ----- .../struct.x/MyXDR.rs | 14 ----- .../test.x/MyXDR.rs | 56 ------------------- .../union.x/MyXDR.rs | 22 -------- .../block_comments.x/MyXDR.rs | 12 ---- .../const.x/MyXDR.rs | 14 ----- .../enum.x/MyXDR.rs | 16 ------ .../nesting.x/MyXDR.rs | 20 ------- .../optional.x/MyXDR.rs | 14 ----- .../struct.x/MyXDR.rs | 14 ----- .../test.x/MyXDR.rs | 56 ------------------- .../union.x/MyXDR.rs | 22 -------- 25 files changed, 525 deletions(-) diff --git a/lib/xdrgen/generators/rust.rb b/lib/xdrgen/generators/rust.rb index 2a44cff75..13120d835 100644 --- a/lib/xdrgen/generators/rust.rb +++ b/lib/xdrgen/generators/rust.rb @@ -16,7 +16,6 @@ def generate render_top_matter(out) render_lib(out) render_definitions(out, @top) - render_type_macro(out, @types) render_enum_of_all_types(out, @types) out.break end @@ -95,26 +94,6 @@ def render_lib(out) out.break end - def render_type_macro(out, types) - out.puts <<-EOS.strip_heredoc - #[doc(hidden)] - #[macro_export] - macro_rules! _call_macro_with_each_type_#{@output.inputs_hash} { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - #{types.map do |t| - <<-EOS - $macro_to_call_back!(#{t}, $($context),*); - EOS - end.join("\n")} - - }}; - } - pub use _call_macro_with_each_type_#{@output.inputs_hash} as call_macro_with_each_type; - EOS - end - def render_enum_of_all_types(out, types) out.puts <<-EOS.strip_heredoc #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] diff --git a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs index 4444409ca..c7f9cf95b 100644 --- a/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/block_comments.x/MyXDR.rs @@ -2876,18 +2876,6 @@ impl WriteXdr for AccountFlags { } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_d7fc2f197127df606e7c3c22fa61d131623fb36d2be217c52672924969e49d0d { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(AccountFlags, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_d7fc2f197127df606e7c3c22fa61d131623fb36d2be217c52672924969e49d0d as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/const.x/MyXDR.rs b/spec/output/generator_spec_rust/const.x/MyXDR.rs index 6036d2f71..80670d3ce 100644 --- a/spec/output/generator_spec_rust/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/const.x/MyXDR.rs @@ -2802,20 +2802,6 @@ pub type TestArray = [i32; Foo]; /// pub type TestArray2 = VecM::; -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_a7dae5f3a6aa197f11de2dc3b36eda238bc02a177a6148b110c1eba0f6e157d5 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(TestArray, $($context),*); - - $macro_to_call_back!(TestArray2, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_a7dae5f3a6aa197f11de2dc3b36eda238bc02a177a6148b110c1eba0f6e157d5 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/enum.x/MyXDR.rs b/spec/output/generator_spec_rust/enum.x/MyXDR.rs index 31c6ce9df..276d6dca4 100644 --- a/spec/output/generator_spec_rust/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/enum.x/MyXDR.rs @@ -3178,22 +3178,6 @@ Self::Blue2 => "Blue2", } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_1affe08901838b4233170cdc473594569da207fcd2eec4afbaac41075ecd4114 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(MessageType, $($context),*); - - $macro_to_call_back!(Color, $($context),*); - - $macro_to_call_back!(Color2, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_1affe08901838b4233170cdc473594569da207fcd2eec4afbaac41075ecd4114 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs index 763cfebfe..e08690046 100644 --- a/spec/output/generator_spec_rust/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/nesting.x/MyXDR.rs @@ -3099,26 +3099,6 @@ Self::Offer => ().write_xdr(w)?, } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_8980212b367c7fd7f6df3534c44d6e78b7e176e22d223cc4c95be74483a52986 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(UnionKey, $($context),*); - - $macro_to_call_back!(Foo, $($context),*); - - $macro_to_call_back!(MyUnion, $($context),*); - - $macro_to_call_back!(MyUnionOne, $($context),*); - - $macro_to_call_back!(MyUnionTwo, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_8980212b367c7fd7f6df3534c44d6e78b7e176e22d223cc4c95be74483a52986 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/optional.x/MyXDR.rs b/spec/output/generator_spec_rust/optional.x/MyXDR.rs index 735afa121..0f29a0a45 100644 --- a/spec/output/generator_spec_rust/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/optional.x/MyXDR.rs @@ -2832,20 +2832,6 @@ self.third_option.write_xdr(w)?; } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_bed2d289d7888b3cb894d83ee4181ed26bdc961d47b1e8d798885ce6c17dbcb1 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(Arr, $($context),*); - - $macro_to_call_back!(HasOptions, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_bed2d289d7888b3cb894d83ee4181ed26bdc961d47b1e8d798885ce6c17dbcb1 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/struct.x/MyXDR.rs b/spec/output/generator_spec_rust/struct.x/MyXDR.rs index eaf3053cc..1e6a82b74 100644 --- a/spec/output/generator_spec_rust/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/struct.x/MyXDR.rs @@ -2840,20 +2840,6 @@ self.max_string.write_xdr(w)?; } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_f5399816ab213168cc346c594e13cf5d33e915736bc78e2994eb1b8a86609391 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(Int64, $($context),*); - - $macro_to_call_back!(MyStruct, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_f5399816ab213168cc346c594e13cf5d33e915736bc78e2994eb1b8a86609391 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/test.x/MyXDR.rs b/spec/output/generator_spec_rust/test.x/MyXDR.rs index f944eb467..4bfffad0c 100644 --- a/spec/output/generator_spec_rust/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/test.x/MyXDR.rs @@ -4476,62 +4476,6 @@ self.nested_union.write_xdr(w)?; } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_0aa79ed8ae8b11603ed635818100b818a4877235c22ef7e7c0ff38389a4f36e2 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(Uint512, $($context),*); - - $macro_to_call_back!(Uint513, $($context),*); - - $macro_to_call_back!(Uint514, $($context),*); - - $macro_to_call_back!(Str, $($context),*); - - $macro_to_call_back!(Str2, $($context),*); - - $macro_to_call_back!(Hash, $($context),*); - - $macro_to_call_back!(Hashes1, $($context),*); - - $macro_to_call_back!(Hashes2, $($context),*); - - $macro_to_call_back!(Hashes3, $($context),*); - - $macro_to_call_back!(OptHash1, $($context),*); - - $macro_to_call_back!(OptHash2, $($context),*); - - $macro_to_call_back!(Int1, $($context),*); - - $macro_to_call_back!(Int2, $($context),*); - - $macro_to_call_back!(Int3, $($context),*); - - $macro_to_call_back!(Int4, $($context),*); - - $macro_to_call_back!(MyStruct, $($context),*); - - $macro_to_call_back!(LotsOfMyStructs, $($context),*); - - $macro_to_call_back!(HasStuff, $($context),*); - - $macro_to_call_back!(Color, $($context),*); - - $macro_to_call_back!(Nester, $($context),*); - - $macro_to_call_back!(NesterNestedEnum, $($context),*); - - $macro_to_call_back!(NesterNestedStruct, $($context),*); - - $macro_to_call_back!(NesterNestedUnion, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_0aa79ed8ae8b11603ed635818100b818a4877235c22ef7e7c0ff38389a4f36e2 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust/union.x/MyXDR.rs b/spec/output/generator_spec_rust/union.x/MyXDR.rs index 50e50cbb8..eb96312c0 100644 --- a/spec/output/generator_spec_rust/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust/union.x/MyXDR.rs @@ -3172,28 +3172,6 @@ impl WriteXdr for IntUnion2 { } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_a9d35711d4349f79a937c021a1f34d9b6558af3b8fec8f44e84b08e37bc3bd23 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(SError, $($context),*); - - $macro_to_call_back!(Multi, $($context),*); - - $macro_to_call_back!(UnionKey, $($context),*); - - $macro_to_call_back!(MyUnion, $($context),*); - - $macro_to_call_back!(IntUnion, $($context),*); - - $macro_to_call_back!(IntUnion2, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_a9d35711d4349f79a937c021a1f34d9b6558af3b8fec8f44e84b08e37bc3bd23 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs index 8b0868eb5..c7f9cf95b 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/block_comments.x/MyXDR.rs @@ -2876,18 +2876,6 @@ impl WriteXdr for AccountFlags { } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_65651c234257097d41984f20914dfd44f91c1a5f2c0050feb44611a0aa539177 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(AccountFlags, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_65651c234257097d41984f20914dfd44f91c1a5f2c0050feb44611a0aa539177 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs index 8b0f15666..80670d3ce 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/const.x/MyXDR.rs @@ -2802,20 +2802,6 @@ pub type TestArray = [i32; Foo]; /// pub type TestArray2 = VecM::; -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_3987b1b0da55480e72d9b9d05876aab566f3bd4b52c950bf1ace1cbcea0648dd { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(TestArray, $($context),*); - - $macro_to_call_back!(TestArray2, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_3987b1b0da55480e72d9b9d05876aab566f3bd4b52c950bf1ace1cbcea0648dd as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs index 1165509fa..f85776cdd 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/enum.x/MyXDR.rs @@ -3177,22 +3177,6 @@ Self::Blue2 => "Blue2", } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_5fc3f78c5d821b38fa85791cc5d5b6f50be338cb8b6342606b4d0d4362c8089d { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(MessageType, $($context),*); - - $macro_to_call_back!(Color, $($context),*); - - $macro_to_call_back!(Color2, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_5fc3f78c5d821b38fa85791cc5d5b6f50be338cb8b6342606b4d0d4362c8089d as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs index 99a211359..a4e145120 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/nesting.x/MyXDR.rs @@ -3097,26 +3097,6 @@ Self::Offer => ().write_xdr(w)?, } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_06b17481d5959412d6c7ae97fb96d4db4d534057726369081b728de075be683c { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(UnionKey, $($context),*); - - $macro_to_call_back!(Foo, $($context),*); - - $macro_to_call_back!(MyUnion, $($context),*); - - $macro_to_call_back!(MyUnionOne, $($context),*); - - $macro_to_call_back!(MyUnionTwo, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_06b17481d5959412d6c7ae97fb96d4db4d534057726369081b728de075be683c as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs index 1f484b484..9e34e30c8 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/optional.x/MyXDR.rs @@ -2831,20 +2831,6 @@ self.third_option.write_xdr(w)?; } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_3170ead79299e6af1fa5ac44ee6992f7681cf7c80286dd1cbe2e6660db2ab0d9 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(Arr, $($context),*); - - $macro_to_call_back!(HasOptions, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_3170ead79299e6af1fa5ac44ee6992f7681cf7c80286dd1cbe2e6660db2ab0d9 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs index bcabcd020..b7db61fc8 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/struct.x/MyXDR.rs @@ -2839,20 +2839,6 @@ self.max_string.write_xdr(w)?; } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_49a18d13126431dabed30ae4a6c514a084df4a2c93a549318a517844eab20a40 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(Int64, $($context),*); - - $macro_to_call_back!(MyStruct, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_49a18d13126431dabed30ae4a6c514a084df4a2c93a549318a517844eab20a40 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs index 1f7211a9d..fdc5594db 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/test.x/MyXDR.rs @@ -4474,62 +4474,6 @@ self.nested_union.write_xdr(w)?; } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_c1547a0cbce873115f3f0aaad38902bdc99f3fe547440cafe94f2d702f7abc42 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(Uint512, $($context),*); - - $macro_to_call_back!(Uint513, $($context),*); - - $macro_to_call_back!(Uint514, $($context),*); - - $macro_to_call_back!(Str, $($context),*); - - $macro_to_call_back!(Str2, $($context),*); - - $macro_to_call_back!(Hash, $($context),*); - - $macro_to_call_back!(Hashes1, $($context),*); - - $macro_to_call_back!(Hashes2, $($context),*); - - $macro_to_call_back!(Hashes3, $($context),*); - - $macro_to_call_back!(OptHash1, $($context),*); - - $macro_to_call_back!(OptHash2, $($context),*); - - $macro_to_call_back!(Int1, $($context),*); - - $macro_to_call_back!(Int2, $($context),*); - - $macro_to_call_back!(Int3, $($context),*); - - $macro_to_call_back!(Int4, $($context),*); - - $macro_to_call_back!(MyStruct, $($context),*); - - $macro_to_call_back!(LotsOfMyStructs, $($context),*); - - $macro_to_call_back!(HasStuff, $($context),*); - - $macro_to_call_back!(Color, $($context),*); - - $macro_to_call_back!(Nester, $($context),*); - - $macro_to_call_back!(NesterNestedEnum, $($context),*); - - $macro_to_call_back!(NesterNestedStruct, $($context),*); - - $macro_to_call_back!(NesterNestedUnion, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_c1547a0cbce873115f3f0aaad38902bdc99f3fe547440cafe94f2d702f7abc42 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs index 80028a7e3..093cea099 100644 --- a/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_jsonschema_impls/union.x/MyXDR.rs @@ -3170,28 +3170,6 @@ impl WriteXdr for IntUnion2 { } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_043b3282ddd717aa5167744c1f532017c69c5d20015a63c1e79d004b6daebfb6 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(SError, $($context),*); - - $macro_to_call_back!(Multi, $($context),*); - - $macro_to_call_back!(UnionKey, $($context),*); - - $macro_to_call_back!(MyUnion, $($context),*); - - $macro_to_call_back!(IntUnion, $($context),*); - - $macro_to_call_back!(IntUnion2, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_043b3282ddd717aa5167744c1f532017c69c5d20015a63c1e79d004b6daebfb6 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs index 774f38738..c7f9cf95b 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/block_comments.x/MyXDR.rs @@ -2876,18 +2876,6 @@ impl WriteXdr for AccountFlags { } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_258a538659d11cae025394f94e4aeb512957d32603f08c10d142c0e57bb7db98 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(AccountFlags, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_258a538659d11cae025394f94e4aeb512957d32603f08c10d142c0e57bb7db98 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs index e457690d8..80670d3ce 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/const.x/MyXDR.rs @@ -2802,20 +2802,6 @@ pub type TestArray = [i32; Foo]; /// pub type TestArray2 = VecM::; -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_049e244dc4ffa0895d111b2d9da890f2808a4abc7645410179cf0554332daede { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(TestArray, $($context),*); - - $macro_to_call_back!(TestArray2, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_049e244dc4ffa0895d111b2d9da890f2808a4abc7645410179cf0554332daede as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs index 79f84af50..650ffec70 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/enum.x/MyXDR.rs @@ -3178,22 +3178,6 @@ Self::Blue2 => "Blue2", } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_ebf5b81aab52989060a7a2847c44fee53adec878dc6963b863dc1470575c89e2 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(MessageType, $($context),*); - - $macro_to_call_back!(Color, $($context),*); - - $macro_to_call_back!(Color2, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_ebf5b81aab52989060a7a2847c44fee53adec878dc6963b863dc1470575c89e2 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs index ecb447818..cf7a2d6a0 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/nesting.x/MyXDR.rs @@ -3099,26 +3099,6 @@ Self::Offer => ().write_xdr(w)?, } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_10628f231065b87fa0f02c49b563d2f0ef5dc4be25436fdacd487b9d6ca5715a { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(UnionKey, $($context),*); - - $macro_to_call_back!(Foo, $($context),*); - - $macro_to_call_back!(MyUnion, $($context),*); - - $macro_to_call_back!(MyUnionOne, $($context),*); - - $macro_to_call_back!(MyUnionTwo, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_10628f231065b87fa0f02c49b563d2f0ef5dc4be25436fdacd487b9d6ca5715a as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs index e9057dbe0..4def34ed7 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/optional.x/MyXDR.rs @@ -2832,20 +2832,6 @@ self.third_option.write_xdr(w)?; } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_265be17b7cc3a2b3e82a1c941ba7edc1996a561d0c6c0116b00087c35fa94a90 { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(Arr, $($context),*); - - $macro_to_call_back!(HasOptions, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_265be17b7cc3a2b3e82a1c941ba7edc1996a561d0c6c0116b00087c35fa94a90 as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs index e59a9276c..6278822dd 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/struct.x/MyXDR.rs @@ -2840,20 +2840,6 @@ self.max_string.write_xdr(w)?; } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_1861ae43921a012efe0e2d02d3c1a1c1d170d28299209eeda078f658b096c1cf { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(Int64, $($context),*); - - $macro_to_call_back!(MyStruct, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_1861ae43921a012efe0e2d02d3c1a1c1d170d28299209eeda078f658b096c1cf as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs index 69a74b3b2..1f8261303 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/test.x/MyXDR.rs @@ -4476,62 +4476,6 @@ self.nested_union.write_xdr(w)?; } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_c6e2e3cb430678fd6861b5bc15e0e7c0659ed72f3cc50f4b316db382c9b5e7cc { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(Uint512, $($context),*); - - $macro_to_call_back!(Uint513, $($context),*); - - $macro_to_call_back!(Uint514, $($context),*); - - $macro_to_call_back!(Str, $($context),*); - - $macro_to_call_back!(Str2, $($context),*); - - $macro_to_call_back!(Hash, $($context),*); - - $macro_to_call_back!(Hashes1, $($context),*); - - $macro_to_call_back!(Hashes2, $($context),*); - - $macro_to_call_back!(Hashes3, $($context),*); - - $macro_to_call_back!(OptHash1, $($context),*); - - $macro_to_call_back!(OptHash2, $($context),*); - - $macro_to_call_back!(Int1, $($context),*); - - $macro_to_call_back!(Int2, $($context),*); - - $macro_to_call_back!(Int3, $($context),*); - - $macro_to_call_back!(Int4, $($context),*); - - $macro_to_call_back!(MyStruct, $($context),*); - - $macro_to_call_back!(LotsOfMyStructs, $($context),*); - - $macro_to_call_back!(HasStuff, $($context),*); - - $macro_to_call_back!(Color, $($context),*); - - $macro_to_call_back!(Nester, $($context),*); - - $macro_to_call_back!(NesterNestedEnum, $($context),*); - - $macro_to_call_back!(NesterNestedStruct, $($context),*); - - $macro_to_call_back!(NesterNestedUnion, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_c6e2e3cb430678fd6861b5bc15e0e7c0659ed72f3cc50f4b316db382c9b5e7cc as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"), diff --git a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs index f2444f507..3f8552c43 100644 --- a/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs +++ b/spec/output/generator_spec_rust_custom_str_impls/union.x/MyXDR.rs @@ -3172,28 +3172,6 @@ impl WriteXdr for IntUnion2 { } } -#[doc(hidden)] -#[macro_export] -macro_rules! _call_macro_with_each_type_35506a40d62a2ac0f7dfce39b6fb2286d1aad5e84701d44c2b49ee5daca5320f { - // The x-macro takes a single ident, the name of a macro to call ... - ($macro_to_call_back:ident, $($context:tt),*) => {{ - // ... and calls it back, once for each XDR type. - $macro_to_call_back!(SError, $($context),*); - - $macro_to_call_back!(Multi, $($context),*); - - $macro_to_call_back!(UnionKey, $($context),*); - - $macro_to_call_back!(MyUnion, $($context),*); - - $macro_to_call_back!(IntUnion, $($context),*); - - $macro_to_call_back!(IntUnion2, $($context),*); - - - }}; -} -pub use _call_macro_with_each_type_35506a40d62a2ac0f7dfce39b6fb2286d1aad5e84701d44c2b49ee5daca5320f as call_macro_with_each_type; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr( all(feature = "serde", feature = "alloc"),