kinnison / marked-data

A YAML representation library which explicitly retains provenance data
MIT License
13 stars 6 forks source link

Serde support #5

Closed kinnison closed 6 months ago

kinnison commented 6 months ago

This adds serde support to permit deserialising into structs using Spanned<String> and friends rather than relying on the more flexible but more clumsy Marked*Node interface.

kinnison commented 6 months ago

@wolfv I'd be interested in knowing if you think this is useful / good? I am considering using this kind of thing for some simple config parsing in a project at work; and figured this would be worthwhile to reduce the effort of writing code to work through a Node tree.

kinnison commented 6 months ago

Seems like I have a long way to go with enums etc. but this is looking promising, I'll rebase once I've got further with enums.

kinnison commented 6 months ago

Okay, I think this covers all the important stuff - if you use an untagged or internally tagged enum then you cannot have Spanned<T> inside it because the spans aren't noticed by the serde internal Content system and there's no two ways around that short of forcing an "always spanned" thing which on first attempt results in more pain than it's worth to try and implement. Interestingly, adjacently tagged enums seem plausible still. It's a pity but in theory fairly simple conversions on the node trees would be possible to allow this.

My gut feeling is that this is good enough for pushing to main, but perhaps not yet for a release.

wolfv commented 6 months ago

Interesting! I am currently on vacation but will take a look. We recently also hit some snags with serde and error messages for untagged enums. If you have any insights / ideas would love to hear them. I was even thinking about looking into making a PR for better error messages for untagged enums :)

kinnison commented 6 months ago

Interesting! I am currently on vacation but will take a look.

Don't waste vacation time on my coding messes :D Have an awesome holiday first.

We recently also hit some snags with serde and error messages for untagged enums. If you have any insights / ideas would love to hear them. I was even thinking about looking into making a PR for better error messages for untagged enums :)

So untagged (and internally tagged) enums are interesting because they effectively "deserialize" into an internal data format which is private to serde and then think about that data and then re-deserialize into the relevant enum variants. Whereas adjacent-tagged enums (eg. {t="foo", c={bar:"baz"}} can actually run the deserializer once with the correct types involved from the start. I figure if you're getting unpleasant errors on untagged/internally-tagged enums then they might be related to that intermediate step of the serde::de::Content stuff.

wolfv commented 6 months ago

Yeah basically our problem is that serde simply reports: "Could not find any variant of enum PyPIDependency" or something along those lines.

It doesn't list the available fields, or the most likely variant (based on the matching keys, for example).

kinnison commented 6 months ago

Yeah basically our problem is that serde simply reports: "Could not find any variant of enum PyPIDependency" or something along those lines.

It doesn't list the available fields, or the most likely variant (based on the matching keys, for example).

My gut feeling is that the only way to diagnose that will be to run with a copy of serde you've augmented with debug info :(