Dynamically choose a YAML selector for a parsed YAML document

Greetings,

I'd like to dynamically choose a YAML selector for a parsed YAML document.

I see in the yaml-rust docs:

assert_eq!(doc["foo"][0].as_str().unwrap(), "list1");

I would like to do something like:

let key = "[foo][0]";
assert_eq!(doc.dynamic_lookup(key).unwrap(), "list1");

The reason being is that I'd like to allow the user to select the YAML selector at runtime.

Does anyone have any ideas or know of a rust crate that would allow me to dynamically choose a selector for a parsed YAML document?

Thanks!

You say you use yaml-rust, but I'm assuming you are actually using serde_yaml, which makes more sense in the context of your question. You can iteratively call Value::get till you get to the required depth, like this, for example:

use serde_yaml::{from_str, Value, Index};

fn index_yaml<'a>(yaml: &'a Value, indices: &[&dyn Index]) -> Option<&'a Value> {
    let mut current_depth = yaml;
    
    for i in indices {
        current_depth = current_depth.get(i)?;
    }
    
    Some(current_depth)
} 

fn main() {
    let raw = "foo: [list1, list2]";
    
    let yaml: Value = from_str(raw).unwrap();
    
    assert_eq!(yaml["foo"][0].as_str().unwrap(), "list1");
    
    let indices: Vec<&dyn Index> = vec![&"foo", &0];
    
    let list1 = index_yaml(&yaml, &indices).unwrap();
    
    assert_eq!(list1, "list1");
}

Playground.

How you construct the vector of indices from your user input is up to you and depends on your requirements.

2 Likes

Hello @jofas,

Thank you for the help and code example!

It works great and I learned about dynamic dispatching, too.

Much appreciated.

-m

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.