use super::{AlgebraicType, ProductType, SumType};
use crate::de::fmt_fn;
use core::fmt::Display;
use fmt_algebraic_type as fmt;
pub fn fmt_algebraic_type(ty: &AlgebraicType) -> impl '_ + Display {
fmt_fn(move |f| match ty {
AlgebraicType::Ref(r) => write!(f, "{r}"),
AlgebraicType::Sum(ty) => write!(f, "{}", fmt_sum_type(ty)),
AlgebraicType::Product(ty) => write!(f, "{}", fmt_product_type(ty)),
AlgebraicType::Array(a) => write!(f, "Array<{}>", fmt(&a.elem_ty)),
AlgebraicType::Bool => write!(f, "Bool"),
AlgebraicType::I8 => write!(f, "I8"),
AlgebraicType::U8 => write!(f, "U8"),
AlgebraicType::I16 => write!(f, "I16"),
AlgebraicType::U16 => write!(f, "U16"),
AlgebraicType::I32 => write!(f, "I32"),
AlgebraicType::U32 => write!(f, "U32"),
AlgebraicType::I64 => write!(f, "I64"),
AlgebraicType::U64 => write!(f, "U64"),
AlgebraicType::I128 => write!(f, "I128"),
AlgebraicType::U128 => write!(f, "U128"),
AlgebraicType::I256 => write!(f, "I256"),
AlgebraicType::U256 => write!(f, "U256"),
AlgebraicType::F32 => write!(f, "F32"),
AlgebraicType::F64 => write!(f, "F64"),
AlgebraicType::String => write!(f, "String"),
})
}
pub fn fmt_product_type(ty: &ProductType) -> impl '_ + Display {
fmt_fn(move |f| {
write!(f, "(")?;
for (i, e) in ty.elements.iter().enumerate() {
if let Some(name) = &e.name {
write!(f, "{name}")?;
} else {
write!(f, "{i}")?;
}
write!(f, ": ")?;
write!(f, "{}", fmt(&e.algebraic_type))?;
if i < ty.elements.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, ")")
})
}
fn fmt_sum_type(ty: &SumType) -> impl '_ + Display {
fmt_fn(move |f| {
if ty.variants.is_empty() {
return write!(f, "(|)");
}
write!(f, "(")?;
for (i, e) in ty.variants.iter().enumerate() {
if let Some(name) = &e.name {
write!(f, "{name}")?;
write!(f, ": ")?;
}
write!(f, "{}", fmt(&e.algebraic_type))?;
if i < ty.variants.len() - 1 {
write!(f, " | ")?;
}
}
write!(f, ")")
})
}