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
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use response::{ContentType, Serializer, SerializerContext};
use util::Chain;
use util::tuple::Either2;

use bytes::Bytes;
use http::header::HeaderValue;
use serde::Serialize;

/// Default serializer
///
/// Serializes responses into one of a number of common HTTP formats.
#[derive(Debug, Clone)]
pub struct DefaultSerializer<T = ()> {
    custom: T,
    plain: HeaderValue,
    json: HeaderValue,
}

/// Response type
#[derive(Debug, Clone)]
pub struct Format {
    kind: Kind,
}

#[derive(Debug, Clone)]
enum Kind {
    Json,
    Plain,
}

const TEXT_PLAIN: &str = "text/plain";
const APPLICATION_JSON: &str = "application/json";

impl DefaultSerializer {
    /// Return a new `DefaultSerializer` value.
    pub fn new() -> DefaultSerializer {
        DefaultSerializer {
            custom: (),
            plain: HeaderValue::from_static(TEXT_PLAIN),
            json: HeaderValue::from_static(APPLICATION_JSON),
        }
    }
}

impl<T> Serializer for DefaultSerializer<T>
where T: Serializer,
{
    type Format = Either2<T::Format, Format>;

    fn lookup(&self, name: &str) -> Option<ContentType<Self::Format>> {
        if let Some(content_type) = self.custom.lookup(name) {
            return Some(content_type.map(Either2::A));
        }

        match name {
            "json" | APPLICATION_JSON => {
                let format = Either2::B(Format::json());
                Some(ContentType::new(self.json.clone(), format))
            }
            "plain" | TEXT_PLAIN => {
                let format = Either2::B(Format::plain());
                Some(ContentType::new(self.plain.clone(), format))
            }
            _ => {
                None
            }
        }
    }

    fn serialize<V>(&self, value: &V, format: &Self::Format, ctx: &SerializerContext)
        -> Result<Bytes, ::Error>
    where
        V: Serialize,
    {
        match format {
            Either2::A(ref format) => self.custom.serialize(value, format, ctx),
            Either2::B(ref format) => {
                match format.kind {
                    Kind::Json => {
                        let body = ::serde_json::to_vec(&value).unwrap();
                        Ok(body.into())
                    }
                    Kind::Plain => {
                        let body = ::serde_plain::to_string(&value).unwrap();
                        Ok(body.into())
                    }
                }
            }
        }
    }
}

impl<T, U> Chain<U> for DefaultSerializer<T> {
    type Output = DefaultSerializer<(T, U)>;

    fn chain(self, other: U) -> Self::Output {
        DefaultSerializer {
            custom: (self.custom, other),
            plain: self.plain,
            json: self.json,
        }
    }
}

impl<T> ::util::Sealed for DefaultSerializer<T> {}

impl Format {
    /// Json
    fn json() -> Format {
        Format { kind: Kind::Json }
    }

    /// Plain
    fn plain() -> Format {
        Format { kind: Kind::Plain }
    }
}