Generalize schema definition to work from inline schema or reference.
This commit is contained in:
parent
d620f6367c
commit
ee220881b6
|
@ -142,7 +142,7 @@ impl From<&Config> for Preamble {
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use aiken_lang::builtins;
|
use aiken_lang::builtins;
|
||||||
use schema::{Data, Items, Schema};
|
use schema::{Data, Declaration, Items, Schema};
|
||||||
use serde_json::{self, json};
|
use serde_json::{self, json};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
@ -218,7 +218,10 @@ mod test {
|
||||||
&HashMap::new(),
|
&HashMap::new(),
|
||||||
|_| Ok(Schema::Data(Data::Bytes).into()),
|
|_| Ok(Schema::Data(Data::Bytes).into()),
|
||||||
)?;
|
)?;
|
||||||
Ok(Schema::Data(Data::List(Items::One(Box::new(ref_bytes)))).into())
|
Ok(
|
||||||
|
Schema::Data(Data::List(Items::One(Declaration::Referenced(ref_bytes))))
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -11,6 +11,7 @@ use serde::{
|
||||||
de::{self, Deserialize, Deserializer, MapAccess, Visitor},
|
de::{self, Deserialize, Deserializer, MapAccess, Visitor},
|
||||||
ser::{Serialize, SerializeStruct, Serializer},
|
ser::{Serialize, SerializeStruct, Serializer},
|
||||||
};
|
};
|
||||||
|
use serde_json as json;
|
||||||
use std::{collections::HashMap, fmt, ops::Deref, sync::Arc};
|
use std::{collections::HashMap, fmt, ops::Deref, sync::Arc};
|
||||||
use uplc::ast::Term;
|
use uplc::ast::Term;
|
||||||
|
|
||||||
|
@ -27,6 +28,13 @@ pub struct Annotated<T> {
|
||||||
pub annotated: T,
|
pub annotated: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum Declaration<T> {
|
||||||
|
Referenced(Reference),
|
||||||
|
Inline(Box<T>),
|
||||||
|
}
|
||||||
|
|
||||||
/// A schema for low-level UPLC primitives.
|
/// A schema for low-level UPLC primitives.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum Schema {
|
pub enum Schema {
|
||||||
|
@ -35,10 +43,8 @@ pub enum Schema {
|
||||||
Integer,
|
Integer,
|
||||||
Bytes,
|
Bytes,
|
||||||
String,
|
String,
|
||||||
// TODO: Generalize to work with either Reference or Data
|
Pair(Declaration<Schema>, Declaration<Schema>),
|
||||||
Pair(Reference, Reference),
|
List(Items<Schema>),
|
||||||
// TODO: Generalize to work with either Reference or Data
|
|
||||||
List(Items<Reference>),
|
|
||||||
Data(Data),
|
Data(Data),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,10 +53,8 @@ pub enum Schema {
|
||||||
pub enum Data {
|
pub enum Data {
|
||||||
Integer,
|
Integer,
|
||||||
Bytes,
|
Bytes,
|
||||||
// TODO: Generalize to work with either Reference or Data
|
List(Items<Data>),
|
||||||
List(Items<Reference>),
|
Map(Declaration<Data>, Declaration<Data>),
|
||||||
// TODO: Generalize to work with either Reference or Data
|
|
||||||
Map(Box<Reference>, Box<Reference>),
|
|
||||||
AnyOf(Vec<Annotated<Constructor>>),
|
AnyOf(Vec<Annotated<Constructor>>),
|
||||||
Opaque,
|
Opaque,
|
||||||
}
|
}
|
||||||
|
@ -59,8 +63,8 @@ pub enum Data {
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum Items<T> {
|
pub enum Items<T> {
|
||||||
One(Box<T>),
|
One(Declaration<T>),
|
||||||
Many(Vec<T>),
|
Many(Vec<Declaration<T>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Captures a single UPLC constructor with its
|
/// Captures a single UPLC constructor with its
|
||||||
|
@ -68,7 +72,7 @@ pub enum Items<T> {
|
||||||
pub struct Constructor {
|
pub struct Constructor {
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
// TODO: Generalize to work with either Reference or Data
|
// TODO: Generalize to work with either Reference or Data
|
||||||
pub fields: Vec<Annotated<Reference>>,
|
pub fields: Vec<Annotated<Declaration<Data>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<T> for Annotated<T> {
|
impl<T> From<T> for Annotated<T> {
|
||||||
|
@ -103,10 +107,10 @@ impl<'a, T> TryFrom<&'a Term<T>> for Schema {
|
||||||
PlutusData::BoundedBytes(..) => {
|
PlutusData::BoundedBytes(..) => {
|
||||||
Data::Bytes
|
Data::Bytes
|
||||||
}
|
}
|
||||||
PlutusData::Map(keyValuePair) => {
|
PlutusData::Array(elems) => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
PlutusData::Array(elems) => {
|
PlutusData::Map(keyValuePair) => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
PlutusData::Constr(Constr{ tag, fields, any_constructor }) => {
|
PlutusData::Constr(Constr{ tag, fields, any_constructor }) => {
|
||||||
|
@ -141,7 +145,7 @@ impl Annotated<Schema> {
|
||||||
description: Some("A redeemer wrapped in an extra constructor to make multi-validator detection possible on-chain.".to_string()),
|
description: Some("A redeemer wrapped in an extra constructor to make multi-validator detection possible on-chain.".to_string()),
|
||||||
annotated: Schema::Data(Data::AnyOf(vec![Constructor {
|
annotated: Schema::Data(Data::AnyOf(vec![Constructor {
|
||||||
index: REDEEMER_DISCRIMINANT,
|
index: REDEEMER_DISCRIMINANT,
|
||||||
fields: vec![schema.into()],
|
fields: vec![Declaration::Referenced(schema).into()],
|
||||||
}
|
}
|
||||||
.into()])),
|
.into()])),
|
||||||
})
|
})
|
||||||
|
@ -270,7 +274,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.into()],
|
fields: vec![Declaration::Referenced(generic).into()],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Annotated {
|
Annotated {
|
||||||
|
@ -311,22 +315,15 @@ impl Annotated<Schema> {
|
||||||
} if xs.len() == 2 => {
|
} if xs.len() == 2 => {
|
||||||
definitions.remove(&generic);
|
definitions.remove(&generic);
|
||||||
Data::Map(
|
Data::Map(
|
||||||
Box::new(
|
xs.first()
|
||||||
xs.first()
|
.expect("length (== 2) checked in pattern clause")
|
||||||
.expect("length (== 2) checked in pattern clause")
|
.to_owned(),
|
||||||
.to_owned(),
|
xs.last()
|
||||||
),
|
.expect("length (== 2) checked in pattern clause")
|
||||||
Box::new(
|
.to_owned(),
|
||||||
xs.last()
|
|
||||||
.expect("length (== 2) checked in pattern clause")
|
|
||||||
.to_owned(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Data::List(Items::One(Declaration::Referenced(generic))),
|
||||||
// let inner = schema.clone().into_data(type_info)?.annotated;
|
|
||||||
Data::List(Items::One(Box::new(generic)))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Schema::Data(data).into())
|
Ok(Schema::Data(data).into())
|
||||||
|
@ -371,6 +368,7 @@ impl Annotated<Schema> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|elem| {
|
.map(|elem| {
|
||||||
Annotated::do_from_type(elem, modules, type_parameters, definitions)
|
Annotated::do_from_type(elem, modules, type_parameters, definitions)
|
||||||
|
.map(Declaration::Referenced)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.map_err(|e| e.backtrack(type_info))?;
|
.map_err(|e| e.backtrack(type_info))?;
|
||||||
|
@ -449,7 +447,7 @@ impl Data {
|
||||||
fields.push(Annotated {
|
fields.push(Annotated {
|
||||||
title: field.label.clone(),
|
title: field.label.clone(),
|
||||||
description: field.doc.clone().map(|s| s.trim().to_string()),
|
description: field.doc.clone().map(|s| s.trim().to_string()),
|
||||||
annotated: reference,
|
annotated: Declaration::Referenced(reference),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,7 +577,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut data_type: Option<String> = None;
|
let mut data_type: Option<String> = None;
|
||||||
let mut items: Option<Items<Reference>> = None;
|
let mut items: Option<json::Value> = None; // defer items deserialization to later
|
||||||
let mut keys = None;
|
let mut keys = None;
|
||||||
let mut left = None;
|
let mut left = None;
|
||||||
let mut right = None;
|
let mut right = None;
|
||||||
|
@ -639,6 +637,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let expect_data_items = || match &items {
|
||||||
|
Some(items) => serde_json::from_value::<Items<Data>>(items.clone())
|
||||||
|
.map_err(|e| de::Error::custom(e.to_string())),
|
||||||
|
None => Err(de::Error::missing_field("items")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let expect_schema_items = || match &items {
|
||||||
|
Some(items) => serde_json::from_value::<Items<Schema>>(items.clone())
|
||||||
|
.map_err(|e| de::Error::custom(e.to_string())),
|
||||||
|
None => Err(de::Error::missing_field("items")),
|
||||||
|
};
|
||||||
|
|
||||||
let expect_no_items = || {
|
let expect_no_items = || {
|
||||||
if items.is_some() {
|
if items.is_some() {
|
||||||
return Err(de::Error::custom(
|
return Err(de::Error::custom(
|
||||||
|
@ -695,26 +705,28 @@ where
|
||||||
Some(constructors) => Ok(Schema::Data(Data::AnyOf(constructors))),
|
Some(constructors) => Ok(Schema::Data(Data::AnyOf(constructors))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(data_type) if data_type == "list" || data_type == "#list" => {
|
Some(data_type) if data_type == "list" => {
|
||||||
expect_no_keys()?;
|
expect_no_keys()?;
|
||||||
expect_no_values()?;
|
expect_no_values()?;
|
||||||
expect_no_any_of()?;
|
expect_no_any_of()?;
|
||||||
expect_no_left_or_right()?;
|
expect_no_left_or_right()?;
|
||||||
match items {
|
let items = expect_data_items()?;
|
||||||
Some(items) if data_type == "list" => Ok(Schema::Data(Data::List(items))),
|
Ok(Schema::Data(Data::List(items)))
|
||||||
Some(items) if data_type == "#list" => Ok(Schema::List(items)),
|
}
|
||||||
Some(_) => unreachable!("condition checked in pattern guard"),
|
Some(data_type) if data_type == "#list" => {
|
||||||
None => Err(de::Error::missing_field("items")),
|
expect_no_keys()?;
|
||||||
}
|
expect_no_values()?;
|
||||||
|
expect_no_any_of()?;
|
||||||
|
expect_no_left_or_right()?;
|
||||||
|
let items = expect_schema_items()?;
|
||||||
|
Ok(Schema::List(items))
|
||||||
}
|
}
|
||||||
Some(data_type) if data_type == "map" => {
|
Some(data_type) if data_type == "map" => {
|
||||||
expect_no_items()?;
|
expect_no_items()?;
|
||||||
expect_no_any_of()?;
|
expect_no_any_of()?;
|
||||||
expect_no_left_or_right()?;
|
expect_no_left_or_right()?;
|
||||||
match (keys, values) {
|
match (keys, values) {
|
||||||
(Some(keys), Some(values)) => {
|
(Some(keys), Some(values)) => Ok(Schema::Data(Data::Map(keys, values))),
|
||||||
Ok(Schema::Data(Data::Map(Box::new(keys), Box::new(values))))
|
|
||||||
}
|
|
||||||
(None, _) => Err(de::Error::missing_field("keys")),
|
(None, _) => Err(de::Error::missing_field("keys")),
|
||||||
(Some(..), None) => Err(de::Error::missing_field("values")),
|
(Some(..), None) => Err(de::Error::missing_field("values")),
|
||||||
}
|
}
|
||||||
|
@ -1069,7 +1081,7 @@ pub mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_data_list_1() {
|
fn serialize_data_list_1() {
|
||||||
let ref_integer = Reference::new("Int");
|
let ref_integer = Reference::new("Int");
|
||||||
let schema = Schema::Data(Data::List(Items::One(Box::new(ref_integer))));
|
let schema = Schema::Data(Data::List(Items::One(Declaration::Referenced(ref_integer))));
|
||||||
assert_json(
|
assert_json(
|
||||||
&schema,
|
&schema,
|
||||||
json!({
|
json!({
|
||||||
|
@ -1084,7 +1096,9 @@ pub mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_data_list_2() {
|
fn serialize_data_list_2() {
|
||||||
let ref_list_integer = Reference::new("List$Int");
|
let ref_list_integer = Reference::new("List$Int");
|
||||||
let schema = Schema::Data(Data::List(Items::One(Box::new(ref_list_integer))));
|
let schema = Schema::Data(Data::List(Items::One(Declaration::Referenced(
|
||||||
|
ref_list_integer,
|
||||||
|
))));
|
||||||
assert_json(
|
assert_json(
|
||||||
&schema,
|
&schema,
|
||||||
json!({
|
json!({
|
||||||
|
@ -1098,9 +1112,9 @@ pub mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_data_map_1() {
|
fn serialize_data_map_1() {
|
||||||
let ref_integer = Reference::new("Int");
|
let ref_integer = Declaration::Referenced(Reference::new("Int"));
|
||||||
let ref_bytes = Reference::new("ByteArray");
|
let ref_bytes = Declaration::Referenced(Reference::new("ByteArray"));
|
||||||
let schema = Schema::Data(Data::Map(Box::new(ref_integer), Box::new(ref_bytes)));
|
let schema = Schema::Data(Data::Map(ref_integer, ref_bytes));
|
||||||
assert_json(
|
assert_json(
|
||||||
&schema,
|
&schema,
|
||||||
json!({
|
json!({
|
||||||
|
@ -1139,12 +1153,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![Reference::new("Int").into()],
|
fields: vec![Declaration::Referenced(Reference::new("Int")).into()],
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
Constructor {
|
Constructor {
|
||||||
index: 1,
|
index: 1,
|
||||||
fields: vec![Reference::new("Bytes").into()],
|
fields: vec![Declaration::Referenced(Reference::new("Bytes")).into()],
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
]));
|
]));
|
||||||
|
@ -1236,7 +1250,7 @@ pub mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialize_data_list_one() {
|
fn deserialize_data_list_one() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Data::List(Items::One(Box::new(Reference::new("foo")))),
|
Data::List(Items::One(Declaration::Referenced(Reference::new("foo")))),
|
||||||
serde_json::from_value(json!({
|
serde_json::from_value(json!({
|
||||||
"dataType": "list",
|
"dataType": "list",
|
||||||
"items": { "$ref": "foo" }
|
"items": { "$ref": "foo" }
|
||||||
|
@ -1249,8 +1263,8 @@ pub mod test {
|
||||||
fn deserialize_data_list_many() {
|
fn deserialize_data_list_many() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Data::List(Items::Many(vec![
|
Data::List(Items::Many(vec![
|
||||||
Reference::new("foo"),
|
Declaration::Referenced(Reference::new("foo")),
|
||||||
Reference::new("bar")
|
Declaration::Referenced(Reference::new("bar"))
|
||||||
])),
|
])),
|
||||||
serde_json::from_value(json!({
|
serde_json::from_value(json!({
|
||||||
"dataType": "list",
|
"dataType": "list",
|
||||||
|
@ -1267,8 +1281,8 @@ pub mod test {
|
||||||
fn deserialize_data_map() {
|
fn deserialize_data_map() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Data::Map(
|
Data::Map(
|
||||||
Box::new(Reference::new("foo")),
|
Declaration::Referenced(Reference::new("foo")),
|
||||||
Box::new(Reference::new("bar"))
|
Declaration::Referenced(Reference::new("bar"))
|
||||||
),
|
),
|
||||||
serde_json::from_value(json!({
|
serde_json::from_value(json!({
|
||||||
"dataType": "map",
|
"dataType": "map",
|
||||||
|
@ -1284,7 +1298,10 @@ pub mod test {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Data::AnyOf(vec![Constructor {
|
Data::AnyOf(vec![Constructor {
|
||||||
index: 0,
|
index: 0,
|
||||||
fields: vec![Reference::new("foo").into(), Reference::new("bar").into()],
|
fields: vec![
|
||||||
|
Declaration::Referenced(Reference::new("foo")).into(),
|
||||||
|
Declaration::Referenced(Reference::new("bar")).into()
|
||||||
|
],
|
||||||
}
|
}
|
||||||
.into()]),
|
.into()]),
|
||||||
serde_json::from_value(json!({
|
serde_json::from_value(json!({
|
||||||
|
@ -1309,7 +1326,10 @@ pub mod test {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Data::AnyOf(vec![Constructor {
|
Data::AnyOf(vec![Constructor {
|
||||||
index: 0,
|
index: 0,
|
||||||
fields: vec![Reference::new("foo").into(), Reference::new("bar").into()],
|
fields: vec![
|
||||||
|
Declaration::Referenced(Reference::new("foo")).into(),
|
||||||
|
Declaration::Referenced(Reference::new("bar")).into()
|
||||||
|
],
|
||||||
}
|
}
|
||||||
.into()]),
|
.into()]),
|
||||||
serde_json::from_value(json!({
|
serde_json::from_value(json!({
|
||||||
|
@ -1330,45 +1350,58 @@ pub mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arbitrary_data() -> impl Strategy<Value = Data> {
|
fn arbitrary_data() -> impl Strategy<Value = Data> {
|
||||||
let r = prop_oneof![".*".prop_map(|s| Reference::new(&s))];
|
let leaf = prop_oneof![Just(Data::Opaque), Just(Data::Bytes), Just(Data::Integer)];
|
||||||
let constructor =
|
|
||||||
(0..3usize, prop::collection::vec(r.clone(), 0..3)).prop_map(|(index, fields)| {
|
leaf.prop_recursive(3, 8, 3, |inner| {
|
||||||
Constructor {
|
let r = prop_oneof![
|
||||||
index,
|
".*".prop_map(|s| Declaration::Referenced(Reference::new(&s))),
|
||||||
fields: fields.into_iter().map(|f| f.into()).collect(),
|
inner.prop_map(|s| Declaration::Inline(Box::new(s)))
|
||||||
}
|
];
|
||||||
.into()
|
let constructor =
|
||||||
});
|
(0..3usize, prop::collection::vec(r.clone(), 0..3)).prop_map(|(index, fields)| {
|
||||||
prop_oneof![
|
Constructor {
|
||||||
Just(Data::Opaque),
|
index,
|
||||||
Just(Data::Bytes),
|
fields: fields.into_iter().map(|f| f.into()).collect(),
|
||||||
Just(Data::Integer),
|
}
|
||||||
(r.clone(), r.clone()).prop_map(|(k, v)| Data::Map(Box::new(k), Box::new(v))),
|
.into()
|
||||||
r.clone().prop_map(|x| Data::List(Items::One(Box::new(x)))),
|
});
|
||||||
prop::collection::vec(r, 1..3).prop_map(|xs| Data::List(Items::Many(xs))),
|
|
||||||
prop::collection::vec(constructor, 1..3).prop_map(Data::AnyOf)
|
prop_oneof![
|
||||||
]
|
(r.clone(), r.clone()).prop_map(|(k, v)| Data::Map(k, v)),
|
||||||
|
r.clone().prop_map(|x| Data::List(Items::One(x))),
|
||||||
|
prop::collection::vec(r, 1..3).prop_map(|xs| Data::List(Items::Many(xs))),
|
||||||
|
prop::collection::vec(constructor, 1..3).prop_map(Data::AnyOf)
|
||||||
|
]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arbitrary_schema() -> impl Strategy<Value = Schema> {
|
fn arbitrary_schema() -> impl Strategy<Value = Schema> {
|
||||||
let r = prop_oneof![".*".prop_map(|s| Reference::new(&s))];
|
|
||||||
prop_compose! {
|
prop_compose! {
|
||||||
fn data_strategy()(data in arbitrary_data()) -> Schema {
|
fn data_strategy()(data in arbitrary_data()) -> Schema {
|
||||||
Schema::Data(data)
|
Schema::Data(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prop_oneof![
|
|
||||||
|
let leaf = prop_oneof![
|
||||||
Just(Schema::Unit),
|
Just(Schema::Unit),
|
||||||
Just(Schema::Boolean),
|
Just(Schema::Boolean),
|
||||||
Just(Schema::Bytes),
|
Just(Schema::Bytes),
|
||||||
Just(Schema::Integer),
|
Just(Schema::Integer),
|
||||||
Just(Schema::String),
|
Just(Schema::String),
|
||||||
(r.clone(), r.clone()).prop_map(|(l, r)| Schema::Pair(l, r)),
|
|
||||||
r.clone()
|
|
||||||
.prop_map(|x| Schema::List(Items::One(Box::new(x)))),
|
|
||||||
prop::collection::vec(r, 1..3).prop_map(|xs| Schema::List(Items::Many(xs))),
|
|
||||||
data_strategy(),
|
data_strategy(),
|
||||||
]
|
];
|
||||||
|
|
||||||
|
leaf.prop_recursive(3, 8, 3, |inner| {
|
||||||
|
let r = prop_oneof![
|
||||||
|
".*".prop_map(|s| Declaration::Referenced(Reference::new(&s))),
|
||||||
|
inner.prop_map(|s| Declaration::Inline(Box::new(s)))
|
||||||
|
];
|
||||||
|
prop_oneof![
|
||||||
|
(r.clone(), r.clone()).prop_map(|(l, r)| Schema::Pair(l, r)),
|
||||||
|
r.clone().prop_map(|x| Schema::List(Items::One(x))),
|
||||||
|
prop::collection::vec(r, 1..3).prop_map(|xs| Schema::List(Items::Many(xs))),
|
||||||
|
]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
proptest! {
|
proptest! {
|
||||||
|
|
|
@ -226,7 +226,7 @@ mod test {
|
||||||
super::{
|
super::{
|
||||||
definitions::Definitions,
|
definitions::Definitions,
|
||||||
error::Error,
|
error::Error,
|
||||||
schema::{Annotated, Data, Schema},
|
schema::{Annotated, Data, Declaration, Items, Schema},
|
||||||
},
|
},
|
||||||
*,
|
*,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue