Skip to content

Commit b889564

Browse files
authored
Add library to convert data type to JSON schema. #27 (#85)
Add library to convert data type to JSON schema.
1 parent 59bf84d commit b889564

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ derivative = "2.2.0"
4040
async-lock = "3.4.0"
4141
hex = "0.4.3"
4242
pythonize = "0.23.0"
43+
schemars = "0.8.22"

src/base/json_schema.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use super::schema;
2+
use schemars::schema::{
3+
ArrayValidation, InstanceType, ObjectValidation, SchemaObject, SingleOrVec,
4+
};
5+
6+
pub trait ToJsonSchema {
7+
fn to_json_schema(&self) -> SchemaObject;
8+
}
9+
10+
impl ToJsonSchema for schema::BasicValueType {
11+
fn to_json_schema(&self) -> SchemaObject {
12+
let mut schema = SchemaObject::default();
13+
match self {
14+
schema::BasicValueType::Str => {
15+
schema.instance_type = Some(SingleOrVec::Single(Box::new(InstanceType::String)));
16+
}
17+
schema::BasicValueType::Bytes => {
18+
schema.instance_type = Some(SingleOrVec::Single(Box::new(InstanceType::String)));
19+
}
20+
schema::BasicValueType::Bool => {
21+
schema.instance_type = Some(SingleOrVec::Single(Box::new(InstanceType::Boolean)));
22+
}
23+
schema::BasicValueType::Int64 => {
24+
schema.instance_type = Some(SingleOrVec::Single(Box::new(InstanceType::Integer)));
25+
}
26+
schema::BasicValueType::Float32 | schema::BasicValueType::Float64 => {
27+
schema.instance_type = Some(SingleOrVec::Single(Box::new(InstanceType::Number)));
28+
}
29+
schema::BasicValueType::Json => {
30+
// Can be any value. No type constraint.
31+
}
32+
schema::BasicValueType::Range => {
33+
schema.instance_type = Some(SingleOrVec::Single(Box::new(InstanceType::Array)));
34+
schema.array = Some(Box::new(ArrayValidation {
35+
items: Some(SingleOrVec::Single(Box::new(
36+
SchemaObject {
37+
instance_type: Some(SingleOrVec::Single(Box::new(
38+
InstanceType::Integer,
39+
))),
40+
..Default::default()
41+
}
42+
.into(),
43+
))),
44+
min_items: Some(2),
45+
max_items: Some(2),
46+
..Default::default()
47+
}));
48+
schema
49+
.metadata
50+
.get_or_insert_with(|| Default::default())
51+
.description =
52+
Some("A range, start pos (inclusive), end pos (exclusive).".to_string());
53+
}
54+
schema::BasicValueType::Vector(s) => {
55+
schema.instance_type = Some(SingleOrVec::Single(Box::new(InstanceType::Array)));
56+
schema.array = Some(Box::new(ArrayValidation {
57+
items: Some(SingleOrVec::Single(Box::new(
58+
s.element_type.to_json_schema().into(),
59+
))),
60+
min_items: s.dimension.and_then(|d| u32::try_from(d).ok()),
61+
max_items: s.dimension.and_then(|d| u32::try_from(d).ok()),
62+
..Default::default()
63+
}));
64+
}
65+
}
66+
schema
67+
}
68+
}
69+
70+
impl ToJsonSchema for schema::StructSchema {
71+
fn to_json_schema(&self) -> SchemaObject {
72+
SchemaObject {
73+
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
74+
object: Some(Box::new(ObjectValidation {
75+
properties: self
76+
.fields
77+
.iter()
78+
.map(|f| (f.name.to_string(), f.value_type.to_json_schema().into()))
79+
.collect(),
80+
required: self
81+
.fields
82+
.iter()
83+
.filter_map(|f| (!f.value_type.nullable).then(|| f.name.to_string()))
84+
.collect(),
85+
..Default::default()
86+
})),
87+
..Default::default()
88+
}
89+
}
90+
}
91+
92+
impl ToJsonSchema for schema::ValueType {
93+
fn to_json_schema(&self) -> SchemaObject {
94+
match self {
95+
schema::ValueType::Basic(b) => b.to_json_schema(),
96+
schema::ValueType::Struct(s) => s.to_json_schema(),
97+
schema::ValueType::Collection(c) => SchemaObject {
98+
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Array))),
99+
array: Some(Box::new(ArrayValidation {
100+
items: Some(SingleOrVec::Single(Box::new(c.row.to_json_schema().into()))),
101+
..Default::default()
102+
})),
103+
..Default::default()
104+
},
105+
}
106+
}
107+
}
108+
109+
impl ToJsonSchema for schema::EnrichedValueType {
110+
fn to_json_schema(&self) -> SchemaObject {
111+
self.typ.to_json_schema()
112+
}
113+
}

src/base/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod field_attrs;
2+
pub mod json_schema;
23
pub mod schema;
34
pub mod spec;
45
pub mod value;

0 commit comments

Comments
 (0)