Fix blueprint schema for tuples.

This commit is contained in:
KtorZ 2023-02-21 15:29:33 +01:00
parent e611d1ee7a
commit db0dfbbec1
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
2 changed files with 56 additions and 18 deletions

View File

@ -44,11 +44,18 @@ pub enum Schema {
pub enum Data { pub enum Data {
Integer, Integer,
Bytes, Bytes,
List(Box<Data>), List(Items<Data>),
Map(Box<Data>, Box<Data>), Map(Box<Data>, Box<Data>),
AnyOf(Vec<Annotated<Constructor>>), AnyOf(Vec<Annotated<Constructor>>),
} }
/// A structure that represents either one or many elements.
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Items<T> {
One(Box<T>),
Many(Vec<T>),
}
/// Captures a single UPLC constructor with its /// Captures a single UPLC constructor with its
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct Constructor { pub struct Constructor {
@ -195,10 +202,15 @@ impl Annotated<Schema> {
// as such. We don't have a concept of language maps in Aiken, so we simply // as such. We don't have a concept of language maps in Aiken, so we simply
// make all types abide by this convention. // make all types abide by this convention.
let data = match generic.annotated { let data = match generic.annotated {
Schema::Pair(left, right) => Data::Map(Box::new(left), Box::new(right)), Schema::Data(Some(Data::List(Items::Many(xs)))) if xs.len() == 2 => {
Data::Map(
Box::new(xs.first().unwrap().to_owned()),
Box::new(xs.last().unwrap().to_owned()),
)
}
_ => { _ => {
let inner = generic.into_data(type_info)?.annotated; let inner = generic.into_data(type_info)?.annotated;
Data::List(Box::new(inner)) Data::List(Items::One(Box::new(inner)))
} }
}; };
@ -247,7 +259,11 @@ impl Annotated<Schema> {
let right = Annotated::from_type(modules, right, type_parameters)? let right = Annotated::from_type(modules, right, type_parameters)?
.into_data(right) .into_data(right)
.map_err(|e| e.backtrack(type_info))?; .map_err(|e| e.backtrack(type_info))?;
Ok(Schema::Pair(left.annotated, right.annotated).into()) Ok(Schema::Data(Some(Data::List(Items::Many(vec![
left.annotated,
right.annotated,
]))))
.into())
} }
_ => { _ => {
let elems = elems let elems = elems
@ -261,7 +277,7 @@ impl Annotated<Schema> {
Ok(Annotated { Ok(Annotated {
title: Some("Tuple".to_owned()), title: Some("Tuple".to_owned()),
description: None, description: None,
annotated: Schema::List(elems), annotated: Schema::Data(Some(Data::List(Items::Many(elems)))).into(),
}) })
} }
}, },
@ -409,7 +425,13 @@ impl Serialize for Data {
s.serialize_field("dataType", "bytes")?; s.serialize_field("dataType", "bytes")?;
s.end() s.end()
} }
Data::List(items) => { Data::List(Items::One(item)) => {
let mut s = serializer.serialize_struct("List", 2)?;
s.serialize_field("dataType", "list")?;
s.serialize_field("items", &item)?;
s.end()
}
Data::List(Items::Many(items)) => {
let mut s = serializer.serialize_struct("List", 2)?; let mut s = serializer.serialize_struct("List", 2)?;
s.serialize_field("dataType", "list")?; s.serialize_field("dataType", "list")?;
s.serialize_field("items", &items)?; s.serialize_field("items", &items)?;
@ -624,7 +646,7 @@ pub mod test {
#[test] #[test]
fn serialize_data_list_1() { fn serialize_data_list_1() {
let schema = Schema::Data(Some(Data::List(Box::new(Data::Integer)))); let schema = Schema::Data(Some(Data::List(Items::One(Box::new(Data::Integer)))));
assert_json( assert_json(
&schema, &schema,
json!({ json!({
@ -638,8 +660,8 @@ pub mod test {
#[test] #[test]
fn serialize_data_list_2() { fn serialize_data_list_2() {
let schema = Schema::Data(Some(Data::List(Box::new(Data::List(Box::new( let schema = Schema::Data(Some(Data::List(Items::One(Box::new(Data::List(
Data::Integer, Items::One(Box::new(Data::Integer)),
)))))); ))))));
assert_json( assert_json(
&schema, &schema,
@ -654,6 +676,24 @@ pub mod test {
); );
} }
#[test]
fn serialize_data_list_3() {
let schema = Schema::Data(Some(Data::List(Items::Many(vec![
Data::Integer,
Data::Bytes,
]))));
assert_json(
&schema,
json!({
"dataType": "list",
"items": [
{ "dataType": "integer" },
{ "dataType": "bytes" },
]
}),
);
}
#[test] #[test]
fn serialize_data_map_1() { fn serialize_data_map_1() {
let schema = Schema::Data(Some(Data::Map( let schema = Schema::Data(Some(Data::Map(
@ -678,7 +718,7 @@ pub mod test {
fn serialize_data_map_2() { fn serialize_data_map_2() {
let schema = Schema::Data(Some(Data::Map( let schema = Schema::Data(Some(Data::Map(
Box::new(Data::Bytes), Box::new(Data::Bytes),
Box::new(Data::List(Box::new(Data::Integer))), Box::new(Data::List(Items::One(Box::new(Data::Integer)))),
))); )));
assert_json( assert_json(
&schema, &schema,

View File

@ -474,13 +474,11 @@ mod test {
"title": "test_module.spend", "title": "test_module.spend",
"hash": "3c6766e7a36df2aa13c0e9e6e071317ed39d05f405771c4f1a81c6cc", "hash": "3c6766e7a36df2aa13c0e9e6e071317ed39d05f405771c4f1a81c6cc",
"datum": { "datum": {
"dataType": "#pair", "dataType": "list",
"left": { "items": [
"dataType": "integer" { "dataType": "integer" },
}, { "dataType": "bytes" }
"right": { ]
"dataType": "bytes"
}
}, },
"redeemer": { "redeemer": {
"dataType": "#string" "dataType": "#string"
@ -505,7 +503,7 @@ mod test {
"hash": "f335ce0436fd7df56e727a66ada7298534a27b98f887bc3b7947ee48", "hash": "f335ce0436fd7df56e727a66ada7298534a27b98f887bc3b7947ee48",
"datum": { "datum": {
"title": "Tuple", "title": "Tuple",
"dataType": "#list", "dataType": "list",
"items": [ "items": [
{ {
"dataType": "integer" "dataType": "integer"