diff --git a/crates/aiken-project/src/blueprint/schema.rs b/crates/aiken-project/src/blueprint/schema.rs index 8b5b4009..aecb52fe 100644 --- a/crates/aiken-project/src/blueprint/schema.rs +++ b/crates/aiken-project/src/blueprint/schema.rs @@ -36,7 +36,7 @@ pub enum Schema { String, Pair(Data, Data), List(Vec), - Data(Option), + Data(Data), } /// A schema for Plutus' Data. @@ -47,6 +47,7 @@ pub enum Data { List(Items), Map(Box, Box), AnyOf(Vec>), + Opaque, } /// A structure that represents either one or many elements. @@ -89,32 +90,32 @@ impl Annotated { "Data" => Ok(Annotated { title: Some("Data".to_string()), description: Some("Any Plutus data.".to_string()), - annotated: Schema::Data(None), + annotated: Schema::Data(Data::Opaque), }), - "ByteArray" => Ok(Schema::Data(Some(Data::Bytes)).into()), + "ByteArray" => Ok(Schema::Data(Data::Bytes).into()), - "Int" => Ok(Schema::Data(Some(Data::Integer)).into()), + "Int" => Ok(Schema::Data(Data::Integer).into()), "String" => Ok(Schema::String.into()), "Void" => Ok(Annotated { title: Some("Unit".to_string()), description: Some("The nullary constructor.".to_string()), - annotated: Schema::Data(Some(Data::AnyOf(vec![Annotated { + annotated: Schema::Data(Data::AnyOf(vec![Annotated { title: None, description: None, annotated: Constructor { index: 0, fields: vec![], }, - }]))), + }])), }), "Bool" => Ok(Annotated { title: Some("Bool".to_string()), description: None, - annotated: Schema::Data(Some(Data::AnyOf(vec![ + annotated: Schema::Data(Data::AnyOf(vec![ Annotated { title: Some("False".to_string()), description: None, @@ -131,13 +132,13 @@ impl Annotated { fields: vec![], }, }, - ]))), + ])), }), "Ordering" => Ok(Annotated { title: Some("Ordering".to_string()), description: None, - annotated: Schema::Data(Some(Data::AnyOf(vec![ + annotated: Schema::Data(Data::AnyOf(vec![ Annotated { title: Some("Less".to_string()), description: None, @@ -162,7 +163,7 @@ impl Annotated { fields: vec![], }, }, - ]))), + ])), }), "Option" => { @@ -172,7 +173,7 @@ impl Annotated { Ok(Annotated { title: Some("Optional".to_string()), description: None, - annotated: Schema::Data(Some(Data::AnyOf(vec![ + annotated: Schema::Data(Data::AnyOf(vec![ Annotated { title: Some("Some".to_string()), description: Some("An optional value.".to_string()), @@ -189,7 +190,7 @@ impl Annotated { fields: vec![], }, }, - ]))), + ])), }) } @@ -202,19 +203,17 @@ 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::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()), - ) - } + Schema::Data(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(Items::One(Box::new(inner))) } }; - Ok(Schema::Data(Some(data)).into()) + Ok(Schema::Data(data).into()) } _ => Err(Error::new(ErrorContext::UnsupportedType, type_info)), @@ -228,10 +227,10 @@ impl Annotated { let module = modules.get(module_name).unwrap(); let constructor = find_definition(type_name, &module.ast.definitions).unwrap(); let type_parameters = collect_type_parameters(&constructor.typed_parameters, args); - let annotated = Schema::Data(Some( + let annotated = Schema::Data( Data::from_data_type(modules, constructor, &type_parameters) .map_err(|e| e.backtrack(type_info))?, - )); + ); Ok(Annotated { title: Some(constructor.name.clone()), @@ -259,10 +258,10 @@ impl Annotated { let right = Annotated::from_type(modules, right, type_parameters)? .into_data(right) .map_err(|e| e.backtrack(type_info))?; - Ok(Schema::Data(Some(Data::List(Items::Many(vec![ + Ok(Schema::Data(Data::List(Items::Many(vec![ left.annotated, right.annotated, - ])))) + ]))) .into()) } _ => { @@ -277,7 +276,7 @@ impl Annotated { Ok(Annotated { title: Some("Tuple".to_owned()), description: None, - annotated: Schema::Data(Some(Data::List(Items::Many(elems)))), + annotated: Schema::Data(Data::List(Items::Many(elems))), }) } }, @@ -290,7 +289,7 @@ impl Annotated { Annotated { title, description, - annotated: Schema::Data(Some(data)), + annotated: Schema::Data(data), } => Ok(Annotated { title, description, @@ -403,11 +402,7 @@ impl Serialize for Schema { s.serialize_field("items", &items)?; s.end() } - Schema::Data(None) => { - let s = serializer.serialize_struct("Data", 0)?; - s.end() - } - Schema::Data(Some(data)) => data.serialize(serializer), + Schema::Data(data) => data.serialize(serializer), } } } @@ -415,6 +410,10 @@ impl Serialize for Schema { impl Serialize for Data { fn serialize(&self, serializer: S) -> Result { match self { + Data::Opaque => { + let s = serializer.serialize_struct("Opaque", 0)?; + s.end() + } Data::Integer => { let mut s = serializer.serialize_struct("Integer", 1)?; s.serialize_field("dataType", "integer")?; @@ -628,7 +627,7 @@ pub mod test { #[test] fn serialize_data_integer() { - let schema = Schema::Data(Some(Data::Integer)); + let schema = Schema::Data(Data::Integer); assert_json( &schema, json!({ @@ -639,7 +638,7 @@ pub mod test { #[test] fn serialize_data_bytes() { - let schema = Schema::Data(Some(Data::Bytes)); + let schema = Schema::Data(Data::Bytes); assert_json( &schema, json!({ @@ -650,7 +649,7 @@ pub mod test { #[test] fn serialize_data_list_1() { - let schema = Schema::Data(Some(Data::List(Items::One(Box::new(Data::Integer))))); + let schema = Schema::Data(Data::List(Items::One(Box::new(Data::Integer)))); assert_json( &schema, json!({ @@ -664,8 +663,8 @@ pub mod test { #[test] fn serialize_data_list_2() { - let schema = Schema::Data(Some(Data::List(Items::One(Box::new(Data::List( - Items::One(Box::new(Data::Integer)), + let schema = Schema::Data(Data::List(Items::One(Box::new(Data::List(Items::One( + Box::new(Data::Integer), )))))); assert_json( &schema, @@ -682,10 +681,7 @@ pub mod test { #[test] fn serialize_data_list_3() { - let schema = Schema::Data(Some(Data::List(Items::Many(vec![ - Data::Integer, - Data::Bytes, - ])))); + let schema = Schema::Data(Data::List(Items::Many(vec![Data::Integer, Data::Bytes]))); assert_json( &schema, json!({ @@ -700,10 +696,7 @@ pub mod test { #[test] fn serialize_data_map_1() { - let schema = Schema::Data(Some(Data::Map( - Box::new(Data::Integer), - Box::new(Data::Bytes), - ))); + let schema = Schema::Data(Data::Map(Box::new(Data::Integer), Box::new(Data::Bytes))); assert_json( &schema, json!({ @@ -720,10 +713,10 @@ pub mod test { #[test] fn serialize_data_map_2() { - let schema = Schema::Data(Some(Data::Map( + let schema = Schema::Data(Data::Map( Box::new(Data::Bytes), Box::new(Data::List(Items::One(Box::new(Data::Integer)))), - ))); + )); assert_json( &schema, json!({ @@ -741,11 +734,11 @@ pub mod test { #[test] fn serialize_data_constr_1() { - let schema = Schema::Data(Some(Data::AnyOf(vec![Constructor { + let schema = Schema::Data(Data::AnyOf(vec![Constructor { index: 0, fields: vec![], } - .into()]))); + .into()])); assert_json( &schema, json!({ @@ -760,7 +753,7 @@ pub mod test { #[test] fn serialize_data_constr_2() { - let schema = Schema::Data(Some(Data::AnyOf(vec![ + let schema = Schema::Data(Data::AnyOf(vec![ Constructor { index: 0, fields: vec![Data::Integer.into()], @@ -771,7 +764,7 @@ pub mod test { fields: vec![Data::Bytes.into()], } .into(), - ]))); + ])); assert_json( &schema, json!({ @@ -793,7 +786,7 @@ pub mod test { #[test] fn serialize_empty_data() { - let schema = Schema::Data(None); + let schema = Schema::Data(Data::Opaque); assert_json(&schema, json!({})) } diff --git a/crates/aiken-project/src/blueprint/validator.rs b/crates/aiken-project/src/blueprint/validator.rs index da4136b6..2c20353a 100644 --- a/crates/aiken-project/src/blueprint/validator.rs +++ b/crates/aiken-project/src/blueprint/validator.rs @@ -710,9 +710,18 @@ mod test { "title": "test_module.spend", "hash": "a3dbab684d90d19e6bab3a0b00a7290ff59fe637d14428859bf74376", "datum": { - "title": "Data", - "description": "Any Plutus data.", - "schema": {}, + "title": "Foo", + "schema": { + "anyOf": [{ + "title": "Foo", + "index": 0, + "fields": [{ + "title": "foo", + "description": "Any Plutus data.", + }], + "dataType": "constructor", + }] + }, }, "redeemer": { "schema": {