use microcad_lang::{builtin::*, src_ref::*, value::*, Id};
pub struct TomlImporter;
impl TomlImporter {
fn toml_to_value(toml: &toml::Value) -> Value {
match toml {
toml::Value::String(s) => Value::String(s.clone()),
toml::Value::Integer(i) => Value::Integer(*i),
toml::Value::Float(f) => (*f).into(),
toml::Value::Boolean(b) => Value::Bool(*b),
toml::Value::Datetime(_) => todo!(),
toml::Value::Array(values) => {
let mut list = Vec::new();
for toml_value in values {
list.push(Self::toml_to_value(toml_value));
}
Value::Array(Array::from_values(
ValueList::new(list),
microcad_lang::ty::Type::Invalid, ))
}
toml::Value::Table(map) => Value::Tuple(Box::new(Tuple::new_named(
map.iter()
.map(|(k, v)| (Identifier::no_ref(k), Self::toml_to_value(v)))
.collect(),
SrcRef(None),
))),
}
}
}
impl Importer for TomlImporter {
fn import(
&self,
args: µcad_lang::value::Tuple,
) -> Result<microcad_lang::value::Value, microcad_lang::builtin::ImportError> {
let filename = args.get::<String>("filename");
let content = std::fs::read_to_string(filename)?;
Ok(Self::toml_to_value(
&toml::from_str::<toml::Value>(&content)
.map_err(|err| ImportError::CustomError(Box::new(err)))?,
))
}
}
impl FileIoInterface for TomlImporter {
fn id(&self) -> microcad_lang::Id {
Id::new("toml")
}
}
#[test]
fn toml_importer() {
use microcad_lang::{model::*, value::Tuple};
let toml_importer = TomlImporter;
let mut args = Tuple::default();
args.insert(
Identifier::no_ref("filename"),
Value::String("Cargo.toml".into()),
);
let value = toml_importer.import(&args).expect("No error");
println!("{value}");
if let Value::Tuple(tuple) = value {
if let Value::Model(model) = tuple
.by_id(&Identifier::no_ref("package"))
.expect("Package info")
{
let model_ = model.borrow();
let name = model_
.get_property(&Identifier::no_ref("name"))
.expect("property");
let name = name.try_string().expect("String value");
println!("{name}");
}
} else {
panic!("Value must be a tuple!")
}
}