jonasbb / serde_with

This crate provides custom de/serialization helpers to use in combination with serde's `with`-annotation and with the improved `serde_as`-annotation.
https://docs.rs/serde_with
Apache License 2.0
646 stars 69 forks source link

Feature request: per-container prefix #641

Open jaskij opened 1 year ago

jaskij commented 1 year ago

Rather than set the prefix at the point of use, I'd like to set it on a container, essentially just prepending it to the rename value for all fields.

My use case is working with Wireshark's packet dissection JSON, which likes to prepend an object's name to all the field names inside said object, although the prefix is not always exact.

TBH, I'm not sure if this feature is better suited here, or in serde proper.

        "ip": {
          "ip.version": "4",
          "ip.hdr_len": "20",
          "ip.dsfield": "0x00",
          "ip.dsfield_tree": {
            "ip.dsfield.dscp": "0",
            "ip.dsfield.ecn": "0"
          },
          "ip.len": "101",
          "ip.id": "0xe2f4",
          "ip.flags": "0x00",
          "ip.flags_tree": {
            "ip.flags.rb": "0",
            "ip.flags.df": "0",
            "ip.flags.mf": "0"
          },
          "ip.frag_offset": "0",
          "ip.ttl": "30",
          "ip.proto": "6",
          "ip.checksum": "0x237c",
          "ip.checksum.status": "2",
          "ip.src": "192.168.10.101",
          "ip.addr": "192.168.10.109",
          "ip.src_host": "192.168.10.101",
          "ip.host": "192.168.10.109",
          "ip.dst": "192.168.10.109",
          "ip.dst_host": "192.168.10.109"
        },
jonasbb commented 10 months ago

I am not sure it, this works well as a container attribute. It seems like you want this prefix to apply recursively, i.e., in the case of ip.dsfield.dscp having two prefixes, first dsfield. and then afterwards ip.. If you want to treat ip.dsfield. as a single prefix, then it might work. But that also means that it is bound to only structs which perform prefixing of ip. too.

Overall, I am open to providing some rename capabilities. From time to time, there are feature requests to serde for different patterns. A rename macro would place a matching #[serde(rename = "...")] on every field. This could include functionality for prefixing/suffixing too. I would welcome contributions for that.

jaskij commented 10 months ago

Ideally, yes, it'd be recursive. But thinking on it further, that'd probably be very hard (if at all possible). Single-level implementation would still be very useful.

I haven't looked at your sources, are those proc macros or regular ones? I must profess to have no experience with either.

jonasbb commented 10 months ago

You would need a proc-macro for this to work because you would need various computations to be executed at compile time. Getting started with proc-macros is quite a bit, due to the very specific nature and the needed crates. Otherwise, the proc-macro wouldn't be too complicated. It needs to go over all fields and find all the prefix/suffix/rename rules and combine them.

Beside prefixes, the macro could collect other rename patterns, like https://github.com/serde-rs/serde/pull/2571 or https://github.com/serde-rs/serde/pull/2657 or https://github.com/serde-rs/serde/issues/1724.

xamgore commented 3 months ago

Here it is: https://docs.rs/serde_prefix/latest/src/serde_prefix/lib.rs.html#1-77