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
use std::{convert::Infallible, marker::PhantomData, str::FromStr};

use super::Format;

/// A format that uses ToString and FromStr to parse to and from a string representation.
///
/// This is a good choice if you have a type that has non-structured string
/// serialization needs, like for Uuids or IP addresses.
pub struct Parse<Out, In = Out>(PhantomData<Out>, PhantomData<In>)
where
    In: ?Sized + ToString,
    Out: FromStr,
    <Out as FromStr>::Err: std::error::Error;

impl<Out, In> Format for Parse<Out, In>
where
    In: ?Sized + ToString,
    Out: FromStr,
    <Out as FromStr>::Err: std::error::Error,
{
    type Out = Out;
    type In = In;
    type Buffer = String;
    type SerializeError = Infallible;
    type DeserializeError = <Out as FromStr>::Err;

    fn sql_type() -> &'static str {
        "TEXT"
    }

    fn serialize(object: &Self::In) -> Result<Self::Buffer, Self::SerializeError> {
        Ok(object.to_string())
    }

    fn deserialize(data: &Self::Buffer) -> Result<Self::Out, Self::DeserializeError> {
        data.parse()
    }
}