mitsuhiko / minijinja

MiniJinja is a powerful but minimal dependency template engine for Rust compatible with Jinja/Jinja2
https://docs.rs/minijinja/
Apache License 2.0
1.56k stars 86 forks source link

Serialized Value cannot Deserialize #553

Closed cathaysia closed 1 month ago

cathaysia commented 1 month ago

Description

I'm using Value::from_serialize pass context to template. Then using ViaDeserialize<Type> deserialize the value. however, it failed.

here are some log:

```console called `Result::unwrap()` on an `Err` value: Error { kind: CannotDeserialize, detail: "invalid type: map, expected enum Type", name: "op.idl", line: 24 } ----------------------------------- op.idl ------------------------------------ 22 | {% for param in params %} 24 > {{ param.ty | to_ty }} {{ param.ident }}; i ^^^^^ cannot deserialize ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Referenced variables: { base_name: , in_params: 0, loop: , param: { "ident": "com", "ty": { "Path": [ "Command", ], }, } } ```

here is my enum defination:

enum Type {
    Array(TypeArray),
    Path(TypePath),
    Primative(PrimativeType),
}

as far as I know, plain enum, unit struct cannot be deserialize. It seems enum would be serialized to &str?

Additional helpful information:

What did you expect

Serialization and deserialization operations should be symmetric

cathaysia commented 1 month ago

I try 1.0.10, I report the same error.

mitsuhiko commented 1 month ago

Can you provide a minimal reproduction case that shows the issue? I am not entirely sure what you are trying to attempt from the code provided.

cathaysia commented 1 month ago

Here is a example to deserialzie Enum:

```rust #[derive(Debug, serde::Serialize, serde::Deserialize)] enum SimpleEnum { B, C, D, } #[derive(Debug, serde::Serialize, serde::Deserialize)] enum TaggedUnion { V(String), } #[derive(Debug, serde::Serialize, serde::Deserialize)] struct UnitStruct(String); let mut env = Environment::new(); env.add_function("pe", |v: ViaDeserialize| { println!("{:?}", v.0); }); env.add_function("pu", |v: ViaDeserialize| { println!("{:?}", v.0); }); env.add_function("pt", |v: ViaDeserialize| { println!("{:?}", v.0); }); let mut ctx = HashMap::new(); ctx.insert("spe", Value::from_serialize(SimpleEnum::B)); ctx.insert("spu", Value::from_serialize(UnitStruct("hello".into()))); ctx.insert("spt", Value::from_serialize(TaggedUnion::V("workd".into()))); let _ = env .render_str( r#" {{ pe(spe) }} {# failed #} {{ pu(spu) }} {# failed #} {{ pt(spt) }} {# failed #} "#, ctx, ) .unwrap(); ```
mitsuhiko commented 1 month ago

There are some interesting bugs clearly with the value deserializer. Basic testing shows that SimpleEnum::deserialize(&Value::from("B")) succeeds but SimpleEnum::deserialize(Value::from("B")) fails. I will get that fixed.