pub struct StructSpec { build: String, children: Vec>, } impl StructSpec { pub fn new(build: &str, children: Vec>) -> Self { Self { build: build.to_string(), children, } } /// The type to be built, in Pascal case. pub fn build(&self) -> &str { &self.build } /// The children for this build spec. pub fn children(&self) -> impl Iterator { self.children.iter().map(Box::as_ref) } } pub enum StructChild { SkipChild(SkipChild), VecChild(VecChild), MemberChild(MemberChild), } pub struct SkipChild { rule: String, } impl SkipChild { pub fn new(rule: &str) -> Self { Self { rule: rule.to_string(), } } /// The grammar rule to match. pub fn rule(&self) -> &str { &self.rule } } pub struct VecChild { name: String, rule: String, build: Box, } impl VecChild { pub fn new(name: &str, rule: &str, build: Box) -> Self { Self { name: name.to_string(), rule: rule.to_string(), build, } } /// The name of this child. pub fn name(&self) -> &str { &self.name } /// The rule to match to build this child. pub fn rule(&self) -> &str { &self.rule } pub fn build(&self) -> &VecChildBuild { &self.build } } pub enum VecChildBuild { String(VecChildStringBuild), Node(VecChildNodeBuild), } pub struct VecChildStringBuild { with: String, } impl VecChildStringBuild { pub fn new(with: &str) -> Self { Self { with: with.to_string(), } } pub fn with(&self) -> &str { &self.with } } pub struct VecChildNodeBuild { kind: String, with: String, } impl VecChildNodeBuild { pub fn new(kind: &str, with: &str) -> Self { Self { kind: kind.to_string(), with: with.to_string(), } } pub fn kind(&self) -> &str { &self.kind } pub fn with(&self) -> &str { &self.with } } #[derive(Debug)] pub struct MemberChild { name: String, rule: String, optional: bool, build: Box, } impl MemberChild { pub fn new(name: &str, rule: &str, optional: bool, build: Box) -> Self { Self { name: name.to_string(), rule: rule.to_string(), optional, build, } } /// The name of this child in the yaml file, in snake case. pub fn name(&self) -> &str { &self.name } /// The grammar rule to match to build this child. pub fn rule(&self) -> &str { &self.rule } pub fn optional(&self) -> bool { self.optional } /// The specification for what to actually build. pub fn build(&self) -> &MemberChildBuild { &self.build } } #[derive(Debug)] pub enum MemberChildBuild { Node(NodeMemberBuild), Boolean(BooleanMemberBuild), Special(SpecialMemberBuild), } #[derive(Debug)] pub struct NodeMemberBuild { kind: String, with: String, or_else: Option, } impl NodeMemberBuild { pub fn new(kind: &str, with: &str, or_else: Option) -> Self { Self { kind: kind.to_string(), with: with.to_string(), or_else, } } /// The type to build, in Pascal case. pub fn kind(&self) -> &str { &self.kind } pub fn with(&self) -> &str { &self.with } /// The default fn to call when unwrapping the child (before passing as arg to new). pub fn or_else(&self) -> Option<&str> { self.or_else.as_deref() } } #[derive(Debug)] pub struct BooleanMemberBuild { on: BooleanMemberBuildOn, } impl BooleanMemberBuild { pub fn new(on: BooleanMemberBuildOn) -> Self { Self { on } } pub fn on(&self) -> &BooleanMemberBuildOn { &self.on } } #[derive(Debug)] pub enum BooleanMemberBuildOn { RulePresent, } #[derive(Debug)] pub enum SpecialMemberBuild { FileId, Range, }