Skip to content

Commit e05dae7

Browse files
committed
Allow for schema derivation for the Hex type
1 parent 16ea265 commit e05dae7

File tree

9 files changed

+211
-2
lines changed

9 files changed

+211
-2
lines changed

serde_with/src/schemars_0_8.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,64 @@ impl<T> JsonSchemaAs<T> for DisplayFromStr {
404404
forward_schema!(String);
405405
}
406406

407+
#[cfg(feature = "hex")]
408+
impl<T> JsonSchemaAs<T> for hex::Hex<formats::Lowercase> {
409+
fn schema_name() -> String {
410+
"Hex<Lowercase>".into()
411+
}
412+
413+
fn schema_id() -> Cow<'static, str> {
414+
"serde_with::hex::Hex<Lowercase>".into()
415+
}
416+
417+
fn json_schema(_: &mut SchemaGenerator) -> Schema {
418+
use ::schemars_0_8::schema::StringValidation;
419+
420+
SchemaObject {
421+
instance_type: Some(InstanceType::String.into()),
422+
string: Some(Box::new(StringValidation {
423+
pattern: Some(r"^(?:[0-9a-f]{2})*$".to_owned()),
424+
..Default::default()
425+
})),
426+
..Default::default()
427+
}
428+
.into()
429+
}
430+
431+
fn is_referenceable() -> bool {
432+
false
433+
}
434+
}
435+
436+
#[cfg(feature = "hex")]
437+
impl<T> JsonSchemaAs<T> for hex::Hex<formats::Uppercase> {
438+
fn schema_name() -> String {
439+
"Hex<Uppercase>".into()
440+
}
441+
442+
fn schema_id() -> Cow<'static, str> {
443+
"serde_with::hex::Hex<Uppercase>".into()
444+
}
445+
446+
fn json_schema(_: &mut SchemaGenerator) -> Schema {
447+
use ::schemars_0_8::schema::StringValidation;
448+
449+
SchemaObject {
450+
instance_type: Some(InstanceType::String.into()),
451+
string: Some(Box::new(StringValidation {
452+
pattern: Some(r"^(?:[0-9A-F]{2})*$".to_owned()),
453+
..Default::default()
454+
})),
455+
..Default::default()
456+
}
457+
.into()
458+
}
459+
460+
fn is_referenceable() -> bool {
461+
false
462+
}
463+
}
464+
407465
impl JsonSchemaAs<bool> for BoolFromInt<Strict> {
408466
fn schema_name() -> String {
409467
"BoolFromInt<Strict>".into()

serde_with/src/schemars_0_9.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,50 @@ impl<T> JsonSchemaAs<T> for DisplayFromStr {
406406
forward_schema!(String);
407407
}
408408

409+
#[cfg(feature = "hex")]
410+
impl<T> JsonSchemaAs<T> for hex::Hex<formats::Lowercase> {
411+
fn schema_name() -> Cow<'static, str> {
412+
"Hex<Lowercase>".into()
413+
}
414+
415+
fn schema_id() -> Cow<'static, str> {
416+
"serde_with::hex::Hex<Lowercase>".into()
417+
}
418+
419+
fn json_schema(_: &mut SchemaGenerator) -> Schema {
420+
json_schema!({
421+
"type": "string",
422+
"pattern": r"^(?:[0-9a-f]{2})*$",
423+
})
424+
}
425+
426+
fn inline_schema() -> bool {
427+
true
428+
}
429+
}
430+
431+
#[cfg(feature = "hex")]
432+
impl<T> JsonSchemaAs<T> for hex::Hex<formats::Uppercase> {
433+
fn schema_name() -> Cow<'static, str> {
434+
"Hex<Uppercase>".into()
435+
}
436+
437+
fn schema_id() -> Cow<'static, str> {
438+
"serde_with::hex::Hex<Uppercase>".into()
439+
}
440+
441+
fn json_schema(_: &mut SchemaGenerator) -> Schema {
442+
json_schema!({
443+
"type": "string",
444+
"pattern": r"^(?:[0-9A-F]{2})*$",
445+
})
446+
}
447+
448+
fn inline_schema() -> bool {
449+
true
450+
}
451+
}
452+
409453
impl JsonSchemaAs<bool> for BoolFromInt<Strict> {
410454
fn schema_name() -> Cow<'static, str> {
411455
"BoolFromInt<Strict>".into()

serde_with/src/schemars_1.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,50 @@ impl<T> JsonSchemaAs<T> for DisplayFromStr {
408408
forward_schema!(String);
409409
}
410410

411+
#[cfg(feature = "hex")]
412+
impl<T> JsonSchemaAs<T> for hex::Hex<formats::Lowercase> {
413+
fn schema_name() -> Cow<'static, str> {
414+
"Hex<Lowercase>".into()
415+
}
416+
417+
fn schema_id() -> Cow<'static, str> {
418+
"serde_with::hex::Hex<Lowercase>".into()
419+
}
420+
421+
fn json_schema(_: &mut SchemaGenerator) -> Schema {
422+
json_schema!({
423+
"type": "string",
424+
"pattern": r"^(?:[0-9a-f]{2})*$",
425+
})
426+
}
427+
428+
fn inline_schema() -> bool {
429+
true
430+
}
431+
}
432+
433+
#[cfg(feature = "hex")]
434+
impl<T> JsonSchemaAs<T> for hex::Hex<formats::Uppercase> {
435+
fn schema_name() -> Cow<'static, str> {
436+
"Hex<Uppercase>".into()
437+
}
438+
439+
fn schema_id() -> Cow<'static, str> {
440+
"serde_with::hex::Hex<Uppercase>".into()
441+
}
442+
443+
fn json_schema(_: &mut SchemaGenerator) -> Schema {
444+
json_schema!({
445+
"type": "string",
446+
"pattern": r"^(?:[0-9A-F]{2})*$",
447+
})
448+
}
449+
450+
fn inline_schema() -> bool {
451+
true
452+
}
453+
}
454+
411455
impl JsonSchemaAs<bool> for BoolFromInt<Strict> {
412456
fn schema_name() -> Cow<'static, str> {
413457
"BoolFromInt<Strict>".into()

serde_with/tests/schemars_0_8/main.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use expect_test::expect_file;
55
use schemars::JsonSchema;
66
use serde::Serialize;
77
use serde_json::json;
8+
use serde_with::hex::*;
89
use serde_with::*;
910
use std::collections::BTreeSet;
1011

@@ -90,6 +91,14 @@ fn schemars_basic() {
9091
/// Same thing, but with a Vec this time.
9192
#[serde_as(as = "Vec<_>")]
9293
vec_same: Vec<u32>,
94+
95+
/// A vector of bytes that's serialized as a lowercase hex string.
96+
#[serde_as(as = "Hex")]
97+
lowercase_hex: Vec<u8>,
98+
99+
/// A vector of bytes that's serialized as an uppercase hex string.
100+
#[serde_as(as = "Hex<formats::Uppercase>")]
101+
uppercase_hex: Vec<u8>,
93102
}
94103

95104
let schema = schemars::schema_for!(Basic);

serde_with/tests/schemars_0_8/schemars_basic.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
"bare_field",
77
"box_same",
88
"display_from_str",
9+
"lowercase_hex",
910
"same",
11+
"uppercase_hex",
1012
"vec_same"
1113
],
1214
"properties": {
@@ -26,12 +28,22 @@
2628
"description": "Field that directly uses `DisplayFromStr`",
2729
"type": "string"
2830
},
31+
"lowercase_hex": {
32+
"description": "A vector of bytes that's serialized as a lowercase hex string.",
33+
"type": "string",
34+
"pattern": "^(?:[0-9a-f]{2})*$"
35+
},
2936
"same": {
3037
"description": "Same does not implement `JsonSchema` directly so this checks that the correct schemars attribute was injected.",
3138
"type": "integer",
3239
"format": "uint32",
3340
"minimum": 0.0
3441
},
42+
"uppercase_hex": {
43+
"description": "A vector of bytes that's serialized as an uppercase hex string.",
44+
"type": "string",
45+
"pattern": "^(?:[0-9A-F]{2})*$"
46+
},
3547
"vec_same": {
3648
"description": "Same thing, but with a Vec this time.",
3749
"type": "array",

serde_with/tests/schemars_0_9/main.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use expect_test::expect_file;
66
use schemars::JsonSchema;
77
use serde::Serialize;
88
use serde_json::json;
9+
use serde_with::hex::*;
910
use serde_with::*;
1011
use std::collections::BTreeSet;
1112

@@ -91,6 +92,14 @@ fn schemars_basic() {
9192
/// Same thing, but with a Vec this time.
9293
#[serde_as(as = "Vec<_>")]
9394
vec_same: Vec<u32>,
95+
96+
/// A vector of bytes that's serialized as a lowercase hex string.
97+
#[serde_as(as = "Hex")]
98+
lowercase_hex: Vec<u8>,
99+
100+
/// A vector of bytes that's serialized as an uppercase hex string.
101+
#[serde_as(as = "Hex<formats::Uppercase>")]
102+
uppercase_hex: Vec<u8>,
94103
}
95104

96105
let schema = schemars::schema_for!(Basic);

serde_with/tests/schemars_0_9/schemars_basic.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,25 @@
3333
"format": "uint32",
3434
"minimum": 0
3535
}
36+
},
37+
"lowercase_hex": {
38+
"description": "A vector of bytes that's serialized as a lowercase hex string.",
39+
"type": "string",
40+
"pattern": "^(?:[0-9a-f]{2})*$"
41+
},
42+
"uppercase_hex": {
43+
"description": "A vector of bytes that's serialized as an uppercase hex string.",
44+
"type": "string",
45+
"pattern": "^(?:[0-9A-F]{2})*$"
3646
}
3747
},
3848
"required": [
3949
"bare_field",
4050
"display_from_str",
4151
"same",
4252
"box_same",
43-
"vec_same"
53+
"vec_same",
54+
"lowercase_hex",
55+
"uppercase_hex"
4456
]
4557
}

serde_with/tests/schemars_1/main.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use expect_test::expect_file;
66
use schemars::JsonSchema;
77
use serde::Serialize;
88
use serde_json::json;
9+
use serde_with::hex::*;
910
use serde_with::*;
1011
use std::collections::BTreeSet;
1112

@@ -91,6 +92,14 @@ fn schemars_basic() {
9192
/// Same thing, but with a Vec this time.
9293
#[serde_as(as = "Vec<_>")]
9394
vec_same: Vec<u32>,
95+
96+
/// A vector of bytes that's serialized as a lowercase hex string.
97+
#[serde_as(as = "Hex")]
98+
lowercase_hex: Vec<u8>,
99+
100+
/// A vector of bytes that's serialized as an uppercase hex string.
101+
#[serde_as(as = "Hex<formats::Uppercase>")]
102+
uppercase_hex: Vec<u8>,
94103
}
95104

96105
let schema = schemars::schema_for!(Basic);

serde_with/tests/schemars_1/schemars_basic.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,25 @@
3333
"format": "uint32",
3434
"minimum": 0
3535
}
36+
},
37+
"lowercase_hex": {
38+
"description": "A vector of bytes that's serialized as a lowercase hex string.",
39+
"type": "string",
40+
"pattern": "^(?:[0-9a-f]{2})*$"
41+
},
42+
"uppercase_hex": {
43+
"description": "A vector of bytes that's serialized as an uppercase hex string.",
44+
"type": "string",
45+
"pattern": "^(?:[0-9A-F]{2})*$"
3646
}
3747
},
3848
"required": [
3949
"bare_field",
4050
"display_from_str",
4151
"same",
4252
"box_same",
43-
"vec_same"
53+
"vec_same",
54+
"lowercase_hex",
55+
"uppercase_hex"
4456
]
4557
}

0 commit comments

Comments
 (0)