You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
use std::path::Path;
use allocative::Allocative;
use starlark::any::ProvidesStaticType;
use starlark::environment::Globals;
use starlark::environment::Module;
use starlark::eval::Evaluator;
use starlark::syntax::AstModule;
use starlark::syntax::Dialect;
use starlark::values::starlark_value;
use starlark::values::NoSerialize;
use starlark::values::StarlarkValue;
use starlark::values::UnpackValue;
use anyhow::{anyhow, Result};
#[derive(
Debug,
derive_more::Display,
Allocative,
NoSerialize,
ProvidesStaticType,
UnpackValue,
)]
struct Config {
test: String,
}
#[starlark_value(type = "Config", UnpackValue, StarlarkTypeRepr)]
impl<'v> StarlarkValue<'v> for Config {}
pub fn read_config(path: &Path) -> Result<Config> {
let content = std::fs::read_to_string(path)?;
let file_name = path.file_name().ok_or(anyhow!("No file name in path"))?;
let file_name = file_name.to_str().ok_or(anyhow!("File name isn't valid UTF-8"))?;
read_config_text(content, file_name)
}
pub fn read_config_text(content: String, file_name: &str) -> Result<Config> {
let dialect = Dialect {
enable_f_strings: true,
..Dialect::Extended
};
let ast = AstModule::parse(file_name, content, &dialect).map_err(|e| anyhow!("Parse error: {e}"))?;
let globals = Globals::standard();
let module = Module::new();
let mut eval = Evaluator::new(&module);
let value = eval.eval_module(ast, &globals).map_err(|e| anyhow!("Eval error: {e}"))?;
UnpackValue::unpack_value_err(value)
}
Unfortunately #[derive(UnpackValue)] apparently only works for enums. Is this kind of use case supported?
The text was updated successfully, but these errors were encountered:
You can write your own UnpackValue by hand, which shouldn't be too difficult.
I do agree that a reasonable UnpackValue implementation for a struct would be to UnpackValue all the fields from appropriately named Dict (or maybe anything with a get_item). I think we'd take a patch adding that functionality to UnpackValue.
Your broad use case makes a lot of sense, and we've seen many people do things like that. I would say the reason they haven't wanted exactly UnpackValue the way you are after is because often they'll define a data type Server and a function server which is exposed as a Rust function in the Starlark environment, so instead of users producing a Dict, they'd have to call server. Either can work though.
Hmm maybe I can just implement serde::Deserialise for Value? I will try...
they'll define a data type Server and a function server which is exposed as a Rust function in the Starlark environment, so instead of users producing a Dict, they'd have to call server.
Yeah I guess that's the imperative vs functional style. I think I prefer functional in this case, even though Python syntax is not very functional - especially as it matches how you'd do it in JSON/YAML/etc.
Hi, I'm considering using Starlark as a config file format - where you might normally use JSON or YAML or TOML via Serde.
So for example instead of a config file like
You could have
I got as far as this:
Unfortunately
#[derive(UnpackValue)]
apparently only works for enums. Is this kind of use case supported?The text was updated successfully, but these errors were encountered: