From 844e092a626f22fa71d6c78305be7c11f9ba002b Mon Sep 17 00:00:00 2001 From: dzmitry-lahoda Date: Tue, 28 Nov 2023 12:08:32 +0000 Subject: [PATCH] fixes of std and improvement of schema --- primitive-types/Cargo.toml | 2 + primitive-types/src/json_schema.rs | 75 ++++++++++++++++++++++++++++++ primitive-types/src/lib.rs | 35 +------------- 3 files changed, 79 insertions(+), 33 deletions(-) create mode 100644 primitive-types/src/json_schema.rs diff --git a/primitive-types/Cargo.toml b/primitive-types/Cargo.toml index 126b17dc..1c861d36 100644 --- a/primitive-types/Cargo.toml +++ b/primitive-types/Cargo.toml @@ -20,6 +20,8 @@ schemars = { version = ">=0.8.12", default-features = true, optional = true } [dev-dependencies] num-traits = "0.2" +serde_json = { version = "1.0", default-features = false } +jsonschema = { version = "0.17", default-features = false } [features] default = ["std"] diff --git a/primitive-types/src/json_schema.rs b/primitive-types/src/json_schema.rs new file mode 100644 index 00000000..948bf86c --- /dev/null +++ b/primitive-types/src/json_schema.rs @@ -0,0 +1,75 @@ +use super::*; +#[cfg(not(feature = "std"))] +use alloc::{ + borrow::ToOwned, + string::{String, ToString}, +}; + +use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema}; + +impl JsonSchema for H160 { + fn schema_name() -> String { + "HexEncoded20Bytes".to_owned() + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + let mut schema = gen.subschema_for::().into_object(); + schema.metadata().description = Some("Hex encoded 20 bytes".to_string()); + schema.string().pattern = Some("^0(x|X)[a-fA-F0-9]{40}$".to_string()); + schema.into() + } +} + +impl JsonSchema for U256 { + fn schema_name() -> String { + "U256String".to_string() + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + let mut schema = gen.subschema_for::().into_object(); + schema.metadata().description = Some("256-bit Unsigned Integer".to_string()); + schema.string().pattern = Some("^(0|[1-9][0-9]{0,77})$".to_string()); + schema.into() + } +} + +#[cfg(test)] +#[cfg(any(feature = "serde", feature = "serde_no_std"))] +mod tests { + use crate::{H160, U256}; + #[cfg(not(feature = "std"))] + use alloc::string::String; + use jsonschema::Draft; + use schemars::JsonSchema; + + #[test] + fn hex_encoded_20_bytes() { + let schema = H160::json_schema(&mut schemars::gen::SchemaGenerator::default()); + let schema_json = serde_json::to_value(&schema).unwrap(); + let schema = jsonschema::JSONSchema::options() + .with_draft(Draft::Draft7) + .compile(&schema_json) + .unwrap(); + let value = serde_json::to_value("0x55086adeca661185c437d92b9818e6eda6d0d047").unwrap(); + assert!(schema.validate(&value).is_ok()); + let value = serde_json::to_value("0X0E9C8DA9FD4BDD3281879D9E328D8D74D02558CC").unwrap(); + assert!(schema.validate(&value).is_ok()); + + let value = serde_json::to_value("42").unwrap(); + assert!(schema.validate(&value).is_err()); + } + + #[test] + fn u256() { + let schema = U256::json_schema(&mut schemars::gen::SchemaGenerator::default()); + let schema_json = serde_json::to_value(&schema).unwrap(); + let schema = jsonschema::JSONSchema::options() + .with_draft(Draft::Draft7) + .compile(&schema_json) + .unwrap(); + let addr = serde_json::to_value("42").unwrap(); + assert!(schema.validate(&addr).is_ok()); + let addr = serde_json::to_value(['1'; 79].into_iter().collect::()).unwrap(); + assert!(schema.validate(&addr).is_err()); + } +} diff --git a/primitive-types/src/lib.rs b/primitive-types/src/lib.rs index c502e9e9..ec3eda4f 100644 --- a/primitive-types/src/lib.rs +++ b/primitive-types/src/lib.rs @@ -19,6 +19,8 @@ extern crate alloc; #[cfg(feature = "fp-conversion")] mod fp_conversion; +#[cfg(feature = "json-schema")] +mod json_schema; use core::convert::TryFrom; use fixed_hash::{construct_fixed_hash, impl_fixed_hash_conversions}; @@ -108,39 +110,6 @@ mod serde { impl_fixed_hash_serde!(H768, 96); } - -// TODO: make macro -#[cfg(feature = "json-schema")] -mod json_schema { - use super::*; - - impl schemars::JsonSchema for H160 { - fn schema_name() -> alloc::string::String { - use alloc::string::ToString; - "0xPrefixedHexString".to_string() - } - - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - use alloc::string::String; - // TODO: validate format - String::json_schema(gen) - } - } - - impl schemars::JsonSchema for U256 { - fn schema_name() -> alloc::string::String { - use alloc::string::ToString; - "U256String".to_string() - } - - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - use alloc::string::String; - // TODO: validate format - String::json_schema(gen) - } - } -} - #[cfg(feature = "impl-codec")] mod codec { use super::*;