Introduce indirection for fields.
This commit is contained in:
parent
3a7aac0a33
commit
f67e049dc2
|
@ -61,7 +61,15 @@ pub enum Items<T> {
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct Constructor {
|
pub struct Constructor {
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
pub fields: Vec<Annotated<Data>>,
|
pub fields: Vec<Field>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A field of a constructor. Can be either an inlined Data schema or a reference to another type.
|
||||||
|
/// References are mostly only used for recursive types.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
pub enum Field {
|
||||||
|
Inline(Annotated<Data>),
|
||||||
|
Reference { path: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<T> for Annotated<T> {
|
impl<T> From<T> for Annotated<T> {
|
||||||
|
@ -179,7 +187,7 @@ impl Annotated<Schema> {
|
||||||
description: Some("An optional value.".to_string()),
|
description: Some("An optional value.".to_string()),
|
||||||
annotated: Constructor {
|
annotated: Constructor {
|
||||||
index: 0,
|
index: 0,
|
||||||
fields: vec![generic],
|
fields: vec![Field::Inline(generic)],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Annotated {
|
Annotated {
|
||||||
|
@ -308,7 +316,7 @@ impl Data {
|
||||||
schema.description = field.doc.clone().map(|s| s.trim().to_string());
|
schema.description = field.doc.clone().map(|s| s.trim().to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
fields.push(schema);
|
fields.push(Field::Inline(schema));
|
||||||
}
|
}
|
||||||
|
|
||||||
let variant = Annotated {
|
let variant = Annotated {
|
||||||
|
@ -324,7 +332,7 @@ impl Data {
|
||||||
// are erased completely at compilation time.
|
// are erased completely at compilation time.
|
||||||
if data_type.opaque {
|
if data_type.opaque {
|
||||||
if let [variant] = &variants[..] {
|
if let [variant] = &variants[..] {
|
||||||
if let [field] = &variant.annotated.fields[..] {
|
if let [Field::Inline(field)] = &variant.annotated.fields[..] {
|
||||||
return Ok(field.annotated.clone());
|
return Ok(field.annotated.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,6 +461,19 @@ impl Serialize for Constructor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Serialize for Field {
|
||||||
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
|
match self {
|
||||||
|
Field::Inline(schema) => schema.serialize(serializer),
|
||||||
|
Field::Reference { path } => {
|
||||||
|
let mut s = serializer.serialize_struct("$ref", 1)?;
|
||||||
|
s.serialize_field("$ref", path)?;
|
||||||
|
s.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, thiserror::Error)]
|
#[derive(Debug, PartialEq, Clone, thiserror::Error)]
|
||||||
#[error("{}", context)]
|
#[error("{}", context)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
|
@ -743,12 +764,12 @@ pub mod test {
|
||||||
let schema = Schema::Data(Data::AnyOf(vec![
|
let schema = Schema::Data(Data::AnyOf(vec![
|
||||||
Constructor {
|
Constructor {
|
||||||
index: 0,
|
index: 0,
|
||||||
fields: vec![Data::Integer.into()],
|
fields: vec![Field::Inline(Data::Integer.into())],
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
Constructor {
|
Constructor {
|
||||||
index: 1,
|
index: 1,
|
||||||
fields: vec![Data::Bytes.into()],
|
fields: vec![Field::Inline(Data::Bytes.into())],
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
]));
|
]));
|
||||||
|
|
Loading…
Reference in New Issue