martinohmann / hcl-rs

HCL parsing and encoding libraries for rust with serde support
Apache License 2.0
119 stars 14 forks source link

`Deserialize` impl for `Block` is wrong #322

Closed auguwu closed 4 months ago

auguwu commented 6 months ago

With the following code:

    #[test]
    fn heckheckheck() {
        use hcl::Block;

        let contents = r#"block1 "label0" "label1" { inner = true }"#;
        let block: Block = hcl::from_str(contents).unwrap();
    }

receives this error:

running 1 test
thread 'config::tests::heckheckheck' panicked at crates/config/src/config.rs:132:52:
called `Result::unwrap()` on an `Err` value: Message("missing field `identifier`")

when, it should be successful with the following structure:

Block {
   identifier: Identifier(block1),
   labels: ["label0", "label1"],
   body: ... # with attribute "inner" ~> true
}

Since it derives Deserialize, I guess the implementation is wrong or is this intended behaviour?

https://github.com/martinohmann/hcl-rs/blob/8349bdd12df96b47d5d7f0bc9ce988dc03c57fb6/crates/hcl-rs/src/structure/block.rs#L18-L19

denfren commented 4 months ago

Currently, only hcl::Body implements the special handling - all other structures are deserialized according to hcl-json-spec (including hcl::Block)

https://github.com/martinohmann/hcl-rs/blob/8349bdd12df96b47d5d7f0bc9ce988dc03c57fb6/crates/hcl-rs/src/de/mod.rs#L229-L237

If you remove Deserialize then you can see where this is used internally. Should be possible to rewrite this. However it seems to be easier to deserialize into hcl::Body as documented and extract the Block from there.

auguwu commented 4 months ago

That seems reasonable, thanks :)