serde
serde copied to clipboard
Add new field attributes: from/try_from/from_str/into
Addresses #1550.
The new field attributes from
, try_from
, from_str
and into
act as a shorthand for the deserialize_with
and serialize_with
attributes. They mirror the functionality found in the container attributes from
, try_from
and into
with the exception of from_str
, which is a new kind of attribute this PR adds. A field with the from_str
attribute first deserializes the field as a String
and then attempts to convert it into the correct type by calling FromStr::from_str
.
Example
#[derive(Debug, Deserialize)]
struct Foo {
#[serde(from = "i32")]
sign: Sign,
#[serde(from_str)]
number: u32,
}
#[derive(Debug, PartialEq)]
enum Sign {
Negative,
Zero,
Positive,
}
impl From<i32> for Sign {
fn from(v: i32) -> Sign {
match v {
_ if v < 0 => Sign::Negative,
_ if v == 0 => Sign::Zero,
_ => Sign::Positive
}
}
}
fn main() {
let json = r#"{ "sign": -1, "number": "14" }"#;
let foo: Foo = serde_json::from_str(json).unwrap();
assert_eq!(foo.sign, Sign::Negative);
assert_eq!(foo.number, 14);
}
@dtolnay , David, this is an interesting PR. This "from" / "into" approach can make for less boilerplate than with using variant type enums. I'm happy to spend some to finish what @nolanderc started, if you think it has legs.
@dtolnay what is the current status of this PR. The feature offered by it is interesting for me in a current project, so I would also be willing to put some time into this if that means it has a good chance of getting it merged.
If you're adding from_str
, then to_string
(or display
) would be pretty neat. It'd be nice not to have to write a wrapper for that.
Agree that this feature would be very useful
I also need exactly this!
Many crates implement e.g. From<String>
on their type, but have no serde
support.
Please add this feature. We need it!
Also, what is the best current workaround?
@jbirnick I do not know what the best is, but I am using deserialize_with = try_from_string_to_u32
of course this not working then for mixed types.