bookdata/util/
serde_string.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//! Utility module for serializing with to/from string.
//!
//! This module is designed to be used with `#[serde(with)]`, as in:
//!
//! ```
//! # use serde::{Deserialize, Serialize};
//! # use serde_json::{to_value, json};
//! #[derive(Serialize, Deserialize, Debug)]
//! struct MyStruct {
//!   #[serde(with="bookdata::util::serde_string")]
//!   value: u64
//! }
//!
//! let jsv = to_value(MyStruct { value: 72 }).unwrap();
//! assert_eq!(jsv, json!({
//!   "value": "72"
//! }));
//! ```
//!
//! It will use [ToString] and [FromStr] to serialize and deserialize the data.
//!
// This isn't currently in use anywhere.
#![allow(dead_code)]
use std::fmt;
use std::marker::PhantomData;
use std::str::FromStr;

use serde::{de, Deserializer, Serializer};

pub fn serialize<S, T: ToString>(v: &T, ser: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    let vs = v.to_string();
    ser.serialize_str(vs.as_str())
}

struct FromStrVisitor<T> {
    _ph: PhantomData<T>,
}

pub fn deserialize<'de, D, T: FromStr>(de: D) -> Result<T, D::Error>
where
    D: Deserializer<'de>,
{
    de.deserialize_str(FromStrVisitor { _ph: PhantomData })
}

impl<'de, T: FromStr> de::Visitor<'de> for FromStrVisitor<T> {
    type Value = T;

    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(formatter, "a parsable string")
    }

    fn visit_str<E: de::Error>(self, s: &str) -> Result<Self::Value, E> {
        s.parse()
            .map_err(|_e| de::Error::invalid_value(de::Unexpected::Str(s), &self))
    }
}