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

is there a way to iterate over key, values in a map #131

Closed
sassman opened this issue Oct 20, 2022 · 3 comments · Fixed by #132
Closed

is there a way to iterate over key, values in a map #131

sassman opened this issue Oct 20, 2022 · 3 comments · Fixed by #132

Comments

@sassman
Copy link

sassman commented Oct 20, 2022

For a custom function, that accepts a minijinja::value::Value which holds a map, I would like to access the key, values of the inner map and even mutate the values or add new key, value pairs.

As it seems right one can only check for specific keys, via .get_attr(&str) but not iterate over all contents.

Maybe I'm missing something, in that case I would appreciate some input.

@mitsuhiko
Copy link
Owner

That is currently somewhat intentional. What you can do today is to use serde to serialize the value into something else. That's obviously not entirely ideal, but might be what you actually need. Can you share what you are trying to do? I'm happy to try to figure out an API to iterate over values and to expose the maps (in some form), but for that it would be interesting to understand the intended use.

@sassman
Copy link
Author

sassman commented Oct 20, 2022

Nice idea, I was able to go via serde_json::from_str into a HashMap<String, serde_json::Value>.
The HashMap is then mutable and all works well. The double serialization is right now not ideal, but also not a big issue in my case.

The example looks something like this:

pub fn jwt(_state: &State, claims: Value, signing_key: Option<Value>) -> Result<String, Error> {
    let mut claims: HashMap<String, serde_json::Value> =
        serde_json::from_str(claims.to_string().as_str()).unwrap();

    // in case the expiry is missing, we expire it in 15min
    if claims.contains_key(EXPIRY).not() {
        let expire_in = Utc::now()
            .add(Duration::minutes(15))
            .with_second(0)
            .unwrap()
            .timestamp();
        claims.insert(EXPIRY.to_string(), serde_json::Value::from(expire_in));
    }

    let token = jsonwebtoken::encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(b"secret"),
    );

    token.map_err(|e| {
        Error::new(
            ErrorKind::UndefinedError,
            "jsonwebtoken failed to encode the token.",
        )
        .with_source(e)
    })
}

@sassman
Copy link
Author

sassman commented Oct 23, 2022

Thanks a lot @mitsuhiko ❤️

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

Successfully merging a pull request may close this issue.

2 participants