1use alloc::string::String;
4use core::fmt::{Display, Formatter, Result};
5use core::ops::Deref;
6
7use crate::stmt::{Stmt, StmtRef};
8use crate::util::{AddOnlyVec, Indented};
9use crate::{Ninja, ToArg, Variable, Variables};
10
11#[derive(Debug)]
36pub struct Pool {
37 pub name: String,
39 pub variables: AddOnlyVec<Variable>,
43}
44
45#[derive(Debug, Clone)]
47pub struct PoolRef(pub(crate) StmtRef);
48
49impl Deref for PoolRef {
50 type Target = Pool;
51 fn deref(&self) -> &Self::Target {
52 match self.0.deref().deref() {
53 Stmt::Pool(p) => p,
54 _ => unreachable!(),
56 }
57 }
58}
59
60impl AsRef<Pool> for PoolRef {
61 fn as_ref(&self) -> &Pool {
62 self.deref()
63 }
64}
65
66impl Pool {
67 pub fn new(name: impl ToArg, depth: usize) -> Self {
69 let x = Self {
70 name: name.to_arg(),
71 variables: AddOnlyVec::new(),
72 };
73 x.variable("depth", depth)
74 }
75
76 #[inline]
78 pub fn add_to(self, ninja: &Ninja) -> PoolRef {
79 PoolRef(ninja.add_stmt(Stmt::Pool(self)))
80 }
81}
82
83impl Variables for Pool {
84 fn add_variable_internal(&self, v: Variable) {
85 self.variables.add(v);
86 }
87}
88
89impl Variables for PoolRef {
90 fn add_variable_internal(&self, v: Variable) {
91 self.deref().add_variable_internal(v);
92 }
93}
94
95impl Display for Pool {
96 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
97 writeln!(f, "pool {}", self.name)?;
98 for variable in self.variables.inner().iter() {
99 Indented(variable).fmt(f)?;
100 writeln!(f)?;
101 }
102 Ok(())
103 }
104}
105
106#[cfg(test)]
107mod test {
108 use super::*;
109 use alloc::string::ToString;
110
111 #[test]
112 fn test_default() {
113 let pool = Pool::new("foo", 1);
114 assert_eq!(pool.to_string(), "pool foo\n depth = 1\n");
115 }
116
117 #[test]
118 fn test_variable() {
119 let pool = Pool::new("foo", 42).variable("foov", "z");
120 assert_eq!(pool.to_string(), "pool foo\n depth = 42\n foov = z\n");
121 }
122}