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 {}