rust_release_channel/
serialization.rs

1//! A place to stick our custom serialization implementations
2//! so they don't clog up the main code.
3use chrono;
4use collections;
5use serde;
6use url_serde;
7
8impl serde::Serialize for super::Channel {
9    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
10    where
11        S: serde::Serializer,
12    {
13        #[derive(Serialize)]
14        struct EncodedChannel<'a> {
15            #[serde(rename = "manifest-version")]
16            manifest_version: &'a str,
17            date: &'a chrono::naive::NaiveDate,
18            #[serde(
19                skip_serializing_if = "::std::collections::BTreeMap::is_empty"
20            )]
21            pkg: &'a collections::BTreeMap<String, super::Package>,
22            #[serde(
23                skip_serializing_if = "::std::collections::BTreeMap::is_empty"
24            )]
25            renames: collections::BTreeMap<
26                &'a str,
27                collections::BTreeMap<&'a str, &'a str>,
28            >,
29        }
30
31        let mut fake_renames = collections::BTreeMap::new();
32        for (old_pkg, new_pkg) in self.renames.iter() {
33            let mut inner = collections::BTreeMap::new();
34            inner.insert("to", new_pkg.as_str());
35            fake_renames.insert(old_pkg.as_str(), inner);
36        }
37
38        let output = EncodedChannel {
39            manifest_version: "2",
40            date: &self.date,
41            pkg: &self.pkg,
42            renames: fake_renames,
43        };
44
45        output.serialize(serializer)
46    }
47}
48
49impl<'de> serde::Deserialize<'de> for super::Channel {
50    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
51    where
52        D: serde::Deserializer<'de>,
53    {
54        use serde::de::Error;
55
56        #[derive(Deserialize)]
57        #[serde(tag = "manifest-version")]
58        enum EncodedChannel {
59            #[serde(rename = "2")]
60            VersionTwo {
61                date: chrono::naive::NaiveDate,
62                #[serde(default)]
63                pkg: collections::BTreeMap<String, super::Package>,
64                #[serde(default)]
65                renames: collections::BTreeMap<
66                    String,
67                    collections::BTreeMap<String, String>,
68                >,
69            },
70        }
71
72        match EncodedChannel::deserialize(deserializer)? {
73            EncodedChannel::VersionTwo { date, pkg, renames } => {
74                let mut fixed_renames = collections::BTreeMap::new();
75                for (old_pkg, mut inner_map) in renames {
76                    let new_pkg = inner_map
77                        .remove("to")
78                        .ok_or(D::Error::missing_field("to"))?;
79                    fixed_renames.insert(old_pkg, new_pkg);
80                }
81
82                Ok(super::Channel {
83                    date: date,
84                    pkg: pkg,
85                    renames: fixed_renames,
86                })
87            }
88        }
89    }
90}
91
92impl serde::Serialize for super::Artefact {
93    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
94    where
95        S: serde::Serializer,
96    {
97        fn slice_is_empty<T>(s: &[T]) -> bool {
98            s.is_empty()
99        }
100
101        #[derive(Serialize, Default, Debug)]
102        struct EncodedArtefact<'a> {
103            available: bool,
104            url: Option<url_serde::SerdeUrl>,
105            hash: Option<&'a str>,
106            xz_url: Option<url_serde::SerdeUrl>,
107            xz_hash: Option<&'a str>,
108            #[serde(skip_serializing_if = "slice_is_empty")]
109            components: &'a [super::ArtefactToken],
110            #[serde(skip_serializing_if = "slice_is_empty")]
111            extensions: &'a [super::ArtefactToken],
112        }
113
114        let mut output = EncodedArtefact::default();
115
116        output.available = !self.standalone.is_empty();
117
118        self.standalone
119            .get(&super::ArchiveFormat::TarGzip)
120            .map(|src| {
121                output.url = Some(url_serde::Serde(src.url.clone()));
122                output.hash = Some(&src.hash);
123            });
124        self.standalone
125            .get(&super::ArchiveFormat::TarXz)
126            .map(|src| {
127                output.xz_url = Some(url_serde::Serde(src.url.clone()));
128                output.xz_hash = Some(&src.hash);
129            });
130
131        output.components = &self.components;
132        output.extensions = &self.extensions;
133
134        output.serialize(serializer)
135    }
136}
137
138impl<'de> serde::Deserialize<'de> for super::Artefact {
139    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
140    where
141        D: serde::Deserializer<'de>,
142    {
143        #[derive(Deserialize, Debug)]
144        struct EncodedArtefact {
145            available: bool,
146            url: Option<url_serde::SerdeUrl>,
147            hash: Option<String>,
148            xz_url: Option<url_serde::SerdeUrl>,
149            xz_hash: Option<String>,
150            #[serde(default)]
151            components: Vec<super::ArtefactToken>,
152            #[serde(default)]
153            extensions: Vec<super::ArtefactToken>,
154        }
155
156        let input = EncodedArtefact::deserialize(deserializer)?;
157
158        let mut output = super::Artefact::default();
159
160        if let (Some(url), Some(hash)) = (input.url, input.hash) {
161            output.standalone.insert(
162                super::ArchiveFormat::TarGzip,
163                super::ArchiveSource::new(url.into_inner(), hash),
164            );
165        }
166
167        if let (Some(url), Some(hash)) = (input.xz_url, input.xz_hash) {
168            output.standalone.insert(
169                super::ArchiveFormat::TarXz,
170                super::ArchiveSource::new(url.into_inner(), hash),
171            );
172        }
173
174        output.components = input.components;
175        output.extensions = input.extensions;
176
177        Ok(output)
178    }
179}