Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Examples of how to use this to configure a rust program. #1751

Open
cstorey opened this issue Jan 5, 2024 · 4 comments
Open

Comments

@cstorey
Copy link

cstorey commented Jan 5, 2024

I've an application where i might need to update small parts of th configuration for different environments (credentials, which messaging topics to subscribe to, etc). I'm currently using dhall for this, but it seems like the current implementation is no longer maintained.

i've been thinking that nickel might be a good replacement for this, but I can't find clear guidance on how to integrate this for configuration (eg: being able to pass an io::Reader into nickle function, and get back either a deserialized data type or a useful error).

I'd love to see a clear examples of how to do this, along with helper functions like serde_dhall::from_file that make it easy to use for common cases, while preservinvg the existing usage for less common cases.

It's entirely possible for me to pick through the types (eg: it looks like various types in the crate implement serde's Deserialize/r, but I've never quite had the time to properly sit through it and implement it.

Thanks for your consideration.

@cstorey cstorey changed the title Examples of how to use this to configure a rust program. Feature request: Examples of how to use this to configure a rust program. Jan 5, 2024
@jneem
Copy link
Member

jneem commented Jan 5, 2024

Hey, thanks for the question! We've been definitely more focused on the CLI usage than the rust APIs, so most things here are under-documented and subject to change. But you should be able to get started by using Program::new_from_source to load from a std::io::Read (or see the other Program::new_from... methods). Then Program::eval_full_for_export will give you back a RichTerm that implements serde::Serialize. You can either serialize it to some format, or use serde-transcode to convert it to something else.

For a full example, you could look at the code for the export cli command

@cstorey
Copy link
Author

cstorey commented Jan 5, 2024

Oh, amazing. Thanks for the pointers!

@yannham
Copy link
Member

yannham commented Jan 10, 2024

Additionally, the tests of the deserialize module are also a good inspiration on how to just eval a Nickel string and get back an arbitrary Rust structure that derives Deserialize:

mod tests {

@akavel
Copy link
Contributor

akavel commented Jan 23, 2024

FWIW, here's what seemed to work for me (with Nickel 0.4), based on the hints above - please note it can probably be improved, it's just in the hacked-together state in which I first got it to work:

https://github.com/akavel/mana/blob/01736bebe81d355335368992e6b19e543f025cbf/src/main.rs#L254-L272

    use nickel_lang_core::error::report::ErrorFormat;
    use nickel_lang_core::eval::cache::lazy::CBNCache;
    use nickel_lang_core::program::Program as Prog;
    let err = std::io::stderr();
    let mut prog = Prog::<CBNCache>::new_from_file(&path, err)?;
    let res_field = prog.parse_field_path(field_path.clone());
    let Ok(field) = res_field else {
        prog.report(res_field.unwrap_err(), ErrorFormat::Text);
        bail!("failed to parse {field_path:?} as Nickel path");
    };
    prog.field = field;
    let res_term = prog.eval_full_for_export();
    let Ok(term) = res_term else {
        prog.report(res_term.unwrap_err(), ErrorFormat::Text);
        bail!("script {path:?} failed");
    };
    // FIXME: shorten to: toml::Table::deserialize(term)
    let toml = toml::to_string(&term).unwrap();
    parse_input_toml(&toml)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants