use espr::{ast::SyntaxTree, codegen::rust::*, ir::IR}; const EXPRESS: &str = r#" SCHEMA test_schema; ENTITY base SUPERTYPE OF (ONEOF (sub)); x: REAL; END_ENTITY; ENTITY sub SUPERTYPE OF (subsub) SUBTYPE OF (base); y: REAL; END_ENTITY; ENTITY subsub SUBTYPE OF (sub); z: REAL; END_ENTITY; END_SCHEMA; "#; #[test] fn subsuper() { let st = SyntaxTree::parse(EXPRESS).unwrap(); let ir = IR::from_syntax_tree(&st).unwrap(); let tt = ir.to_token_stream(CratePrefix::External).to_string(); let tt = rustfmt(tt); insta::assert_snapshot!(tt, @r###" pub mod test_schema { use ruststep::{as_holder, derive_more::*, primitive::*, Holder, TableInit}; use std::collections::HashMap; #[derive(Debug, Clone, PartialEq, Default, TableInit)] pub struct Tables { base: HashMap, sub: HashMap, subsub: HashMap, } impl Tables { pub fn base_holders(&self) -> &HashMap { &self.base } pub fn sub_holders(&self) -> &HashMap { &self.sub } pub fn subsub_holders(&self) -> &HashMap { &self.subsub } } #[derive(Debug, Clone, PartialEq, :: derive_new :: new, Holder)] # [holder (table = Tables)] # [holder (field = base)] #[holder(generate_deserialize)] pub struct Base { pub x: f64, } #[derive(Debug, Clone, PartialEq, Holder)] # [holder (table = Tables)] #[holder(generate_deserialize)] pub enum BaseAny { #[holder(use_place_holder)] Base(Box), #[holder(use_place_holder)] Sub(Box), } impl Into for Base { fn into(self) -> BaseAny { BaseAny::Base(Box::new(self)) } } impl Into for Sub { fn into(self) -> BaseAny { BaseAny::Sub(Box::new(self.into())) } } impl AsRef for BaseAny { fn as_ref(&self) -> &Base { match self { BaseAny::Base(x) => x.as_ref(), BaseAny::Sub(x) => (**x).as_ref(), } } } #[derive( Debug, Clone, PartialEq, :: derive_new :: new, Holder, AsRef, AsMut, Deref, DerefMut, )] # [holder (table = Tables)] # [holder (field = sub)] #[holder(generate_deserialize)] pub struct Sub { #[as_ref] #[as_mut] #[deref] #[deref_mut] #[holder(use_place_holder)] pub base: Base, pub y: f64, } #[derive(Debug, Clone, PartialEq, Holder)] # [holder (table = Tables)] #[holder(generate_deserialize)] pub enum SubAny { #[holder(use_place_holder)] Sub(Box), #[holder(use_place_holder)] Subsub(Box), } impl Into for Sub { fn into(self) -> SubAny { SubAny::Sub(Box::new(self)) } } impl Into for Subsub { fn into(self) -> SubAny { SubAny::Subsub(Box::new(self.into())) } } impl AsRef for SubAny { fn as_ref(&self) -> &Sub { match self { SubAny::Sub(x) => x.as_ref(), SubAny::Subsub(x) => (**x).as_ref(), } } } impl AsRef for SubAny { fn as_ref(&self) -> &Base { match self { SubAny::Sub(x) => AsRef::::as_ref(x).as_ref(), SubAny::Subsub(x) => AsRef::::as_ref(x.as_ref()).as_ref(), } } } #[derive( Debug, Clone, PartialEq, :: derive_new :: new, Holder, AsRef, AsMut, Deref, DerefMut, )] # [holder (table = Tables)] # [holder (field = subsub)] #[holder(generate_deserialize)] pub struct Subsub { #[as_ref] #[as_mut] #[deref] #[deref_mut] #[holder(use_place_holder)] pub sub: Sub, pub z: f64, } } "###); }