diff --git a/src/ast.rs b/src/ast.rs index 5cc03da..3db94b7 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -54,3 +54,57 @@ pub enum Constant { Number(i64), String(String), } + +impl Expression { + pub fn new_constant(value: impl Into) -> Self { + Self::Constant(value.into()) + } +} + +impl From<()> for Constant { + fn from(_value: ()) -> Self { + Self::Nil + } +} + +macro_rules! impl_from { + ($as: ident, $from: ty) => { + impl From<$from> for Constant { + fn from(value: $from) -> Self { + Self::$as(value.into()) + } + } + }; + (try $as: ident, $from: ty) => { + impl TryFrom<$from> for Constant { + type Error = ::std::num::TryFromIntError; + fn try_from(value: $from) -> Result { + Ok(Self::$as(value.try_into()?)) + } + } + }; +} + +impl_from!(Boolean, bool); +impl_from!(try Number, isize); +impl_from!(try Number, usize); +impl_from!(try Number, i64); +impl_from!(try Number, u64); +impl_from!(Number, u32); +impl_from!(Number, i32); +impl_from!(String, String); +impl_from!(String, &str); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_into() { + // test that this compiles + Expression::new_constant(()); + Expression::new_constant(true); + Expression::new_constant(42); + Expression::new_constant("foobar"); + } +}