deimos-lang/ast-generator/src/spec/struct_spec.rs

222 lines
4.1 KiB
Rust

pub struct StructSpec {
build: String,
children: Vec<Box<StructChild>>,
}
impl StructSpec {
pub fn new(build: &str, children: Vec<Box<StructChild>>) -> 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<Item = &StructChild> {
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<VecChildBuild>,
}
impl VecChild {
pub fn new(name: &str, rule: &str, build: Box<VecChildBuild>) -> 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<MemberChildBuild>,
}
impl MemberChild {
pub fn new(name: &str, rule: &str, optional: bool, build: Box<MemberChildBuild>) -> 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<String>,
}
impl NodeMemberBuild {
pub fn new(kind: &str, with: &str, or_else: Option<String>) -> 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,
}