tower_web/response/
default_serializer.rs1use response::{ContentType, Serializer, SerializerContext};
2use util::Chain;
3use util::tuple::Either2;
4
5use bytes::Bytes;
6use http::header::HeaderValue;
7use serde::Serialize;
8
9#[derive(Debug, Clone)]
13pub struct DefaultSerializer<T = ()> {
14 custom: T,
15 plain: HeaderValue,
16 json: HeaderValue,
17}
18
19#[derive(Debug, Clone)]
21pub struct Format {
22 kind: Kind,
23}
24
25#[derive(Debug, Clone)]
26enum Kind {
27 Json,
28 Plain,
29}
30
31const TEXT_PLAIN: &str = "text/plain";
32const APPLICATION_JSON: &str = "application/json";
33
34impl DefaultSerializer {
35 pub fn new() -> DefaultSerializer {
37 DefaultSerializer {
38 custom: (),
39 plain: HeaderValue::from_static(TEXT_PLAIN),
40 json: HeaderValue::from_static(APPLICATION_JSON),
41 }
42 }
43}
44
45impl<T> Serializer for DefaultSerializer<T>
46where T: Serializer,
47{
48 type Format = Either2<T::Format, Format>;
49
50 fn lookup(&self, name: &str) -> Option<ContentType<Self::Format>> {
51 if let Some(content_type) = self.custom.lookup(name) {
52 return Some(content_type.map(Either2::A));
53 }
54
55 match name {
56 "json" | APPLICATION_JSON => {
57 let format = Either2::B(Format::json());
58 Some(ContentType::new(self.json.clone(), format))
59 }
60 "plain" | TEXT_PLAIN => {
61 let format = Either2::B(Format::plain());
62 Some(ContentType::new(self.plain.clone(), format))
63 }
64 _ => {
65 None
66 }
67 }
68 }
69
70 fn serialize<V>(&self, value: &V, format: &Self::Format, ctx: &SerializerContext)
71 -> Result<Bytes, ::Error>
72 where
73 V: Serialize,
74 {
75 match format {
76 Either2::A(ref format) => self.custom.serialize(value, format, ctx),
77 Either2::B(ref format) => {
78 match format.kind {
79 Kind::Json => {
80 let body = ::serde_json::to_vec(&value).unwrap();
81 Ok(body.into())
82 }
83 Kind::Plain => {
84 let body = ::serde_plain::to_string(&value).unwrap();
85 Ok(body.into())
86 }
87 }
88 }
89 }
90 }
91}
92
93impl<T, U> Chain<U> for DefaultSerializer<T> {
94 type Output = DefaultSerializer<(T, U)>;
95
96 fn chain(self, other: U) -> Self::Output {
97 DefaultSerializer {
98 custom: (self.custom, other),
99 plain: self.plain,
100 json: self.json,
101 }
102 }
103}
104
105impl<T> ::util::Sealed for DefaultSerializer<T> {}
106
107impl Format {
108 fn json() -> Format {
110 Format { kind: Kind::Json }
111 }
112
113 fn plain() -> Format {
115 Format { kind: Kind::Plain }
116 }
117}