Skip to content

Commit 7422b19

Browse files
authored
Allow for schema derivation for the Hex type (#866)
2 parents 8e5558c + b01c3d4 commit 7422b19

File tree

9 files changed

+138
-2
lines changed

9 files changed

+138
-2
lines changed

serde_with/src/schemars_0_8.rs

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

407+
#[cfg(feature = "hex")]
408+
impl<T, F: formats::Format> JsonSchemaAs<T> for hex::Hex<F> {
409+
fn schema_name() -> String {
410+
"Hex<F>".into()
411+
}
412+
413+
fn schema_id() -> Cow<'static, str> {
414+
"serde_with::hex::Hex<F>".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-Fa-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+
407436
impl JsonSchemaAs<bool> for BoolFromInt<Strict> {
408437
fn schema_name() -> String {
409438
"BoolFromInt<Strict>".into()

serde_with/src/schemars_0_9.rs

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

409+
#[cfg(feature = "hex")]
410+
impl<T, F: formats::Format> JsonSchemaAs<T> for hex::Hex<F> {
411+
fn schema_name() -> Cow<'static, str> {
412+
"Hex<F>".into()
413+
}
414+
415+
fn schema_id() -> Cow<'static, str> {
416+
"serde_with::hex::Hex<F>".into()
417+
}
418+
419+
fn json_schema(_: &mut SchemaGenerator) -> Schema {
420+
json_schema!({
421+
"type": "string",
422+
"pattern": r"^(?:[0-9A-Fa-f]{2})*$",
423+
})
424+
}
425+
426+
fn inline_schema() -> bool {
427+
true
428+
}
429+
}
430+
409431
impl JsonSchemaAs<bool> for BoolFromInt<Strict> {
410432
fn schema_name() -> Cow<'static, str> {
411433
"BoolFromInt<Strict>".into()

serde_with/src/schemars_1.rs

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

411+
#[cfg(feature = "hex")]
412+
impl<T, F: formats::Format> JsonSchemaAs<T> for hex::Hex<F> {
413+
fn schema_name() -> Cow<'static, str> {
414+
"Hex<F>".into()
415+
}
416+
417+
fn schema_id() -> Cow<'static, str> {
418+
"serde_with::hex::Hex<F>".into()
419+
}
420+
421+
fn json_schema(_: &mut SchemaGenerator) -> Schema {
422+
json_schema!({
423+
"type": "string",
424+
"pattern": r"^(?:[0-9A-Fa-f]{2})*$",
425+
})
426+
}
427+
428+
fn inline_schema() -> bool {
429+
true
430+
}
431+
}
432+
411433
impl JsonSchemaAs<bool> for BoolFromInt<Strict> {
412434
fn schema_name() -> Cow<'static, str> {
413435
"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-Fa-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-Fa-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-Fa-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-Fa-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-Fa-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-Fa-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)