use orchid_base::location::Pos; use crate::{atom::{AtomicFeatures, TypAtom}, error::{ProjectError, ProjectResult}, expr::{atom, bot_obj, ExprHandle, GenExpr, OwnedExpr}, system::downcast_atom}; pub trait TryFromExpr: Sized { fn try_from_expr(expr: ExprHandle) -> ProjectResult; } impl TryFromExpr for OwnedExpr { fn try_from_expr(expr: ExprHandle) -> ProjectResult { Ok(OwnedExpr::new(expr)) } } impl TryFromExpr for (T, U) { fn try_from_expr(expr: ExprHandle) -> ProjectResult { Ok((T::try_from_expr(expr.clone())?, U::try_from_expr(expr)?)) } } pub struct ErrorNotAtom(Pos); impl ProjectError for ErrorNotAtom { const DESCRIPTION: &'static str = "Expected an atom"; fn one_position(&self) -> Pos { self.0.clone() } } pub struct ErrorUnexpectedType(Pos); impl ProjectError for ErrorUnexpectedType { const DESCRIPTION: &'static str = "Type error"; fn one_position(&self) -> Pos { self.0.clone() } } impl TryFromExpr for TypAtom { fn try_from_expr(expr: ExprHandle) -> ProjectResult { OwnedExpr::new(expr).foreign_atom().map_err(|ex| ErrorNotAtom(ex.pos.clone()).pack()) .and_then(|f| downcast_atom(f).map_err(|f| ErrorUnexpectedType(f.pos).pack())) } } pub trait ToExpr { fn to_expr(self) -> GenExpr; } impl ToExpr for ProjectResult { fn to_expr(self) -> GenExpr { match self { Err(e) => bot_obj(e), Ok(t) => t.to_expr(), } } } impl ToExpr for A { fn to_expr(self) -> GenExpr { atom(self) } }