pacak / bpaf

Command line parser with applicative interface
Apache License 2.0
351 stars 17 forks source link

fallback to a config file #275

Open pacak opened 1 year ago

pacak commented 1 year ago

API for bpaf can look like this:

  1. add a key method to NamedField to try to read next value that belongs to this key
  2. add enter method to Parser - this method would move a cursor inside the AST
  3. add something that would add an applicative config reader to Args/State

API for applicative config reader can look like this:

  1. enter(&mut self, key: &'static str) - move to a table key inside a current table
  2. pop(&mut self) - go one level up
  3. get(&mut self, key: &'static str) -> Option<&str> - to to read next available value from a key in a current table
  4. drain(&mut self, key: &'static) - mark full key as parsed - successfully consumed item

applicative reader needs to maintain a set of cursors - one for each field, similar to command line arguments reading should succeed only once, bpaf will handle cloning for forks.

reader structure can be something like this:

struct Reader {
    payload: Rc<BTree<key, ValueOrTree>>, // config data, read only
    flat_keys: Rc<RefCell<MapPathToInt>>>, // maps path to each key to a number, mapping is persistent across the branches
    consumed: Vec<usize>, // counts how many times value at a given key was consumed
}
aeosynth commented 12 months ago

What to use to read the config? toml_edit seems to allow to do it in a serde-free way.

could you let the user read the config and pass that as the payload?

pacak commented 12 months ago

could you let the user read the config and pass that as the payload?

Problem is that I need to be able to query into that payload: "get field called foo in current scope", "move current scope into table bar", etc. Currently there's a trait that lets user to represent this (see #286). User can create an impl Parser trait object that produces something that implements impl Config trait object and this supports hierarchical configuration files - like a list of examples in Cargo.toml. Problem is often you don't need all the flexibility and you just want to be able to read a config file and for that I'd like to provide something simple - you make impl Parser that gets a path to a file and as long as this file is in some common format it works as expected. For that I need to support reading config in those common formats and to implement my Config trait for some of the data types library produces. One way is serde with a few crates like serde_json - I can implement Config for a Value type provided by those crates, but after recent events - I don't really want to depend on it. This means toml_edit. Or as an alternative - make a separate crate that depends on serde and provide impl Config in there...