use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
use core::ops::Deref;
use crate::util::{AddOnlyVec, RefCounted};
use crate::{Build, Pool, Rule, Variable};
#[derive(Debug)]
pub enum Stmt {
Comment(String),
Rule(Rule),
Build(Box<Build>),
Variable(Variable),
Default(Vec<String>),
Subninja(String),
Include(String),
Pool(Pool),
}
impl Stmt {
pub fn ordinal(&self) -> usize {
match self {
Self::Comment(_) => 0,
Self::Rule(_) => 1,
Self::Build(_) => 2,
Self::Variable(_) => 3,
Self::Default(_) => 4,
Self::Subninja(_) => 5,
Self::Include(_) => 6,
Self::Pool(_) => 7,
}
}
pub fn is_same_type(&self, other: &Self) -> bool {
self.ordinal() == other.ordinal()
}
}
#[derive(Debug)]
pub struct StmtRef {
pub(crate) list: RefCounted<AddOnlyVec<RefCounted<Stmt>>>,
pub(crate) stmt: RefCounted<Stmt>,
}
impl StmtRef {
pub fn add(&self, stmt: Stmt) -> StmtRef {
StmtRef {
stmt: self.list.add_rc(stmt),
list: RefCounted::clone(&self.list),
}
}
}
impl Clone for StmtRef {
fn clone(&self) -> Self {
Self {
list: RefCounted::clone(&self.list),
stmt: RefCounted::clone(&self.stmt),
}
}
}
impl Deref for StmtRef {
type Target = RefCounted<Stmt>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.stmt
}
}
impl AsRef<Stmt> for StmtRef {
#[inline]
fn as_ref(&self) -> &Stmt {
self.deref()
}
}