use alloc::string::String;
use core::fmt::{Display, Formatter, Result};
use core::ops::Deref;
use crate::stmt::{Stmt, StmtRef};
use crate::util::{AddOnlyVec, Indented};
use crate::{Ninja, ToArg, Variable, Variables};
#[derive(Debug)]
pub struct Pool {
pub name: String,
pub variables: AddOnlyVec<Variable>,
}
#[derive(Debug, Clone)]
pub struct PoolRef(pub(crate) StmtRef);
impl Deref for PoolRef {
type Target = Pool;
fn deref(&self) -> &Self::Target {
match self.0.deref().deref() {
Stmt::Pool(p) => p,
_ => unreachable!(),
}
}
}
impl AsRef<Pool> for PoolRef {
fn as_ref(&self) -> &Pool {
self.deref()
}
}
impl Pool {
pub fn new(name: impl ToArg, depth: usize) -> Self {
let x = Self {
name: name.to_arg(),
variables: AddOnlyVec::new(),
};
x.variable("depth", depth)
}
#[inline]
pub fn add_to(self, ninja: &Ninja) -> PoolRef {
PoolRef(ninja.add_stmt(Stmt::Pool(self)))
}
}
impl Variables for Pool {
fn add_variable_internal(&self, v: Variable) {
self.variables.add(v);
}
}
impl Variables for PoolRef {
fn add_variable_internal(&self, v: Variable) {
self.deref().add_variable_internal(v);
}
}
impl Display for Pool {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
writeln!(f, "pool {}", self.name)?;
for variable in self.variables.inner().iter() {
Indented(variable).fmt(f)?;
writeln!(f)?;
}
Ok(())
}
}
#[cfg(test)]
mod test {
use super::*;
use alloc::string::ToString;
#[test]
fn test_default() {
let pool = Pool::new("foo", 1);
assert_eq!(pool.to_string(), "pool foo\n depth = 1\n");
}
#[test]
fn test_variable() {
let pool = Pool::new("foo", 42).variable("foov", "z");
assert_eq!(pool.to_string(), "pool foo\n depth = 42\n foov = z\n");
}
}