use somni_expr::{DefaultTypeSet, SomniIterator, SomniStruct, TypedValue, WithIterator};
pub type TemplateTypes = WithIterator<DefaultTypeSet>;
pub trait IntoValue {
fn into_value(self) -> TypedValue<TemplateTypes>;
}
impl IntoValue for u64 {
fn into_value(self) -> TypedValue<TemplateTypes> {
TypedValue::Int(self)
}
}
impl IntoValue for i64 {
fn into_value(self) -> TypedValue<TemplateTypes> {
TypedValue::SignedInt(self)
}
}
impl IntoValue for f64 {
fn into_value(self) -> TypedValue<TemplateTypes> {
TypedValue::Float(self)
}
}
impl IntoValue for bool {
fn into_value(self) -> TypedValue<TemplateTypes> {
TypedValue::Bool(self)
}
}
impl IntoValue for &str {
fn into_value(self) -> TypedValue<TemplateTypes> {
TypedValue::String(self.into())
}
}
impl IntoValue for String {
fn into_value(self) -> TypedValue<TemplateTypes> {
TypedValue::String(self.into_boxed_str())
}
}
impl IntoValue for TypedValue<TemplateTypes> {
fn into_value(self) -> TypedValue<TemplateTypes> {
self
}
}
impl IntoValue for SomniStruct<TemplateTypes> {
fn into_value(self) -> TypedValue<TemplateTypes> {
TypedValue::Struct(self)
}
}
pub struct Iter<I>(pub I);
impl<I> IntoValue for Iter<I>
where
I: IntoIterator,
I::Item: IntoValue,
{
fn into_value(self) -> TypedValue<TemplateTypes> {
let items: Vec<TypedValue<DefaultTypeSet>> = self
.0
.into_iter()
.map(|e| to_inner(e.into_value()))
.collect();
TypedValue::Iter(SomniIterator::new(items))
}
}
fn to_inner(v: TypedValue<TemplateTypes>) -> TypedValue<DefaultTypeSet> {
match v {
TypedValue::Void => TypedValue::Void,
TypedValue::MaybeSignedInt(x) => TypedValue::MaybeSignedInt(x),
TypedValue::Int(x) => TypedValue::Int(x),
TypedValue::SignedInt(x) => TypedValue::SignedInt(x),
TypedValue::Float(x) => TypedValue::Float(x),
TypedValue::Bool(b) => TypedValue::Bool(b),
TypedValue::String(s) => TypedValue::String(s),
TypedValue::Struct(s) => {
let (name, fields) = s.into_parts();
TypedValue::Struct(SomniStruct::new(
name,
fields.into_iter().map(|(k, v)| (k, to_inner(v))).collect(),
))
}
TypedValue::Iter(_) | TypedValue::Ref(_) => TypedValue::Void,
}
}
pub(crate) fn default_str(v: TypedValue<TemplateTypes>) -> String {
match v {
TypedValue::Int(i) => i.to_string(),
TypedValue::MaybeSignedInt(i) => i.to_string(),
TypedValue::SignedInt(i) => i.to_string(),
TypedValue::Float(f) => f.to_string(),
TypedValue::Bool(b) => b.to_string(),
TypedValue::String(s) => String::from(s),
TypedValue::Void => String::new(),
TypedValue::Iter(_) => String::from("<iter>"),
TypedValue::Struct(s) => format!("<struct {}>", s.name()),
TypedValue::Ref(_) => String::from("<ref>"),
}
}