From db0dfbbec13b544654de66153d0cc6b168ebb145 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Tue, 21 Feb 2023 15:29:33 +0100 Subject: [PATCH] Fix blueprint schema for tuples. --- crates/aiken-project/src/blueprint/schema.rs | 60 +++++++++++++++---- .../aiken-project/src/blueprint/validator.rs | 14 ++--- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/crates/aiken-project/src/blueprint/schema.rs b/crates/aiken-project/src/blueprint/schema.rs index 0a974268..af03eb7f 100644 --- a/crates/aiken-project/src/blueprint/schema.rs +++ b/crates/aiken-project/src/blueprint/schema.rs @@ -44,11 +44,18 @@ pub enum Schema { pub enum Data { Integer, Bytes, - List(Box), + List(Items), Map(Box, Box), AnyOf(Vec>), } +/// A structure that represents either one or many elements. +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum Items { + One(Box), + Many(Vec), +} + /// Captures a single UPLC constructor with its #[derive(Debug, PartialEq, Eq, Clone)] pub struct Constructor { @@ -195,10 +202,15 @@ impl Annotated { // as such. We don't have a concept of language maps in Aiken, so we simply // make all types abide by this convention. 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; - Data::List(Box::new(inner)) + Data::List(Items::One(Box::new(inner))) } }; @@ -247,7 +259,11 @@ impl Annotated { let right = Annotated::from_type(modules, right, type_parameters)? .into_data(right) .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 @@ -261,7 +277,7 @@ impl Annotated { Ok(Annotated { title: Some("Tuple".to_owned()), 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.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)?; s.serialize_field("dataType", "list")?; s.serialize_field("items", &items)?; @@ -624,7 +646,7 @@ pub mod test { #[test] 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( &schema, json!({ @@ -638,8 +660,8 @@ pub mod test { #[test] fn serialize_data_list_2() { - let schema = Schema::Data(Some(Data::List(Box::new(Data::List(Box::new( - Data::Integer, + let schema = Schema::Data(Some(Data::List(Items::One(Box::new(Data::List( + Items::One(Box::new(Data::Integer)), )))))); assert_json( &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] fn serialize_data_map_1() { let schema = Schema::Data(Some(Data::Map( @@ -678,7 +718,7 @@ pub mod test { fn serialize_data_map_2() { let schema = Schema::Data(Some(Data::Map( Box::new(Data::Bytes), - Box::new(Data::List(Box::new(Data::Integer))), + Box::new(Data::List(Items::One(Box::new(Data::Integer)))), ))); assert_json( &schema, diff --git a/crates/aiken-project/src/blueprint/validator.rs b/crates/aiken-project/src/blueprint/validator.rs index 1c3fc1f3..5a99becc 100644 --- a/crates/aiken-project/src/blueprint/validator.rs +++ b/crates/aiken-project/src/blueprint/validator.rs @@ -474,13 +474,11 @@ mod test { "title": "test_module.spend", "hash": "3c6766e7a36df2aa13c0e9e6e071317ed39d05f405771c4f1a81c6cc", "datum": { - "dataType": "#pair", - "left": { - "dataType": "integer" - }, - "right": { - "dataType": "bytes" - } + "dataType": "list", + "items": [ + { "dataType": "integer" }, + { "dataType": "bytes" } + ] }, "redeemer": { "dataType": "#string" @@ -505,7 +503,7 @@ mod test { "hash": "f335ce0436fd7df56e727a66ada7298534a27b98f887bc3b7947ee48", "datum": { "title": "Tuple", - "dataType": "#list", + "dataType": "list", "items": [ { "dataType": "integer"