From 73065fc808333d90a9fa99940c4261502e908ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Sat, 9 Nov 2024 02:28:13 +0100 Subject: [PATCH] fix(expression): make TryInto to TryFrom trait --- src/lisp/expression.rs | 64 ++++++++++++++++++++++++++++++------------ src/lisp/prelude.rs | 2 +- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/lisp/expression.rs b/src/lisp/expression.rs index 6ceb650..fb7b088 100644 --- a/src/lisp/expression.rs +++ b/src/lisp/expression.rs @@ -56,10 +56,10 @@ impl From<(Expression, Expression)> for Expression { } } -impl TryInto for Expression { +impl TryFrom for i64 { type Error = EvalError; - fn try_into(self) -> Result { - match self { + fn try_from(value: Expression) -> Result { + match value { Expression::Integer(i) => Ok(i), _ => Err(EvalError::TypeError( "Expression is not an Integer".to_string(), @@ -68,10 +68,10 @@ impl TryInto for Expression { } } -impl TryInto for Expression { +impl TryFrom for f64 { type Error = EvalError; - fn try_into(self) -> Result { - match self { + fn try_from(value: Expression) -> Result { + match value { Expression::Float(f) => Ok(f), _ => Err(EvalError::TypeError( "Expression is not a Float".to_string(), @@ -80,10 +80,10 @@ impl TryInto for Expression { } } -impl TryInto for Expression { +impl TryFrom for String { type Error = EvalError; - fn try_into(self) -> Result { - match self { + fn try_from(value: Expression) -> Result { + match value { Expression::String(s) => Ok(s), _ => Err(EvalError::TypeError( "Expression is not a String".to_string(), @@ -92,19 +92,35 @@ impl TryInto for Expression { } } -impl TryInto> for Expression { +impl TryFrom for Vec { type Error = EvalError; - fn try_into(self) -> Result, Self::Error> { - CellIterator::new(self).collect() + fn try_from(value: Expression) -> Result, Self::Error> { + CellIterator::new(value).collect() } } -impl TryInto<[Expression; N]> for Expression { +impl TryFrom for Vec +where + ToExpr: TryFrom, +{ type Error = EvalError; - fn try_into(self) -> Result<[Expression; N], Self::Error> { - let buf: Vec = self.try_into()?; + fn try_from(value: Expression) -> Result, Self::Error> { + CellIterator::new(value) + .map(|x| x?.try_into() as Result) + .collect() + } +} + +impl TryFrom for [ToExpr; N] +where + ToExpr: TryFrom, +{ + type Error = EvalError; + + fn try_from(value: Expression) -> Result<[ToExpr; N], Self::Error> { + let buf: Vec = value.try_into()?; let n = buf.len(); buf.try_into() @@ -112,10 +128,22 @@ impl TryInto<[Expression; N]> for Expression { } } -impl TryInto<(Expression, Expression)> for Expression { +impl TryFrom for [Expression; N] { type Error = EvalError; - fn try_into(self) -> Result<(Expression, Expression), Self::Error> { - match self { + + fn try_from(value: Expression) -> Result<[Expression; N], Self::Error> { + let buf: Vec = value.try_into()?; + let n = buf.len(); + + buf.try_into() + .map_err(|_| EvalError::ArgumentError(format!("Expected {} arguments, got {}", N, n))) + } +} + +impl TryFrom for (Expression, Expression) { + type Error = EvalError; + fn try_from(value: Expression) -> Result<(Expression, Expression), Self::Error> { + match value { Expression::Cell(a, b) => Ok((*a, *b)), _ => Err(EvalError::TypeError( "Expression must be a Cell".to_string(), diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs index a740228..1e565cc 100644 --- a/src/lisp/prelude.rs +++ b/src/lisp/prelude.rs @@ -79,7 +79,7 @@ pub fn prelude_div(env: &Environment, expr: Expression) -> Result Result { - let [args, body] = expr.try_into()?; + let [args, body]: [Expression; 2] = expr.try_into()?; let mut arg_exprs: Vec = args.try_into()?; let argument_symbols: Vec = arg_exprs .iter_mut()