diff --git a/implementations/rust/preserves-schema/src/bin/preserves-schema-rs.rs b/implementations/rust/preserves-schema/src/bin/preserves-schema-rs.rs index f2862e7..8d7d9fd 100644 --- a/implementations/rust/preserves-schema/src/bin/preserves-schema-rs.rs +++ b/implementations/rust/preserves-schema/src/bin/preserves-schema-rs.rs @@ -35,11 +35,7 @@ fn main() -> Result<(), Error> { (pieces[0], pieces[1]) }; let modulepath: Vec = modulepath_str.split('.').map(str::to_owned).collect(); - config.add_external_module(ExternalModule { - path: modulepath, - rust_namespace: target.to_owned(), - rust_language_type: None, - }); + config.add_external_module(ExternalModule::new(modulepath, target)); } if let Some(c) = args.support_crate { config.support_crate = c; diff --git a/implementations/rust/preserves-schema/src/compiler/context.rs b/implementations/rust/preserves-schema/src/compiler/context.rs index bdf84f7..c4c191b 100644 --- a/implementations/rust/preserves-schema/src/compiler/context.rs +++ b/implementations/rust/preserves-schema/src/compiler/context.rs @@ -78,6 +78,10 @@ impl<'b> BundleContext<'b> { } } + pub fn any_type(&self) -> &'static str { + "_Value" + } + pub fn type_for_name(&self, r: &Ref) -> Option<&types::TDefinition> { if r.module.0.is_empty() { panic!("BundleContext::type_for_name with module-relative ref {:?}", r); @@ -99,7 +103,9 @@ impl<'b> BundleContext<'b> { _ => prefix }; let next_id = next_id.to_case(Case::UpperSnake); - format!("&_ctxt.into().{}", self.literals.entry(v.clone()).or_insert(next_id)) + format!("&<_L as Into<&'a {}>>::into(_ctxt).{}", + self.language_type(), + self.literals.entry(v.clone()).or_insert(next_id)) } pub fn generate_module( @@ -118,6 +124,16 @@ impl<'b> BundleContext<'b> { pub fn language_struct_name(&self) -> &'static str { "Language" } + + pub fn language_type_base(&self) -> String { + format!("{}::{}", + self.config.fully_qualified_module_prefix.clone(), + self.language_struct_name()) + } + + pub fn language_type(&self) -> String { + format!("{}<{}>", self.language_type_base(), self.any_type()) + } } impl<'m, 'b> ModuleContext<'m, 'b> { @@ -137,6 +153,10 @@ impl<'m, 'b> ModuleContext<'m, 'b> { } } + pub fn any_type(&self) -> &'static str { + self.bundle.any_type() + } + pub fn reset_mode(&mut self) { self.mode = ModuleContextMode::TargetToplevel; } @@ -178,21 +198,20 @@ impl<'m, 'b> ModuleContext<'m, 'b> { } } - pub fn any_type(&self) -> &'static str { - "_Value" - } - pub fn ref_has_embedded(&self, r: &Ref) -> bool { let r = r.qualify(&self.module_path); self.bundle.type_for_name(&r).map(|ty| ty.has_embedded(self.bundle)).unwrap_or(false) // ^ TODO: should the "false" be configurable? } - pub fn language_type(&self) -> Item { - item(seq![self.bundle.config.fully_qualified_module_prefix.clone(), - "::", - self.bundle.language_struct_name(), - anglebrackets![self.any_type()]]) + pub fn parse_unparse_generic_decls(&self, ty: &types::TDefinition) -> Item { + let mut lts = ty.language_types(self.bundle); + lts.insert(self.bundle.language_type()); + item(anglebrackets![ + "'a", + seq!["_L: Copy", + seq(lts.into_iter().map(|t| item(seq![" + Into<&'a ", t, ">"])).collect())], + seq![self.any_type(), ": preserves::value::NestedValue + 'a"]]) } pub fn extract(&mut self) -> Vec { diff --git a/implementations/rust/preserves-schema/src/compiler/mod.rs b/implementations/rust/preserves-schema/src/compiler/mod.rs index 1d4807c..27ad08f 100644 --- a/implementations/rust/preserves-schema/src/compiler/mod.rs +++ b/implementations/rust/preserves-schema/src/compiler/mod.rs @@ -17,6 +17,7 @@ use glob::glob; use preserves::value::BinarySource; use preserves::value::IOBinarySource; use preserves::value::Map; +use preserves::value::Set; use preserves::value::Reader; use std::fs::DirBuilder; @@ -39,11 +40,58 @@ pub trait Plugin: std::fmt::Debug { ); } +pub struct LanguageTypes { + pub fallback: Option Set>>, + pub definitions: Map Set>>, +} + +impl std::fmt::Debug for LanguageTypes { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + f.debug_struct("LanguageTypes") + .field("fallback", &self.fallback.as_ref().map(|f| f("_"))) + .field("definitions", &self.definitions.iter().map( + |(k, f)| (k.clone(), f("_"))).collect::>>()) + .finish() + } +} + #[derive(Debug)] pub struct ExternalModule { pub path: ModulePath, pub rust_namespace: String, - pub rust_language_type: Option, + pub rust_language_types: LanguageTypes, +} + +impl ExternalModule { + pub fn new(path: ModulePath, rust_namespace: &str) -> Self { + ExternalModule { + path, + rust_namespace: rust_namespace.to_owned(), + rust_language_types: LanguageTypes { + fallback: None, + definitions: Map::new(), + }, + } + } + + pub fn set_fallback_language_types Set>( + mut self, + f: F, + ) -> Self { + self.rust_language_types.fallback = Some(Box::new(f)); + self + } + + pub fn set_definition_language_types Set>( + mut self, + d: &str, + f: F, + ) -> Self { + if self.rust_language_types.definitions.insert(d.to_owned(), Box::new(f)).is_some() { + panic!("Duplicate language types definition installed: {:?} {:?}", &self.path, d); + } + self + } } #[derive(Debug)] diff --git a/implementations/rust/preserves-schema/src/compiler/parsers.rs b/implementations/rust/preserves-schema/src/compiler/parsers.rs index 3d6113b..5c9419d 100644 --- a/implementations/rust/preserves-schema/src/compiler/parsers.rs +++ b/implementations/rust/preserves-schema/src/compiler/parsers.rs @@ -45,10 +45,7 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) { construct(&ctxt, ctorname, false, &pattern_type(pat), dest, &mut body); item(seq!["fn ", fname.clone(), - anglebrackets![ - "'a", - seq!["_L: Copy + Into<&'a ", ctxt.m.language_type(), ">"], - seq![ctxt.m.any_type(), ": preserves::value::NestedValue + 'a"]], + ctxt.m.parse_unparse_generic_decls(&ty), "(_ctxt: _L, value: &", ctxt.m.any_type(), ") -> ", "std::result::Result<", names::render_constructor(n), ty.generic_arg(ctxt.m), @@ -75,10 +72,7 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &Definition) { } item(seq!["impl", - anglebrackets![ - "'a", - seq!["_L: Copy + Into<&'a ", ctxt.m.language_type(), ">"], - seq![ctxt.m.any_type(), ": preserves::value::NestedValue + 'a"]], + ctxt.m.parse_unparse_generic_decls(&ty), " _support::Parse", anglebrackets!["_L", ctxt.m.any_type()], " for ", names::render_constructor(n), ty.generic_arg(ctxt.m), " ", codeblock![ diff --git a/implementations/rust/preserves-schema/src/compiler/types.rs b/implementations/rust/preserves-schema/src/compiler/types.rs index 5fcc89d..63d30df 100644 --- a/implementations/rust/preserves-schema/src/compiler/types.rs +++ b/implementations/rust/preserves-schema/src/compiler/types.rs @@ -191,6 +191,37 @@ pub fn field_type(p: &SimplePattern) -> TField { } } +struct WalkState<'a, 'b> { + ctxt: &'a BundleContext<'b>, + current_module_path: ModulePath, + seen: Set, +} + +impl<'a, 'b> WalkState<'a, 'b> { + fn cycle_check) -> R, Kf: FnOnce() -> R>( + &mut self, + r: &Ref, + ks: Ks, + kf: Kf, + ) -> R { + let r = r.qualify(&self.current_module_path); + if self.seen.contains(&r) { + kf() + } else { + self.seen.insert(r.clone()); + match self.ctxt.type_for_name(&r) { + Some(ty) => { + let saved = std::mem::replace(&mut self.current_module_path, ty.self_ref.module.clone()); + let result = ks(self, Some(ty)); + self.current_module_path = saved; + result + }, + None => ks(self, None), + } + } + } +} + impl TField { fn render(&self, ctxt: &ModuleContext, box_needed: bool) -> impl Emittable { match self { @@ -213,28 +244,39 @@ impl TField { } } - pub fn has_embedded(&self, default_module_path: &ModulePath, ctxt: &BundleContext, seen: &mut Set) -> bool { + fn language_types(&self, s: &mut WalkState, ts: &mut Set) { match self { - TField::Unit => false, - TField::Any => true, // at least potentially true - TField::Embedded => true, - TField::Array(f) => f.has_embedded(default_module_path, ctxt, seen), - TField::Set(f) => f.has_embedded(default_module_path, ctxt, seen), - TField::Map(k, v) => - k.has_embedded(default_module_path, ctxt, seen) || - v.has_embedded(default_module_path, ctxt, seen), - TField::Ref(r) => { - let r = r.qualify(default_module_path); - if seen.contains(&r) { - false - } else { - seen.insert(r.clone()); - ctxt.type_for_name(&r).map(|ty| ty._has_embedded(ctxt, seen)).unwrap_or(false) - // ^ TODO: should the "false" be configurable? - // cf. ModuleContext::ref_has_embedded. - } + TField::Unit | TField::Any | TField::Embedded | TField::Base(_) => (), + TField::Array(f) => f.language_types(s, ts), + TField::Set(f) => f.language_types(s, ts), + TField::Map(k, v) => { + k.language_types(s, ts); + v.language_types(s, ts); } - TField::Base(_) => false, + TField::Ref(r) => + s.cycle_check(r, |s,t| match t { + Some(ty) => ty._language_types(s, ts), + None => { + let xmts = &s.ctxt.config.external_modules.get(&r.module.0).unwrap() + .rust_language_types; + if let Some(f) = xmts.definitions.get(&r.name).or(xmts.fallback.as_ref()) { + ts.extend(f(s.ctxt.any_type())); + } + } + }, || ()), + } + } + + fn has_embedded(&self, s: &mut WalkState) -> bool { + match self { + TField::Unit | TField::Base(_) => false, + TField::Any | TField::Embedded => true, // at least potentially true + TField::Array(f) => f.has_embedded(s), + TField::Set(f) => f.has_embedded(s), + TField::Map(k, v) => k.has_embedded(s) || v.has_embedded(s), + TField::Ref(r) => + // v TODO: should the "false" be configurable? cf. ModuleContext::ref_has_embedded. + s.cycle_check(r, |s,t| t.map(|t| t._has_embedded(s)).unwrap_or(false), || false), } } } @@ -254,12 +296,17 @@ impl TSimple { }] } - pub fn has_embedded(&self, default_module_path: &ModulePath, ctxt: &BundleContext, seen: &mut Set) -> bool { + fn language_types(&self, s: &mut WalkState, ts: &mut Set) { match self { - TSimple::Field(f) => - f.has_embedded(default_module_path, ctxt, seen), - TSimple::Record(TRecord(fs)) => - fs.iter().any(|(_k, v)| v.has_embedded(default_module_path, ctxt, seen)), + TSimple::Field(f) => f.language_types(s, ts), + TSimple::Record(TRecord(fs)) => fs.iter().for_each(|(_k, v)| v.language_types(s, ts)), + } + } + + fn has_embedded(&self, s: &mut WalkState) -> bool { + match self { + TSimple::Field(f) => f.has_embedded(s), + TSimple::Record(TRecord(fs)) => fs.iter().any(|(_k, v)| v.has_embedded(s)), } } } @@ -309,16 +356,39 @@ impl TDefinition { }]) } - pub fn has_embedded(&self, ctxt: &BundleContext) -> bool { - self._has_embedded(ctxt, &mut Set::new()) + fn walk_state<'a, 'b>(&self, ctxt: &'a BundleContext<'b>) -> WalkState<'a, 'b> { + WalkState { + current_module_path: self.self_ref.module.clone(), + ctxt, + seen: Set::new(), + } } - fn _has_embedded(&self, ctxt: &BundleContext, seen: &mut Set) -> bool { + pub fn language_types(&self, ctxt: &BundleContext) -> Set { + let mut ts = Set::new(); + self._language_types(&mut self.walk_state(ctxt), &mut ts); + ts + } + + fn _language_types(&self, s: &mut WalkState, ts: &mut Set) { match &self.body { - TDefinitionBody::Union(entries) => - entries.iter().any(|(_k, v)| v.has_embedded(&self.self_ref.module, ctxt, seen)), - TDefinitionBody::Simple(t) => - t.has_embedded(&self.self_ref.module, ctxt, seen), + TDefinitionBody::Union(entries) => entries.iter().for_each(|(_k, v)| v.language_types(s, ts)), + TDefinitionBody::Simple(t) => t.language_types(s, ts), + } + } + + pub fn has_embedded(&self, ctxt: &BundleContext) -> bool { + self._has_embedded(&mut WalkState { + current_module_path: self.self_ref.module.clone(), + ctxt, + seen: Set::new(), + }) + } + + fn _has_embedded(&self, s: &mut WalkState) -> bool { + match &self.body { + TDefinitionBody::Union(entries) => entries.iter().any(|(_k, v)| v.has_embedded(s)), + TDefinitionBody::Simple(t) => t.has_embedded(s), } } } diff --git a/implementations/rust/preserves-schema/src/compiler/unparsers.rs b/implementations/rust/preserves-schema/src/compiler/unparsers.rs index 1bb4fca..eec1cb9 100644 --- a/implementations/rust/preserves-schema/src/compiler/unparsers.rs +++ b/implementations/rust/preserves-schema/src/compiler/unparsers.rs @@ -98,10 +98,7 @@ pub fn gen_definition_unparser(m: &mut ModuleContext, n: &str, d: &Definition) { } item(seq!["impl", - anglebrackets![ - "'a", - seq!["_L: Copy + Into<&'a ", ctxt.m.language_type(), ">"], - seq![ctxt.m.any_type(), ": preserves::value::NestedValue + 'a"]], + ctxt.m.parse_unparse_generic_decls(&ty), " _support::Unparse", anglebrackets!["_L", ctxt.m.any_type()], " for ", names::render_constructor(n), ty.generic_arg(ctxt.m), " ", codeblock![ diff --git a/implementations/rust/preserves-schema/src/gen/schema.rs b/implementations/rust/preserves-schema/src/gen/schema.rs index 4ca225e..b9c751e 100644 --- a/implementations/rust/preserves-schema/src/gen/schema.rs +++ b/implementations/rust/preserves-schema/src/gen/schema.rs @@ -126,7 +126,7 @@ fn parse_atom_kind_boolean< _L: Copy + Into<&'a crate::gen::Language<_Value>>, _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result { - if value != &_ctxt.into().LIT_0_BOOLEAN { return Err(_support::ParseError::conformance_error("schema.AtomKind::Boolean")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_0_BOOLEAN { return Err(_support::ParseError::conformance_error("schema.AtomKind::Boolean")); } let _tmp0 = (); Ok(AtomKind::Boolean) } @@ -136,7 +136,7 @@ fn parse_atom_kind_float< _L: Copy + Into<&'a crate::gen::Language<_Value>>, _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result { - if value != &_ctxt.into().LIT_1_FLOAT { return Err(_support::ParseError::conformance_error("schema.AtomKind::Float")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_1_FLOAT { return Err(_support::ParseError::conformance_error("schema.AtomKind::Float")); } let _tmp0 = (); Ok(AtomKind::Float) } @@ -146,7 +146,7 @@ fn parse_atom_kind_double< _L: Copy + Into<&'a crate::gen::Language<_Value>>, _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result { - if value != &_ctxt.into().LIT_2_DOUBLE { return Err(_support::ParseError::conformance_error("schema.AtomKind::Double")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_2_DOUBLE { return Err(_support::ParseError::conformance_error("schema.AtomKind::Double")); } let _tmp0 = (); Ok(AtomKind::Double) } @@ -156,7 +156,7 @@ fn parse_atom_kind_signed_integer< _L: Copy + Into<&'a crate::gen::Language<_Value>>, _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result { - if value != &_ctxt.into().LIT_3_SIGNED_INTEGER { return Err(_support::ParseError::conformance_error("schema.AtomKind::SignedInteger")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_3_SIGNED_INTEGER { return Err(_support::ParseError::conformance_error("schema.AtomKind::SignedInteger")); } let _tmp0 = (); Ok(AtomKind::SignedInteger) } @@ -166,7 +166,7 @@ fn parse_atom_kind_string< _L: Copy + Into<&'a crate::gen::Language<_Value>>, _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result { - if value != &_ctxt.into().LIT_4_STRING { return Err(_support::ParseError::conformance_error("schema.AtomKind::String")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_4_STRING { return Err(_support::ParseError::conformance_error("schema.AtomKind::String")); } let _tmp0 = (); Ok(AtomKind::String) } @@ -176,7 +176,7 @@ fn parse_atom_kind_byte_string< _L: Copy + Into<&'a crate::gen::Language<_Value>>, _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result { - if value != &_ctxt.into().LIT_5_BYTE_STRING { return Err(_support::ParseError::conformance_error("schema.AtomKind::ByteString")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_5_BYTE_STRING { return Err(_support::ParseError::conformance_error("schema.AtomKind::ByteString")); } let _tmp0 = (); Ok(AtomKind::ByteString) } @@ -186,7 +186,7 @@ fn parse_atom_kind_symbol< _L: Copy + Into<&'a crate::gen::Language<_Value>>, _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result { - if value != &_ctxt.into().LIT_6_SYMBOL { return Err(_support::ParseError::conformance_error("schema.AtomKind::Symbol")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_6_SYMBOL { return Err(_support::ParseError::conformance_error("schema.AtomKind::Symbol")); } let _tmp0 = (); Ok(AtomKind::Symbol) } @@ -215,13 +215,15 @@ impl< > _support::Unparse<_L, _Value> for AtomKind { fn unparse(&self, _ctxt: _L) -> _Value { match self { - AtomKind::Boolean => (&_ctxt.into().LIT_0_BOOLEAN).clone(), - AtomKind::Float => (&_ctxt.into().LIT_1_FLOAT).clone(), - AtomKind::Double => (&_ctxt.into().LIT_2_DOUBLE).clone(), - AtomKind::SignedInteger => (&_ctxt.into().LIT_3_SIGNED_INTEGER).clone(), - AtomKind::String => (&_ctxt.into().LIT_4_STRING).clone(), - AtomKind::ByteString => (&_ctxt.into().LIT_5_BYTE_STRING).clone(), - AtomKind::Symbol => (&_ctxt.into().LIT_6_SYMBOL).clone(), + AtomKind::Boolean => (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_0_BOOLEAN).clone(), + AtomKind::Float => (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_1_FLOAT).clone(), + AtomKind::Double => (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_2_DOUBLE).clone(), + AtomKind::SignedInteger => ( + &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_3_SIGNED_INTEGER + ).clone(), + AtomKind::String => (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_4_STRING).clone(), + AtomKind::ByteString => (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_5_BYTE_STRING).clone(), + AtomKind::Symbol => (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_6_SYMBOL).clone(), } } } @@ -266,7 +268,7 @@ impl< > _support::Parse<_L, _Value> for Binding<_Value> { fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_7_NAMED { return Err(_support::ParseError::conformance_error("schema.Binding")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_7_NAMED { return Err(_support::ParseError::conformance_error("schema.Binding")); } let _tmp1 = (); if _tmp0.fields().len() < 2 { return Err(_support::ParseError::conformance_error("schema.Binding")); } let _tmp2 = (&_tmp0.fields()[0]).value().to_symbol()?; @@ -283,7 +285,7 @@ impl< fn unparse(&self, _ctxt: _L) -> _Value { let Binding {name: _tmp0, pattern: _tmp1} = self; { - let mut _tmp2 = preserves::value::Record(vec![(&_ctxt.into().LIT_7_NAMED).clone()]); + let mut _tmp2 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_7_NAMED).clone()]); _tmp2.fields_vec_mut().push(preserves::value::Value::symbol(_tmp0).wrap()); _tmp2.fields_vec_mut().push(_tmp1.unparse(_ctxt)); _tmp2.finish().wrap() @@ -327,7 +329,7 @@ impl< > _support::Parse<_L, _Value> for Bundle<_Value> { fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_8_BUNDLE { return Err(_support::ParseError::conformance_error("schema.Bundle")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_8_BUNDLE { return Err(_support::ParseError::conformance_error("schema.Bundle")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.Bundle")); } let _tmp2 = Modules::parse(_ctxt, (&_tmp0.fields()[0]))?; @@ -343,7 +345,7 @@ impl< fn unparse(&self, _ctxt: _L) -> _Value { let Bundle {modules: _tmp0} = self; { - let mut _tmp1 = preserves::value::Record(vec![(&_ctxt.into().LIT_8_BUNDLE).clone()]); + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_8_BUNDLE).clone()]); _tmp1.fields_vec_mut().push(_tmp0.unparse(_ctxt)); _tmp1.finish().wrap() } @@ -491,7 +493,7 @@ fn parse_compound_pattern_rec< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_9_REC { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::rec")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_9_REC { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::rec")); } let _tmp1 = (); if _tmp0.fields().len() < 2 { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::rec")); } let _tmp2 = NamedPattern::parse(_ctxt, (&_tmp0.fields()[0]))?; @@ -505,7 +507,7 @@ fn parse_compound_pattern_tuple< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_10_TUPLE { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::tuple")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_10_TUPLE { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::tuple")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::tuple")); } let _tmp3 = (&_tmp0.fields()[0]).value().to_sequence()?; @@ -523,7 +525,7 @@ fn parse_compound_pattern_tuple_prefix< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_11_TUPLE_PREFIX { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::tuplePrefix")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_11_TUPLE_PREFIX { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::tuplePrefix")); } let _tmp1 = (); if _tmp0.fields().len() < 2 { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::tuplePrefix")); } let _tmp3 = (&_tmp0.fields()[0]).value().to_sequence()?; @@ -542,7 +544,7 @@ fn parse_compound_pattern_dict< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_12_DICT { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::dict")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_12_DICT { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::dict")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.CompoundPattern::dict")); } let _tmp2 = DictionaryEntries::parse(_ctxt, (&_tmp0.fields()[0]))?; @@ -571,13 +573,13 @@ impl< fn unparse(&self, _ctxt: _L) -> _Value { match self { CompoundPattern::Rec {label: _tmp0, fields: _tmp1} => { - let mut _tmp2 = preserves::value::Record(vec![(&_ctxt.into().LIT_9_REC).clone()]); + let mut _tmp2 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_9_REC).clone()]); _tmp2.fields_vec_mut().push(_tmp0.as_ref().unparse(_ctxt)); _tmp2.fields_vec_mut().push(_tmp1.as_ref().unparse(_ctxt)); _tmp2.finish().wrap() }, CompoundPattern::Tuple {patterns: _tmp0} => { - let mut _tmp1 = preserves::value::Record(vec![(&_ctxt.into().LIT_10_TUPLE).clone()]); + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_10_TUPLE).clone()]); _tmp1.fields_vec_mut().push( { let mut _tmp2 = std::vec::Vec::new(); @@ -590,7 +592,9 @@ impl< _tmp1.finish().wrap() }, CompoundPattern::TuplePrefix {fixed: _tmp0, variable: _tmp1} => { - let mut _tmp2 = preserves::value::Record(vec![(&_ctxt.into().LIT_11_TUPLE_PREFIX).clone()]); + let mut _tmp2 = preserves::value::Record(vec![( + &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_11_TUPLE_PREFIX + ).clone()]); _tmp2.fields_vec_mut().push( { let mut _tmp3 = std::vec::Vec::new(); @@ -604,7 +608,7 @@ impl< _tmp2.finish().wrap() }, CompoundPattern::Dict {entries: _tmp0} => { - let mut _tmp1 = preserves::value::Record(vec![(&_ctxt.into().LIT_12_DICT).clone()]); + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_12_DICT).clone()]); _tmp1.fields_vec_mut().push(_tmp0.as_ref().unparse(_ctxt)); _tmp1.finish().wrap() }, @@ -728,7 +732,7 @@ fn parse_definition_or< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_13_OR { return Err(_support::ParseError::conformance_error("schema.Definition::or")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_13_OR { return Err(_support::ParseError::conformance_error("schema.Definition::or")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.Definition::or")); } let _tmp2 = (&_tmp0.fields()[0]).value().to_sequence()?; @@ -753,7 +757,7 @@ fn parse_definition_and< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_14_AND { return Err(_support::ParseError::conformance_error("schema.Definition::and")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_14_AND { return Err(_support::ParseError::conformance_error("schema.Definition::and")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.Definition::and")); } let _tmp2 = (&_tmp0.fields()[0]).value().to_sequence()?; @@ -802,7 +806,7 @@ impl< fn unparse(&self, _ctxt: _L) -> _Value { match self { Definition::Or {pattern_0: _tmp0, pattern_1: _tmp1, pattern_n: _tmp2} => { - let mut _tmp3 = preserves::value::Record(vec![(&_ctxt.into().LIT_13_OR).clone()]); + let mut _tmp3 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_13_OR).clone()]); _tmp3.fields_vec_mut().push( { let mut _tmp4 = std::vec::Vec::new(); @@ -817,7 +821,7 @@ impl< _tmp3.finish().wrap() }, Definition::And {pattern_0: _tmp0, pattern_1: _tmp1, pattern_n: _tmp2} => { - let mut _tmp3 = preserves::value::Record(vec![(&_ctxt.into().LIT_14_AND).clone()]); + let mut _tmp3 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_14_AND).clone()]); _tmp3.fields_vec_mut().push( { let mut _tmp4 = std::vec::Vec::new(); @@ -986,7 +990,7 @@ fn parse_embedded_type_name_false< _L: Copy + Into<&'a crate::gen::Language<_Value>>, _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result { - if value != &_ctxt.into().LIT_15_FALSE { return Err(_support::ParseError::conformance_error("schema.EmbeddedTypeName::false")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_15_FALSE { return Err(_support::ParseError::conformance_error("schema.EmbeddedTypeName::false")); } let _tmp0 = (); Ok(EmbeddedTypeName::False) } @@ -1011,7 +1015,7 @@ impl< fn unparse(&self, _ctxt: _L) -> _Value { match self { EmbeddedTypeName::Ref(_tmp0) => _tmp0.as_ref().unparse(_ctxt), - EmbeddedTypeName::False => (&_ctxt.into().LIT_15_FALSE).clone(), + EmbeddedTypeName::False => (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_15_FALSE).clone(), } } } @@ -1424,7 +1428,7 @@ impl< > _support::Parse<_L, _Value> for Ref { fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_16_REF { return Err(_support::ParseError::conformance_error("schema.Ref")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_16_REF { return Err(_support::ParseError::conformance_error("schema.Ref")); } let _tmp1 = (); if _tmp0.fields().len() < 2 { return Err(_support::ParseError::conformance_error("schema.Ref")); } let _tmp2 = ModulePath::parse(_ctxt, (&_tmp0.fields()[0]))?; @@ -1441,7 +1445,7 @@ impl< fn unparse(&self, _ctxt: _L) -> _Value { let Ref {module: _tmp0, name: _tmp1} = self; { - let mut _tmp2 = preserves::value::Record(vec![(&_ctxt.into().LIT_16_REF).clone()]); + let mut _tmp2 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_16_REF).clone()]); _tmp2.fields_vec_mut().push(_tmp0.unparse(_ctxt)); _tmp2.fields_vec_mut().push(preserves::value::Value::symbol(_tmp1).wrap()); _tmp2.finish().wrap() @@ -1523,15 +1527,19 @@ impl< > _support::Parse<_L, _Value> for Schema<_Value> { fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_17_SCHEMA { return Err(_support::ParseError::conformance_error("schema.Schema")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_17_SCHEMA { return Err(_support::ParseError::conformance_error("schema.Schema")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.Schema")); } let _tmp2 = (&_tmp0.fields()[0]).value().to_dictionary()?; - let _tmp3 = _tmp2.get(&_ctxt.into().LIT_18_DEFINITIONS).ok_or_else(|| _support::ParseError::conformance_error("schema.Schema"))?; + let _tmp3 = _tmp2.get( + &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_18_DEFINITIONS + ).ok_or_else(|| _support::ParseError::conformance_error("schema.Schema"))?; let _tmp4 = Definitions::parse(_ctxt, _tmp3)?; - let _tmp5 = _tmp2.get(&_ctxt.into().LIT_19_EMBEDDED_TYPE).ok_or_else(|| _support::ParseError::conformance_error("schema.Schema"))?; + let _tmp5 = _tmp2.get( + &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_19_EMBEDDED_TYPE + ).ok_or_else(|| _support::ParseError::conformance_error("schema.Schema"))?; let _tmp6 = EmbeddedTypeName::parse(_ctxt, _tmp5)?; - let _tmp7 = _tmp2.get(&_ctxt.into().LIT_20_VERSION).ok_or_else(|| _support::ParseError::conformance_error("schema.Schema"))?; + let _tmp7 = _tmp2.get(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_20_VERSION).ok_or_else(|| _support::ParseError::conformance_error("schema.Schema"))?; let _tmp8 = Version::parse(_ctxt, _tmp7)?; Ok(Schema {definitions: _tmp4, embedded_type: _tmp6, version: _tmp8}) } @@ -1545,13 +1553,26 @@ impl< fn unparse(&self, _ctxt: _L) -> _Value { let Schema {definitions: _tmp0, embedded_type: _tmp1, version: _tmp2} = self; { - let mut _tmp3 = preserves::value::Record(vec![(&_ctxt.into().LIT_17_SCHEMA).clone()]); + let mut _tmp3 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_17_SCHEMA).clone()]); _tmp3.fields_vec_mut().push( { let mut _tmp4 = preserves::value::Map::new(); - _tmp4.insert((&_ctxt.into().LIT_18_DEFINITIONS).clone(), _tmp0.unparse(_ctxt)); - _tmp4.insert((&_ctxt.into().LIT_19_EMBEDDED_TYPE).clone(), _tmp1.unparse(_ctxt)); - _tmp4.insert((&_ctxt.into().LIT_20_VERSION).clone(), _tmp2.unparse(_ctxt)); + _tmp4.insert( + ( + &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_18_DEFINITIONS + ).clone(), + _tmp0.unparse(_ctxt) + ); + _tmp4.insert( + ( + &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_19_EMBEDDED_TYPE + ).clone(), + _tmp1.unparse(_ctxt) + ); + _tmp4.insert( + (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_20_VERSION).clone(), + _tmp2.unparse(_ctxt) + ); preserves::value::Value::Dictionary(_tmp4).wrap() } ); @@ -1747,7 +1768,7 @@ fn parse_simple_pattern_any< _L: Copy + Into<&'a crate::gen::Language<_Value>>, _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { - if value != &_ctxt.into().LIT_21_ANY { return Err(_support::ParseError::conformance_error("schema.SimplePattern::any")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_21_ANY { return Err(_support::ParseError::conformance_error("schema.SimplePattern::any")); } let _tmp0 = (); Ok(SimplePattern::Any) } @@ -1758,7 +1779,7 @@ fn parse_simple_pattern_atom< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_22_ATOM { return Err(_support::ParseError::conformance_error("schema.SimplePattern::atom")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_22_ATOM { return Err(_support::ParseError::conformance_error("schema.SimplePattern::atom")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.SimplePattern::atom")); } let _tmp2 = AtomKind::parse(_ctxt, (&_tmp0.fields()[0]))?; @@ -1771,7 +1792,7 @@ fn parse_simple_pattern_embedded< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_23_EMBEDDED { return Err(_support::ParseError::conformance_error("schema.SimplePattern::embedded")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_23_EMBEDDED { return Err(_support::ParseError::conformance_error("schema.SimplePattern::embedded")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.SimplePattern::embedded")); } let _tmp2 = SimplePattern::parse(_ctxt, (&_tmp0.fields()[0]))?; @@ -1784,7 +1805,7 @@ fn parse_simple_pattern_lit< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_24_LIT { return Err(_support::ParseError::conformance_error("schema.SimplePattern::lit")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_24_LIT { return Err(_support::ParseError::conformance_error("schema.SimplePattern::lit")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.SimplePattern::lit")); } let _tmp2 = (&_tmp0.fields()[0]); @@ -1797,7 +1818,7 @@ fn parse_simple_pattern_seqof< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_25_SEQOF { return Err(_support::ParseError::conformance_error("schema.SimplePattern::seqof")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_25_SEQOF { return Err(_support::ParseError::conformance_error("schema.SimplePattern::seqof")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.SimplePattern::seqof")); } let _tmp2 = SimplePattern::parse(_ctxt, (&_tmp0.fields()[0]))?; @@ -1810,7 +1831,7 @@ fn parse_simple_pattern_setof< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_26_SETOF { return Err(_support::ParseError::conformance_error("schema.SimplePattern::setof")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_26_SETOF { return Err(_support::ParseError::conformance_error("schema.SimplePattern::setof")); } let _tmp1 = (); if _tmp0.fields().len() < 1 { return Err(_support::ParseError::conformance_error("schema.SimplePattern::setof")); } let _tmp2 = SimplePattern::parse(_ctxt, (&_tmp0.fields()[0]))?; @@ -1823,7 +1844,7 @@ fn parse_simple_pattern_dictof< _Value: preserves::value::NestedValue + 'a >(_ctxt: _L, value: &_Value) -> std::result::Result, _support::ParseError> { let _tmp0 = value.value().to_record(None)?; - if _tmp0.label() != &_ctxt.into().LIT_27_DICTOF { return Err(_support::ParseError::conformance_error("schema.SimplePattern::dictof")); } + if _tmp0.label() != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_27_DICTOF { return Err(_support::ParseError::conformance_error("schema.SimplePattern::dictof")); } let _tmp1 = (); if _tmp0.fields().len() < 2 { return Err(_support::ParseError::conformance_error("schema.SimplePattern::dictof")); } let _tmp2 = SimplePattern::parse(_ctxt, (&_tmp0.fields()[0]))?; @@ -1865,34 +1886,34 @@ impl< > _support::Unparse<_L, _Value> for SimplePattern<_Value> { fn unparse(&self, _ctxt: _L) -> _Value { match self { - SimplePattern::Any => (&_ctxt.into().LIT_21_ANY).clone(), + SimplePattern::Any => (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_21_ANY).clone(), SimplePattern::Atom {atom_kind: _tmp0} => { - let mut _tmp1 = preserves::value::Record(vec![(&_ctxt.into().LIT_22_ATOM).clone()]); + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_22_ATOM).clone()]); _tmp1.fields_vec_mut().push(_tmp0.as_ref().unparse(_ctxt)); _tmp1.finish().wrap() }, SimplePattern::Embedded {interface: _tmp0} => { - let mut _tmp1 = preserves::value::Record(vec![(&_ctxt.into().LIT_23_EMBEDDED).clone()]); + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_23_EMBEDDED).clone()]); _tmp1.fields_vec_mut().push(_tmp0.as_ref().unparse(_ctxt)); _tmp1.finish().wrap() }, SimplePattern::Lit {value: _tmp0} => { - let mut _tmp1 = preserves::value::Record(vec![(&_ctxt.into().LIT_24_LIT).clone()]); + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_24_LIT).clone()]); _tmp1.fields_vec_mut().push(_tmp0.clone()); _tmp1.finish().wrap() }, SimplePattern::Seqof {pattern: _tmp0} => { - let mut _tmp1 = preserves::value::Record(vec![(&_ctxt.into().LIT_25_SEQOF).clone()]); + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_25_SEQOF).clone()]); _tmp1.fields_vec_mut().push(_tmp0.as_ref().unparse(_ctxt)); _tmp1.finish().wrap() }, SimplePattern::Setof {pattern: _tmp0} => { - let mut _tmp1 = preserves::value::Record(vec![(&_ctxt.into().LIT_26_SETOF).clone()]); + let mut _tmp1 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_26_SETOF).clone()]); _tmp1.fields_vec_mut().push(_tmp0.as_ref().unparse(_ctxt)); _tmp1.finish().wrap() }, SimplePattern::Dictof {key: _tmp0, value: _tmp1} => { - let mut _tmp2 = preserves::value::Record(vec![(&_ctxt.into().LIT_27_DICTOF).clone()]); + let mut _tmp2 = preserves::value::Record(vec![(&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_27_DICTOF).clone()]); _tmp2.fields_vec_mut().push(_tmp0.as_ref().unparse(_ctxt)); _tmp2.fields_vec_mut().push(_tmp1.as_ref().unparse(_ctxt)); _tmp2.finish().wrap() @@ -1927,7 +1948,7 @@ impl< _Value: preserves::value::NestedValue + 'a > _support::Parse<_L, _Value> for Version { fn parse(_ctxt: _L, value: &_Value) -> std::result::Result { - if value != &_ctxt.into().LIT_28_1 { return Err(_support::ParseError::conformance_error("schema.Version")); } + if value != &<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_28_1 { return Err(_support::ParseError::conformance_error("schema.Version")); } let _tmp0 = (); Ok(Version) } @@ -1940,6 +1961,6 @@ impl< > _support::Unparse<_L, _Value> for Version { fn unparse(&self, _ctxt: _L) -> _Value { let Version = self; - (&_ctxt.into().LIT_28_1).clone() + (&<_L as Into<&'a crate::gen::Language<_Value>>>::into(_ctxt).LIT_28_1).clone() } } diff --git a/implementations/rust/preserves-schema/src/lib.rs b/implementations/rust/preserves-schema/src/lib.rs index 8ff2948..ec34461 100644 --- a/implementations/rust/preserves-schema/src/lib.rs +++ b/implementations/rust/preserves-schema/src/lib.rs @@ -50,3 +50,31 @@ mod tests { Ok(()) } } + +#[macro_export] +macro_rules! define_language { + ($fname:ident () : $lang:ident < $default_value:ty > { $($field:ident : $($type:ident)::+ ,)* }) => { + pub struct $lang { + $(pub $field: std::sync::Arc<$($type)::*>),* + } + + $(impl<'a, N: $crate::support::preserves::value::NestedValue> From<&'a $lang> for &'a $($type)::* { + fn from(v: &'a $lang) -> Self { + &v.$field + } + })* + + mod $fname { + use super::*; + lazy_static::lazy_static! { + pub static ref GLOBAL_LANG: $lang<$default_value> = $lang { + $($field: std::sync::Arc::new($($type)::*::default())),* + }; + } + } + + pub fn $fname() -> &'static $lang<$default_value> { + &*$fname::GLOBAL_LANG + } + }; +}