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

Rendering template using yaml data file containing anchors #520

Closed alghazanth closed 2 months ago

alghazanth commented 3 months ago

Description

Currently yaml anchors inside yaml data files are not fully supported because of serde_yaml author refused to implement them. There is wonderful yaml-rust2 that could help mitigate the issue. Would you mind to consider migration from serde_yaml to yaml-rust2?

Additional helpful information:

What did you expect

Structures like:

dict1: &dict1_anchor
  key1: value1
  key2: value2

dict2:
  <<: *dict1_anchor

should serialize into:

dict1:
  key1: value1
  key2: value2

dict2:
  key1: value1
  key2: value2
mitsuhiko commented 3 months ago

I would love to support this. Unfortunately yaml-rust2 does not support serde today. serde_yaml2 which uses yaml-rust2 does support serde, but it does not support anchors: https://github.com/zim32/serde_yaml2/blob/06d2d5ecca84c6d3c0d5e2f3cbac75bf2cc97e1e/src/de/mod.rs#L275-L277

So the actual work required here is quite high. Ideally support for this lands in a YAML library that directly supports serde.

alghazanth commented 3 months ago

Well, the library you mentioned doesn't seem to be well maintained too unfortunately. Also, is it that hard to convert serde_yaml's Value into yaml-rust2's Yaml (by implementing TryFrom or something)? Sorry for naive question, I'm a novice in Rust.

mitsuhiko commented 3 months ago

I cannot say because I'm not entirely sure how Alias is being handled in yaml-rust2. With buffering it wouldn't be too hard would be my guess but again, I cannot say. In general that is something I would not want to maintain as part of MiniJinja. If functionality lands in a serde compatible crate I would switch to it.

mitsuhiko commented 2 months ago

Turns out serde_yml does support aliases but it only supports a singular merge key. So this would not be supported:

dict1: &dict1_anchor
  key1: value1

dict2: &dict2_anchor
  key2: value2

dict3:
  <<: *dict1_anchor
  <<: *dict2_anchor
  key3: value3

However this would be:

dict1: &dict1_anchor
  key1: value1

dict2: &dict2_anchor
  key2: value2

dict3:
  <<: [*dict1_anchor, *dict2_anchor]
  key3: value3