diff --git a/src/internal/execute.rs b/src/internal/execute.rs index 85fe3aa..7a284ec 100644 --- a/src/internal/execute.rs +++ b/src/internal/execute.rs @@ -19,7 +19,6 @@ pub fn execute_(out: &mut String, ast: &Ast, value: &dyn Value) { AstKind::For(f) => for_(out, f, value), AstKind::Has(h) => has(out, h, value), AstKind::If(h) => if_(out, h, value), - e => todo!("{e:?}"), } } } diff --git a/src/lib.rs b/src/lib.rs index b8c6182..cde60ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,32 @@ value_for_int!(isize); impl<'a, T> Value for &'a T where - T: Value, + T: Value + ?Sized, +{ + fn print(&self, out: &mut String) { + (&**self).print(out) + } + + fn lookup(&self, name: &str) -> Option<&dyn Value> { + (&**self).lookup(name) + } + + fn has(&self) -> Option<&dyn Value> { + (&**self).has() + } + + fn if_(&self) -> bool { + (&**self).if_() + } + + fn for_(&self, index: usize) -> Option<&dyn Value> { + (&**self).for_(index) + } +} + +impl<'a, T> Value for &'a mut T +where + T: Value + ?Sized, { fn print(&self, out: &mut String) { (&**self).print(out) @@ -142,24 +167,26 @@ impl Value for String { } } -impl Value for (&str, &dyn Value) { +impl Value for (A, B) +where + A: Value, + B: Value, +{ fn print(&self, out: &mut String) { - out.push('('); self.0.print(out); - out.push_str(", "); self.1.print(out); } fn lookup(&self, name: &str) -> Option<&dyn Value> { match name { "0" => Some(&self.0), - "1" => Some(self.1), + "1" => Some(&self.1), _ => None, } } fn has(&self) -> Option<&dyn Value> { - Some(self) + None } fn if_(&self) -> bool { @@ -169,53 +196,55 @@ impl Value for (&str, &dyn Value) { fn for_(&self, index: usize) -> Option<&dyn Value> { match index { 0 => Some(&self.0), - 1 => Some(self.1), + 1 => Some(&self.1), _ => None, } } } -impl Value for (&dyn Value, &dyn Value) { - fn print(&self, out: &mut String) { - self.0.print(out); - self.1.print(out); - } - - fn lookup(&self, name: &str) -> Option<&dyn Value> { - match name { - "0" => Some(self.0), - "1" => Some(self.1), - _ => None, - } - } - - fn has(&self) -> Option<&dyn Value> { - Some(self) - } - - fn if_(&self) -> bool { - self.0.if_() && self.1.if_() - } - - fn for_(&self, index: usize) -> Option<&dyn Value> { - match index { - 0 => Some(self.0), - 1 => Some(self.1), - _ => None, - } - } -} - -impl Value for [(&str, &dyn Value); N] { +pub struct ValuesListMap<'a>(pub &'a [(&'a str, &'a dyn Value)]); +impl<'a> Value for ValuesListMap<'a> { fn print(&self, w: &mut String) { - for (name, v) in self.iter() { + for (name, v) in self.0.iter() { let _ = write!(w, "{name}"); v.print(w); } } fn lookup(&self, name: &str) -> Option<&dyn Value> { - self.iter().find(|(n, _)| *n == name).map(|(_, v)| *v) + self.0.iter().find(|(n, _)| *n == name).map(|(_, v)| *v) + } + + fn has(&self) -> Option<&dyn Value> { + if self.0.is_empty() { + None + } else { + Some(self) + } + } + + fn if_(&self) -> bool { + !self.0.is_empty() + } + + fn for_(&self, index: usize) -> Option<&dyn Value> { + self.0.get(index).map(|v| v as &dyn Value) + } +} + +impl Value for [T; N] +where + T: Value, +{ + fn print(&self, w: &mut String) { + for v in self.iter() { + v.print(w) + } + } + + fn lookup(&self, name: &str) -> Option<&dyn Value> { + let idx: usize = name.parse().ok()?; + self.get(idx).map(|v| v as &dyn Value) } fn has(&self) -> Option<&dyn Value> { @@ -235,35 +264,6 @@ impl Value for [(&str, &dyn Value); N] { } } -impl Value for [&dyn Value; N] { - fn print(&self, w: &mut String) { - for v in self.iter() { - v.print(w) - } - } - - fn lookup(&self, name: &str) -> Option<&dyn Value> { - let idx: usize = name.parse().ok()?; - self.get(idx).copied() - } - - fn has(&self) -> Option<&dyn Value> { - if self.is_empty() { - None - } else { - Some(self) - } - } - - fn if_(&self) -> bool { - self.is_empty() - } - - fn for_(&self, index: usize) -> Option<&dyn Value> { - self.get(index).map(|v| *v) - } -} - impl Value for Option where T: Value, @@ -314,11 +314,13 @@ impl Newt { #[macro_export] macro_rules! values_list_map { ($($key:literal: $val:expr),* $(,)?) => {{ - &[ - $( - ($key, $val as &dyn Value) - )*, - ] + &$crate::ValuesListMap( + &[ + $( + ($key, $val as &dyn Value) + )*, + ] + ) }} }