Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use serde::{Deserialize, Deserializer};
- use std::collections::HashMap;
- use std::fmt;
- /// Just try to serialize a `Foo`.
- fn main() {
- let s = "features = ['Jerry', 'Jerry']\n\n[aliases]\nfoo='Jerry'\n";
- let _: GoodHelper<'_> = dbg!(toml::from_str(s).unwrap());
- let _: BadHelper<'_> = dbg!(toml::from_str(s).unwrap());
- let _: Foo = dbg!(toml::from_str(s).unwrap());
- }
- /// A container of `Jerry`. This can be created via `GoodHelper`, but not via
- /// `BadHelper`, for some reason.
- #[derive(Debug, Default, Deserialize)]
- #[serde(from = "BadHelper")] // <-- change this to GoodHelper
- struct Foo {
- everything: Vec<Jerry>,
- }
- /// A `Foo` can be created from the helper by just collecting `Jerry`.
- impl From<GoodHelper<'_>> for Foo {
- fn from(helper: GoodHelper<'_>) -> Self {
- let mut res = Foo::default();
- res.everything.extend(helper.aliases.values());
- res
- }
- }
- /// A `Foo` can be created from the helper by just collecting `Jerry`.
- impl From<BadHelper<'_>> for Foo {
- fn from(helper: BadHelper<'_>) -> Self {
- let mut res = Foo::default();
- res.everything.extend(helper.aliases.values().cloned());
- res
- }
- }
- /// Creating `Foo` via this helper works.
- #[derive(Debug, Deserialize)]
- #[serde(rename = "foo")]
- struct GoodHelper<'a> {
- #[serde(borrow)]
- aliases: HashMap<&'a str, Jerry>,
- }
- /// Creating `Foo` via this helper doesn't work.
- /// Creating the helper itself *does* work, however.
- #[derive(Debug, Deserialize)]
- #[serde(rename = "foo")]
- struct BadHelper<'a> {
- #[serde(borrow)]
- aliases: HashMap<&'a str, StaticJerry>,
- }
- type StaticJerry = &'static Jerry;
- /// Jerry.
- #[derive(Debug, Clone, Copy)]
- struct Jerry;
- /// You can deserialize `Jerry` …
- impl<'de> Deserialize<'de> for Jerry {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- use serde::de::Error;
- use serde::de::Unexpected;
- struct Visitor;
- impl<'de> serde::de::Visitor<'de> for Visitor {
- type Value = Jerry;
- fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str("Jerry")
- }
- fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
- where
- E: Error,
- {
- match v {
- "Jerry" => Ok(Jerry),
- _ => Err(Error::invalid_value(Unexpected::Str(v), &self)),
- }
- }
- }
- deserializer.deserialize_str(Visitor)
- }
- }
- /// … but you can also deserialize `&'stati Jerry`.
- impl<'de> Deserialize<'de> for &'static Jerry {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- use serde::de::Error;
- use serde::de::Unexpected;
- struct Visitor;
- impl<'de> serde::de::Visitor<'de> for Visitor {
- type Value = &'static Jerry;
- fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str("Jerry")
- }
- fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
- where
- E: Error,
- {
- match v {
- "Jerry" => Ok(&Jerry),
- _ => Err(Error::invalid_value(Unexpected::Str(v), &self)),
- }
- }
- }
- deserializer.deserialize_str(Visitor)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement