Skip to main content

haloumi_lowering/
lowerable.rs

1//! Traits for types that can be lowered.
2
3use crate::error::Error;
4
5use super::{ExprLowering, Lowering, Result};
6
7/// Declares that the type can be lowered into an expression.
8pub trait LowerableExpr {
9    /// Transforms the value into an expression.
10    fn lower<L>(self, l: &L) -> Result<L::CellOutput>
11    where
12        L: ExprLowering + ?Sized;
13}
14
15impl<T, E> LowerableExpr for std::result::Result<T, E>
16where
17    T: LowerableExpr,
18    Error: From<E>,
19{
20    fn lower<L>(self, l: &L) -> Result<L::CellOutput>
21    where
22        L: ExprLowering + ?Sized,
23    {
24        self?.lower(l)
25    }
26}
27
28impl<Lw: LowerableExpr> LowerableExpr for Box<Lw> {
29    fn lower<L>(self, l: &L) -> Result<L::CellOutput>
30    where
31        L: ExprLowering + ?Sized,
32    {
33        (*self).lower(l)
34    }
35}
36
37/// Declares that the type can be lowered into a statement.
38pub trait LowerableStmt {
39    /// Emits a statement from the value.
40    fn lower<L>(self, l: &L) -> Result<()>
41    where
42        L: Lowering + ?Sized;
43}
44
45impl<T, E> LowerableStmt for std::result::Result<T, E>
46where
47    T: LowerableStmt,
48    Error: From<E>,
49{
50    fn lower<L>(self, l: &L) -> Result<()>
51    where
52        L: Lowering + ?Sized,
53    {
54        self?.lower(l)
55    }
56}
57
58impl<T> LowerableStmt for Option<T>
59where
60    T: LowerableStmt,
61{
62    fn lower<L>(self, l: &L) -> Result<()>
63    where
64        L: Lowering + ?Sized,
65    {
66        if let Some(s) = self {
67            s.lower(l)?;
68        }
69        Ok(())
70    }
71}
72
73impl<T: LowerableStmt> LowerableStmt for Box<T> {
74    fn lower<L>(self, l: &L) -> Result<()>
75    where
76        L: Lowering + ?Sized,
77    {
78        (*self).lower(l)
79    }
80}
81
82impl<T: LowerableStmt, const N: usize> LowerableStmt for [T; N] {
83    fn lower<L>(self, l: &L) -> Result<()>
84    where
85        L: Lowering + ?Sized,
86    {
87        for e in self {
88            e.lower(l)?;
89        }
90        Ok(())
91    }
92}
93
94impl<T: LowerableStmt> LowerableStmt for Vec<T> {
95    fn lower<L>(self, l: &L) -> Result<()>
96    where
97        L: Lowering + ?Sized,
98    {
99        for e in self {
100            e.lower(l)?;
101        }
102        Ok(())
103    }
104}