From 9179c9b372d76cf6c8526c19f9a4d0b2b6aa1a31 Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Tue, 9 Apr 2024 09:12:16 +0530 Subject: [PATCH 1/5] Implement JsonSchema for ZeroVec --- Cargo.lock | 42 ++++++++++++++++++++++++++++++++ utils/zerovec/Cargo.toml | 1 + utils/zerovec/src/lib.rs | 19 +++++++++++++++ utils/zerovec/src/zerovec/mod.rs | 40 ++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index e7a431eaccb..4f4607a9a51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -814,6 +814,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + [[package]] name = "ecma402_traits" version = "4.0.0" @@ -2641,6 +2647,30 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -2725,6 +2755,17 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "serde_json" version = "1.0.107" @@ -3627,6 +3668,7 @@ dependencies = [ "rand", "rand_distr", "rand_pcg", + "schemars", "serde", "serde_json", "twox-hash", diff --git a/utils/zerovec/Cargo.toml b/utils/zerovec/Cargo.toml index b9e7a76569c..a9218cacc36 100644 --- a/utils/zerovec/Cargo.toml +++ b/utils/zerovec/Cargo.toml @@ -37,6 +37,7 @@ serde = { version = "1.0", default-features = false, features = ["alloc"], optio # and all 0.7 versions, but not further. yoke = { version = ">=0.6.0, <0.8.0", path = "../yoke", optional = true } twox-hash = { version = "1.6", default-features = false, optional = true } +schemars = "0.8.16" [dev-dependencies] bincode = "1.3" diff --git a/utils/zerovec/src/lib.rs b/utils/zerovec/src/lib.rs index 8bb5b17e030..e3af069458e 100644 --- a/utils/zerovec/src/lib.rs +++ b/utils/zerovec/src/lib.rs @@ -523,6 +523,25 @@ pub use zerovec_derive::make_varule; mod tests { use super::*; use core::mem::size_of; + use serde::{Serialize, Deserialize}; + use schemars::{gen::SchemaGenerator, JsonSchema}; + + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + #[derive(JsonSchema)] + pub struct DataStruct<'data> { + #[cfg_attr(feature = "serde", serde(borrow))] + nums: ZeroVec<'data, u32>, + + #[cfg_attr(feature = "serde", serde(borrow))] + chars: ZeroVec<'data, char>, + } + + #[test] + fn check_schema(){ + let gen = SchemaGenerator::default(); + let schema = gen.into_root_schema_for::(); + let schema_json = serde_json::to_string_pretty(&schema).expect("Failed to serialize schema"); + } /// Checks that the size of the type is one of the given sizes. /// The size might differ across Rust versions or channels. diff --git a/utils/zerovec/src/zerovec/mod.rs b/utils/zerovec/src/zerovec/mod.rs index 50cbb3dd527..0fe4fae7630 100644 --- a/utils/zerovec/src/zerovec/mod.rs +++ b/utils/zerovec/src/zerovec/mod.rs @@ -10,10 +10,15 @@ mod serde; mod slice; +use schemars::gen::SchemaGenerator; +use schemars::schema::{ArrayValidation, InstanceType, Schema}; pub use slice::ZeroSlice; use crate::ule::*; use alloc::borrow::Cow; +use alloc::boxed::Box; +use alloc::string::String; +use core::fmt::Write; use alloc::vec::Vec; use core::cmp::{Ord, Ordering, PartialOrd}; use core::fmt; @@ -23,6 +28,7 @@ use core::mem; use core::num::NonZeroUsize; use core::ops::Deref; use core::ptr::{self, NonNull}; +use schemars::{JsonSchema, schema::SchemaObject}; /// A zero-copy, byte-aligned vector for fixed-width types. /// @@ -114,6 +120,38 @@ impl<'a, T: AsULE> Deref for ZeroVec<'a, T> { } } +impl<'a, T> JsonSchema for ZeroVec<'a, T> +where + T: AsULE + JsonSchema, +{ + + fn schema_name() -> String { + let mut name = String::from("ZeroVec<"); + let type_name = T::schema_name(); + write!(name, "{}", type_name).expect("Failed to write to string"); + name.push('>'); + + name + } + + fn schema_id() -> Cow<'static, str> { + Cow::Borrowed("zerovec::ZeroVec") + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + let element_schema = gen.subschema_for::(); + SchemaObject { + instance_type: Some(InstanceType::Array.into()), + array: Some(Box::new(ArrayValidation { + items: Some(element_schema.into()), + ..Default::default() + })), + ..Default::default() + } + .into() + } +} + // Represents an unsafe potentially-owned vector/slice type, without a lifetime // working around dropck limitations. // @@ -229,6 +267,8 @@ where } } + + impl PartialEq<[T; N]> for ZeroVec<'_, T> where T: AsULE + PartialEq + ?Sized, From 4e06ff3e98123c3b74a70a77828afa5e784b775a Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Wed, 10 Apr 2024 16:15:05 +0530 Subject: [PATCH 2/5] Improved schema_id and tests --- utils/zerovec/src/lib.rs | 7 +++++++ utils/zerovec/src/zerovec/mod.rs | 11 +++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/utils/zerovec/src/lib.rs b/utils/zerovec/src/lib.rs index e3af069458e..17fa27e63e9 100644 --- a/utils/zerovec/src/lib.rs +++ b/utils/zerovec/src/lib.rs @@ -525,6 +525,7 @@ mod tests { use core::mem::size_of; use serde::{Serialize, Deserialize}; use schemars::{gen::SchemaGenerator, JsonSchema}; + use serde_json::Value; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(JsonSchema)] @@ -541,6 +542,12 @@ mod tests { let gen = SchemaGenerator::default(); let schema = gen.into_root_schema_for::(); let schema_json = serde_json::to_string_pretty(&schema).expect("Failed to serialize schema"); + let parsed_schema: Value = serde_json::from_str(&schema_json).expect("Failed to parse schema JSON"); + + // Check for the existence of "ZeroVec" and "ZeroVec" in `definitions`` + let definitions = parsed_schema.get("definitions").expect("No definitions found in schema"); + assert!(definitions.get("ZeroVec").is_some(), "Definition for ZeroVec not found"); + assert!(definitions.get("ZeroVec").is_some(), "Definition for ZeroVec not found"); } /// Checks that the size of the type is one of the given sizes. diff --git a/utils/zerovec/src/zerovec/mod.rs b/utils/zerovec/src/zerovec/mod.rs index 0fe4fae7630..7f0b99e892f 100644 --- a/utils/zerovec/src/zerovec/mod.rs +++ b/utils/zerovec/src/zerovec/mod.rs @@ -18,8 +18,8 @@ use crate::ule::*; use alloc::borrow::Cow; use alloc::boxed::Box; use alloc::string::String; -use core::fmt::Write; use alloc::vec::Vec; +use alloc::format; use core::cmp::{Ord, Ordering, PartialOrd}; use core::fmt; use core::iter::FromIterator; @@ -126,16 +126,11 @@ where { fn schema_name() -> String { - let mut name = String::from("ZeroVec<"); - let type_name = T::schema_name(); - write!(name, "{}", type_name).expect("Failed to write to string"); - name.push('>'); - - name + format!("ZeroVec<{}>", T::schema_name()) } fn schema_id() -> Cow<'static, str> { - Cow::Borrowed("zerovec::ZeroVec") + Cow::Owned(format!("zerovec::ZeroVec<{}>", T::schema_id())) } fn json_schema(gen: &mut SchemaGenerator) -> Schema { From 6472c50c2eae794c8285fa55e8a212fae072b2fc Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Wed, 10 Apr 2024 16:52:51 +0530 Subject: [PATCH 3/5] Implement JsonSchema for VarZeroVec --- utils/zerovec/src/lib.rs | 6 ++++- utils/zerovec/src/varzerovec/vec.rs | 34 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/utils/zerovec/src/lib.rs b/utils/zerovec/src/lib.rs index 17fa27e63e9..c9e01d51838 100644 --- a/utils/zerovec/src/lib.rs +++ b/utils/zerovec/src/lib.rs @@ -535,6 +535,9 @@ mod tests { #[cfg_attr(feature = "serde", serde(borrow))] chars: ZeroVec<'data, char>, + + #[cfg_attr(feature = "serde", serde(borrow))] + strs: VarZeroVec<'data, str>, } #[test] @@ -544,10 +547,11 @@ mod tests { let schema_json = serde_json::to_string_pretty(&schema).expect("Failed to serialize schema"); let parsed_schema: Value = serde_json::from_str(&schema_json).expect("Failed to parse schema JSON"); - // Check for the existence of "ZeroVec" and "ZeroVec" in `definitions`` + // Check for the existence of "ZeroVec" and "ZeroVec" in `definitions` let definitions = parsed_schema.get("definitions").expect("No definitions found in schema"); assert!(definitions.get("ZeroVec").is_some(), "Definition for ZeroVec not found"); assert!(definitions.get("ZeroVec").is_some(), "Definition for ZeroVec not found"); + assert!(definitions.get("VarZeroVec").is_some(), "Definition for VarZeroVec not found"); } /// Checks that the size of the type is one of the given sizes. diff --git a/utils/zerovec/src/varzerovec/vec.rs b/utils/zerovec/src/varzerovec/vec.rs index 0a1e6bfb92b..b56d9e22a7d 100644 --- a/utils/zerovec/src/varzerovec/vec.rs +++ b/utils/zerovec/src/varzerovec/vec.rs @@ -4,7 +4,14 @@ use crate::ule::*; +use alloc::borrow::Cow; +use alloc::boxed::Box; +use alloc::format; +use alloc::string::String; use alloc::vec::Vec; +use schemars::gen::SchemaGenerator; +use schemars::schema::{ArrayValidation, InstanceType, Schema, SchemaObject}; +use schemars::JsonSchema; use core::cmp::{Ord, Ordering, PartialOrd}; use core::fmt; use core::ops::Deref; @@ -232,6 +239,33 @@ impl Deref for VarZeroVec<'_, T, F> { } } +impl<'a, T, F> JsonSchema for VarZeroVec<'a, T, F> +where + T: VarULE + ?Sized + JsonSchema, + F: VarZeroVecFormat, +{ + fn schema_name() -> String { + format!("VarZeroVec<{}>", T::schema_name()) + } + + fn schema_id() -> Cow<'static, str> { + Cow::Owned(format!("zerovec::VarZeroVec<{}>", T::schema_id())) + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + let items_schema = gen.subschema_for::(); + + SchemaObject { + instance_type: Some(InstanceType::Array.into()), + array: Some(Box::new(ArrayValidation { + items: Some(items_schema.into()), + ..Default::default() + })), + ..Default::default() + }.into() + } +} + impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> { /// Creates a new, empty `VarZeroVec`. /// From dc973699e000e477060a82f43aa9864f316eb1c4 Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Wed, 10 Apr 2024 18:01:34 +0530 Subject: [PATCH 4/5] Implement for ZeroSlice & Errors --- utils/zerovec/src/error.rs | 28 ++++++++++++++++++++++ utils/zerovec/src/lib.rs | 33 ++++++++++++++++++------- utils/zerovec/src/varzerovec/vec.rs | 13 +++++----- utils/zerovec/src/zerovec/mod.rs | 9 +++---- utils/zerovec/src/zerovec/slice.rs | 37 +++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 20 deletions(-) diff --git a/utils/zerovec/src/error.rs b/utils/zerovec/src/error.rs index 85de3ecc8dc..60d21769d52 100644 --- a/utils/zerovec/src/error.rs +++ b/utils/zerovec/src/error.rs @@ -5,6 +5,16 @@ use core::any; use core::fmt; +use crate::__zerovec_internal_reexport::boxed::Box; +use alloc::format; +use alloc::string::String; +use schemars::gen::SchemaGenerator; + +use schemars::schema::InstanceType; +use schemars::schema::Schema; +use schemars::schema::SchemaObject; +use schemars::JsonSchema; + /// A generic error type to be used for decoding slices of ULE types #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[non_exhaustive] @@ -33,6 +43,24 @@ impl fmt::Display for ZeroVecError { } } } +impl JsonSchema for ZeroVecError { + fn schema_name() -> String { + format!("ZeroVecError") + } + + fn json_schema(_gen: &mut SchemaGenerator) -> Schema { + Schema::Object(SchemaObject { + instance_type: Some(InstanceType::String.into()), + metadata: Some(Box::new(schemars::schema::Metadata { + description: Some( + "Represents variants: InvalidLength, ParseError, VarZeroVecFormatError.".into(), + ), + ..Default::default() + })), + ..Default::default() + }) + } +} impl ZeroVecError { /// Construct a parse error for the given type diff --git a/utils/zerovec/src/lib.rs b/utils/zerovec/src/lib.rs index c9e01d51838..0991bd995ac 100644 --- a/utils/zerovec/src/lib.rs +++ b/utils/zerovec/src/lib.rs @@ -523,8 +523,8 @@ pub use zerovec_derive::make_varule; mod tests { use super::*; use core::mem::size_of; - use serde::{Serialize, Deserialize}; use schemars::{gen::SchemaGenerator, JsonSchema}; + use serde::{Deserialize, Serialize}; use serde_json::Value; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -538,20 +538,37 @@ mod tests { #[cfg_attr(feature = "serde", serde(borrow))] strs: VarZeroVec<'data, str>, + + #[cfg_attr(feature = "serde", serde(borrow))] + nested_numbers: VarZeroVec<'data, ZeroSlice>, } #[test] - fn check_schema(){ + fn check_schema() { let gen = SchemaGenerator::default(); let schema = gen.into_root_schema_for::(); - let schema_json = serde_json::to_string_pretty(&schema).expect("Failed to serialize schema"); - let parsed_schema: Value = serde_json::from_str(&schema_json).expect("Failed to parse schema JSON"); + let schema_json = + serde_json::to_string_pretty(&schema).expect("Failed to serialize schema"); + println!("{}", schema_json); + let parsed_schema: Value = + serde_json::from_str(&schema_json).expect("Failed to parse schema JSON"); // Check for the existence of "ZeroVec" and "ZeroVec" in `definitions` - let definitions = parsed_schema.get("definitions").expect("No definitions found in schema"); - assert!(definitions.get("ZeroVec").is_some(), "Definition for ZeroVec not found"); - assert!(definitions.get("ZeroVec").is_some(), "Definition for ZeroVec not found"); - assert!(definitions.get("VarZeroVec").is_some(), "Definition for VarZeroVec not found"); + let definitions = parsed_schema + .get("definitions") + .expect("No definitions found in schema"); + assert!( + definitions.get("ZeroVec").is_some(), + "Definition for ZeroVec not found" + ); + assert!( + definitions.get("ZeroVec").is_some(), + "Definition for ZeroVec not found" + ); + assert!( + definitions.get("VarZeroVec").is_some(), + "Definition for VarZeroVec not found" + ); } /// Checks that the size of the type is one of the given sizes. diff --git a/utils/zerovec/src/varzerovec/vec.rs b/utils/zerovec/src/varzerovec/vec.rs index b56d9e22a7d..4bd564873ca 100644 --- a/utils/zerovec/src/varzerovec/vec.rs +++ b/utils/zerovec/src/varzerovec/vec.rs @@ -9,12 +9,12 @@ use alloc::boxed::Box; use alloc::format; use alloc::string::String; use alloc::vec::Vec; -use schemars::gen::SchemaGenerator; -use schemars::schema::{ArrayValidation, InstanceType, Schema, SchemaObject}; -use schemars::JsonSchema; use core::cmp::{Ord, Ordering, PartialOrd}; use core::fmt; use core::ops::Deref; +use schemars::gen::SchemaGenerator; +use schemars::schema::{ArrayValidation, InstanceType, Schema, SchemaObject}; +use schemars::JsonSchema; use super::*; @@ -239,7 +239,7 @@ impl Deref for VarZeroVec<'_, T, F> { } } -impl<'a, T, F> JsonSchema for VarZeroVec<'a, T, F> +impl<'a, T, F> JsonSchema for VarZeroVec<'a, T, F> where T: VarULE + ?Sized + JsonSchema, F: VarZeroVecFormat, @@ -256,13 +256,14 @@ where let items_schema = gen.subschema_for::(); SchemaObject { - instance_type: Some(InstanceType::Array.into()), + instance_type: Some(InstanceType::Array.into()), array: Some(Box::new(ArrayValidation { items: Some(items_schema.into()), ..Default::default() })), ..Default::default() - }.into() + } + .into() } } diff --git a/utils/zerovec/src/zerovec/mod.rs b/utils/zerovec/src/zerovec/mod.rs index 7f0b99e892f..2a1c13b886c 100644 --- a/utils/zerovec/src/zerovec/mod.rs +++ b/utils/zerovec/src/zerovec/mod.rs @@ -17,9 +17,9 @@ pub use slice::ZeroSlice; use crate::ule::*; use alloc::borrow::Cow; use alloc::boxed::Box; +use alloc::format; use alloc::string::String; use alloc::vec::Vec; -use alloc::format; use core::cmp::{Ord, Ordering, PartialOrd}; use core::fmt; use core::iter::FromIterator; @@ -28,7 +28,7 @@ use core::mem; use core::num::NonZeroUsize; use core::ops::Deref; use core::ptr::{self, NonNull}; -use schemars::{JsonSchema, schema::SchemaObject}; +use schemars::{schema::SchemaObject, JsonSchema}; /// A zero-copy, byte-aligned vector for fixed-width types. /// @@ -120,11 +120,10 @@ impl<'a, T: AsULE> Deref for ZeroVec<'a, T> { } } -impl<'a, T> JsonSchema for ZeroVec<'a, T> +impl<'a, T> JsonSchema for ZeroVec<'a, T> where T: AsULE + JsonSchema, { - fn schema_name() -> String { format!("ZeroVec<{}>", T::schema_name()) } @@ -262,8 +261,6 @@ where } } - - impl PartialEq<[T; N]> for ZeroVec<'_, T> where T: AsULE + PartialEq + ?Sized, diff --git a/utils/zerovec/src/zerovec/slice.rs b/utils/zerovec/src/zerovec/slice.rs index 12d88deff8e..6d4d480db66 100644 --- a/utils/zerovec/src/zerovec/slice.rs +++ b/utils/zerovec/src/zerovec/slice.rs @@ -3,6 +3,8 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use super::*; +use crate::alloc::string::ToString; +use ::serde::Serialize; use alloc::boxed::Box; use core::cmp::Ordering; use core::ops::Range; @@ -543,6 +545,41 @@ impl Ord for ZeroSlice { } } +impl JsonSchema for ZeroSlice +where + T: AsULE + JsonSchema + Serialize, // Ensure T is serializable for accurate schema representation +{ + fn schema_name() -> String { + format!("ZeroSlice<{}>", T::schema_name()) + } + + fn schema_id() -> Cow<'static, str> { + Cow::Owned(format!("zerovec::ZeroSlice<{}>", T::schema_id())) + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + // Instead of generating a subschema for T, we generate a schema representing the byte array + let byte_schema = gen.subschema_for::>(); + + SchemaObject { + instance_type: Some(InstanceType::Object.into()), + object: Some(Box::new({ + let mut object_validation = schemars::schema::ObjectValidation::default(); + object_validation + .properties + .insert("data".to_string(), byte_schema); + object_validation + .properties + .insert("error".to_string(), gen.subschema_for::()); + object_validation.required.insert("data".to_string()); + object_validation + })), + ..Default::default() + } + .into() + } +} + impl AsRef> for Vec { fn as_ref(&self) -> &ZeroSlice { ZeroSlice::::from_ule_slice(self) From 395401f855fd771a4fc7db8e3ce4547876416d15 Mon Sep 17 00:00:00 2001 From: ashu26jha Date: Wed, 10 Apr 2024 21:22:38 +0530 Subject: [PATCH 5/5] error enums for schemars --- utils/zerovec/Cargo.toml | 2 +- utils/zerovec/src/error.rs | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/utils/zerovec/Cargo.toml b/utils/zerovec/Cargo.toml index a9218cacc36..65b9fe3a791 100644 --- a/utils/zerovec/Cargo.toml +++ b/utils/zerovec/Cargo.toml @@ -24,6 +24,7 @@ all-features = true [dependencies] zerofrom = { workspace = true } +serde_json = "1.0" zerovec-derive = { workspace = true, optional = true} @@ -49,7 +50,6 @@ rand = "0.8" rand_distr = "0.4" rand_pcg = "0.3" serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" yoke = { path = "../../utils/yoke", features = ["derive"] } zerofrom = { path = "../../utils/zerofrom", features = ["derive"] } diff --git a/utils/zerovec/src/error.rs b/utils/zerovec/src/error.rs index 60d21769d52..7ff9dfcab75 100644 --- a/utils/zerovec/src/error.rs +++ b/utils/zerovec/src/error.rs @@ -6,15 +6,18 @@ use core::any; use core::fmt; use crate::__zerovec_internal_reexport::boxed::Box; +use alloc::borrow::ToOwned; use alloc::format; use alloc::string::String; +use alloc::vec; use schemars::gen::SchemaGenerator; - use schemars::schema::InstanceType; use schemars::schema::Schema; use schemars::schema::SchemaObject; use schemars::JsonSchema; +use serde_json::Value; + /// A generic error type to be used for decoding slices of ULE types #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[non_exhaustive] @@ -51,10 +54,13 @@ impl JsonSchema for ZeroVecError { fn json_schema(_gen: &mut SchemaGenerator) -> Schema { Schema::Object(SchemaObject { instance_type: Some(InstanceType::String.into()), + enum_values: Some(vec![ + Value::String("InvalidLength".to_owned()), + Value::String("ParseError".to_owned()), + Value::String("VarZeroVecFormatError".to_owned()), + ]), metadata: Some(Box::new(schemars::schema::Metadata { - description: Some( - "Represents variants: InvalidLength, ParseError, VarZeroVecFormatError.".into(), - ), + description: Some("ZeroVecError is an enum representing errors that can occur during the decoding of slices of ULE".into()), ..Default::default() })), ..Default::default()