use alef_core::ir::{PrimitiveType, TypeRef};
use std::borrow::Cow;
pub trait TypeMapper {
fn primitive(&self, prim: &PrimitiveType) -> Cow<'static, str> {
Cow::Borrowed(match prim {
PrimitiveType::Bool => "bool",
PrimitiveType::U8 => "u8",
PrimitiveType::U16 => "u16",
PrimitiveType::U32 => "u32",
PrimitiveType::U64 => "u64",
PrimitiveType::I8 => "i8",
PrimitiveType::I16 => "i16",
PrimitiveType::I32 => "i32",
PrimitiveType::I64 => "i64",
PrimitiveType::F32 => "f32",
PrimitiveType::F64 => "f64",
PrimitiveType::Usize => "usize",
PrimitiveType::Isize => "isize",
})
}
fn string(&self) -> Cow<'static, str> {
Cow::Borrowed("String")
}
fn bytes(&self) -> Cow<'static, str> {
Cow::Borrowed("Vec<u8>")
}
fn path(&self) -> Cow<'static, str> {
Cow::Borrowed("String")
}
fn json(&self) -> Cow<'static, str> {
Cow::Borrowed("serde_json::Value")
}
fn unit(&self) -> Cow<'static, str> {
Cow::Borrowed("()")
}
fn duration(&self) -> Cow<'static, str> {
Cow::Borrowed("u64")
}
fn optional(&self, inner: &str) -> String {
format!("Option<{inner}>")
}
fn vec(&self, inner: &str) -> String {
format!("Vec<{inner}>")
}
fn map(&self, key: &str, value: &str) -> String {
format!("HashMap<{key}, {value}>")
}
fn named<'a>(&self, name: &'a str) -> Cow<'a, str> {
Cow::Borrowed(name)
}
fn map_type(&self, ty: &TypeRef) -> String {
match ty {
TypeRef::Primitive(p) => self.primitive(p).into_owned(),
TypeRef::String | TypeRef::Char => self.string().into_owned(),
TypeRef::Bytes => self.bytes().into_owned(),
TypeRef::Path => self.path().into_owned(),
TypeRef::Json => self.json().into_owned(),
TypeRef::Unit => self.unit().into_owned(),
TypeRef::Optional(inner) => self.optional(&self.map_type(inner)),
TypeRef::Vec(inner) => self.vec(&self.map_type(inner)),
TypeRef::Map(k, v) => self.map(&self.map_type(k), &self.map_type(v)),
TypeRef::Named(name) => self.named(name).into_owned(),
TypeRef::Duration => self.duration().into_owned(),
}
}
fn error_wrapper(&self) -> &str;
fn wrap_return(&self, base: &str, has_error: bool) -> String {
if has_error {
format!("{}<{base}>", self.error_wrapper())
} else {
base.to_string()
}
}
}