deskc_thir2dson/
lib.rs

1use dson::Dson;
2use thir::{Expr, Literal, TypedHir};
3use thiserror::Error;
4
5#[derive(Debug, Clone, PartialEq, Error)]
6pub enum HirToJsonError {
7    #[error("{0} not allowed")]
8    NotAllowed(String),
9}
10
11pub fn thir_to_dson(thir: &TypedHir) -> Result<Dson, HirToJsonError> {
12    let dson = match &thir.expr {
13        Expr::Literal(Literal::Int(value)) => Dson::Literal(dson::Literal::Int(*value)),
14        Expr::Literal(Literal::Rational(a, b)) => Dson::Literal(dson::Literal::Rational(*a, *b)),
15        Expr::Literal(Literal::Float(value)) => Dson::Literal(dson::Literal::Float(*value)),
16        Expr::Literal(Literal::String(value)) => {
17            Dson::Literal(dson::Literal::String(value.clone()))
18        }
19        Expr::Product(values) => Dson::Product(
20            values
21                .iter()
22                .map(thir_to_dson)
23                .collect::<Result<Vec<_>, _>>()?,
24        ),
25        Expr::Array(values) => Dson::Array(
26            values
27                .iter()
28                .map(thir_to_dson)
29                .collect::<Result<Vec<_>, _>>()?,
30        ),
31        Expr::Set(values) => Dson::Set(
32            values
33                .iter()
34                .map(thir_to_dson)
35                .collect::<Result<Vec<_>, _>>()?,
36        ),
37        Expr::Let { .. } => return Err(HirToJsonError::NotAllowed("let".into())),
38        Expr::Perform { .. } => return Err(HirToJsonError::NotAllowed("perform".into())),
39        Expr::Handle { .. } => return Err(HirToJsonError::NotAllowed("handle".into())),
40        Expr::Apply { .. } => return Err(HirToJsonError::NotAllowed("apply".into())),
41        Expr::Match { .. } => return Err(HirToJsonError::NotAllowed("match".into())),
42        Expr::Function { .. } => return Err(HirToJsonError::NotAllowed("function".into())),
43        Expr::Op { .. } => return Err(HirToJsonError::NotAllowed("op".into())),
44        Expr::Label { label, item: expr } => Dson::Labeled {
45            label: label.clone(),
46            expr: Box::new(thir_to_dson(expr)?),
47        },
48    };
49    Ok(dson)
50}
51
52#[cfg(test)]
53mod tests {}