rust_release_channel/
serialization.rs1use 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}