1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6use super::types::Package;
7
8const PACKAGE_SERIALIZED_FIELD_COUNT: usize = 35;
10
11impl Serialize for Package {
12 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
13 where
14 S: serde::Serializer,
15 {
16 use serde::ser::SerializeStruct;
17 let mut state = serializer.serialize_struct("Package", PACKAGE_SERIALIZED_FIELD_COUNT)?;
18 state.serialize_field("name", &self.name)?;
19 state.serialize_field("version", &self.version)?;
20 state.serialize_field("description", &self.description)?;
21 state.serialize_field("authors", &self.authors)?;
22 state.serialize_field("requires", &self.requires)?;
23 state.serialize_field("build_requires", &self.build_requires)?;
24 state.serialize_field("private_build_requires", &self.private_build_requires)?;
25 state.serialize_field("variants", &self.variants)?;
26 state.serialize_field("tools", &self.tools)?;
27 state.serialize_field("commands", &self.commands)?;
28 state.serialize_field("build_command", &self.build_command)?;
29 state.serialize_field("build_system", &self.build_system)?;
30 state.serialize_field("pre_commands", &self.pre_commands)?;
31 state.serialize_field("post_commands", &self.post_commands)?;
32 state.serialize_field("pre_test_commands", &self.pre_test_commands)?;
33 state.serialize_field("pre_build_commands", &self.pre_build_commands)?;
34 state.serialize_field("tests", &self.tests)?;
35 state.serialize_field("requires_rez_version", &self.requires_rez_version)?;
36 state.serialize_field("uuid", &self.uuid)?;
37 state.serialize_field("help", &self.help)?;
39 state.serialize_field("relocatable", &self.relocatable)?;
40 state.serialize_field("cachable", &self.cachable)?;
41 state.serialize_field("timestamp", &self.timestamp)?;
42 state.serialize_field("revision", &self.revision)?;
43 state.serialize_field("changelog", &self.changelog)?;
44 state.serialize_field("release_message", &self.release_message)?;
45 state.serialize_field("previous_version", &self.previous_version)?;
46 state.serialize_field("previous_revision", &self.previous_revision)?;
47 state.serialize_field("vcs", &self.vcs)?;
48 state.serialize_field("format_version", &self.format_version)?;
49 state.serialize_field("base", &self.base)?;
50 state.serialize_field("has_plugins", &self.has_plugins)?;
51 state.serialize_field("plugin_for", &self.plugin_for)?;
52 state.serialize_field("hashed_variants", &self.hashed_variants)?;
53 state.serialize_field("preprocess", &self.preprocess)?;
54 state.end()
55 }
56}
57
58impl<'de> Deserialize<'de> for Package {
59 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60 where
61 D: serde::Deserializer<'de>,
62 {
63 use serde::de::{self, MapAccess, SeqAccess, Visitor};
64 use std::fmt;
65
66 #[derive(Deserialize)]
67 #[serde(field_identifier, rename_all = "snake_case")]
68 enum Field {
69 Name,
70 Version,
71 Description,
72 Authors,
73 Requires,
74 BuildRequires,
75 PrivateBuildRequires,
76 Variants,
77 Tools,
78 Commands,
79 BuildCommand,
80 BuildSystem,
81 PreCommands,
82 PostCommands,
83 PreTestCommands,
84 PreBuildCommands,
85 Tests,
86 RequiresRezVersion,
87 Uuid,
88 Help,
89 Relocatable,
90 Cachable,
91 Timestamp,
92 Revision,
93 Changelog,
94 ReleaseMessage,
95 PreviousVersion,
96 PreviousRevision,
97 Vcs,
98 FormatVersion,
99 Base,
100 HasPlugins,
101 PluginFor,
102 HashedVariants,
103 Preprocess,
104 IsDevPackage,
105 }
106
107 struct PackageVisitor;
108
109 impl<'de> Visitor<'de> for PackageVisitor {
110 type Value = Package;
111
112 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
113 formatter.write_str("struct Package")
114 }
115
116 fn visit_seq<V>(self, mut seq: V) -> Result<Package, V::Error>
117 where
118 V: SeqAccess<'de>,
119 {
120 let name = seq
121 .next_element()?
122 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
123 let version = seq
124 .next_element()?
125 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
126 let description = seq
127 .next_element()?
128 .ok_or_else(|| de::Error::invalid_length(2, &self))?;
129 let authors = seq
130 .next_element()?
131 .ok_or_else(|| de::Error::invalid_length(3, &self))?;
132 let requires = seq
133 .next_element()?
134 .ok_or_else(|| de::Error::invalid_length(4, &self))?;
135 let build_requires = seq
136 .next_element()?
137 .ok_or_else(|| de::Error::invalid_length(5, &self))?;
138 let private_build_requires = seq
139 .next_element()?
140 .ok_or_else(|| de::Error::invalid_length(6, &self))?;
141 let variants = seq
142 .next_element()?
143 .ok_or_else(|| de::Error::invalid_length(7, &self))?;
144 let tools = seq
145 .next_element()?
146 .ok_or_else(|| de::Error::invalid_length(8, &self))?;
147 let commands = seq
148 .next_element()?
149 .ok_or_else(|| de::Error::invalid_length(9, &self))?;
150 let build_command = seq
151 .next_element()?
152 .ok_or_else(|| de::Error::invalid_length(10, &self))?;
153 let build_system = seq
154 .next_element()?
155 .ok_or_else(|| de::Error::invalid_length(11, &self))?;
156 let pre_commands = seq
157 .next_element()?
158 .ok_or_else(|| de::Error::invalid_length(12, &self))?;
159 let post_commands = seq
160 .next_element()?
161 .ok_or_else(|| de::Error::invalid_length(13, &self))?;
162 let pre_test_commands = seq
163 .next_element()?
164 .ok_or_else(|| de::Error::invalid_length(14, &self))?;
165 let pre_build_commands = seq
166 .next_element()?
167 .ok_or_else(|| de::Error::invalid_length(15, &self))?;
168 let tests = seq
169 .next_element()?
170 .ok_or_else(|| de::Error::invalid_length(16, &self))?;
171 let requires_rez_version = seq
172 .next_element()?
173 .ok_or_else(|| de::Error::invalid_length(17, &self))?;
174 let uuid = seq
175 .next_element()?
176 .ok_or_else(|| de::Error::invalid_length(18, &self))?;
177 let help = seq
178 .next_element()?
179 .ok_or_else(|| de::Error::invalid_length(19, &self))?;
180 let relocatable = seq
181 .next_element()?
182 .ok_or_else(|| de::Error::invalid_length(20, &self))?;
183 let cachable = seq
184 .next_element()?
185 .ok_or_else(|| de::Error::invalid_length(21, &self))?;
186 let timestamp = seq
187 .next_element()?
188 .ok_or_else(|| de::Error::invalid_length(22, &self))?;
189 let revision = seq
190 .next_element()?
191 .ok_or_else(|| de::Error::invalid_length(23, &self))?;
192 let changelog = seq
193 .next_element()?
194 .ok_or_else(|| de::Error::invalid_length(24, &self))?;
195 let release_message = seq
196 .next_element()?
197 .ok_or_else(|| de::Error::invalid_length(25, &self))?;
198 let previous_version = seq
199 .next_element()?
200 .ok_or_else(|| de::Error::invalid_length(26, &self))?;
201 let previous_revision = seq
202 .next_element()?
203 .ok_or_else(|| de::Error::invalid_length(27, &self))?;
204 let vcs = seq
205 .next_element()?
206 .ok_or_else(|| de::Error::invalid_length(28, &self))?;
207 let format_version = seq
208 .next_element()?
209 .ok_or_else(|| de::Error::invalid_length(29, &self))?;
210 let base = seq
211 .next_element()?
212 .ok_or_else(|| de::Error::invalid_length(30, &self))?;
213 let has_plugins = seq
214 .next_element()?
215 .ok_or_else(|| de::Error::invalid_length(31, &self))?;
216 let plugin_for = seq
217 .next_element()?
218 .ok_or_else(|| de::Error::invalid_length(32, &self))?;
219 let hashed_variants = seq
220 .next_element()?
221 .ok_or_else(|| de::Error::invalid_length(33, &self))?;
222 let preprocess = seq
223 .next_element()?
224 .ok_or_else(|| de::Error::invalid_length(34, &self))?;
225 let is_dev_package = seq
226 .next_element()?
227 .ok_or_else(|| de::Error::invalid_length(35, &self))?;
228
229 Ok(Package {
230 name,
231 version,
232 description,
233 authors,
234 requires,
235 build_requires,
236 private_build_requires,
237 variants,
238 tools,
239 commands,
240 commands_function: None,
241 build_command,
242 build_system,
243 pre_commands,
244 post_commands,
245 pre_test_commands,
246 pre_build_commands,
247 tests,
248 requires_rez_version,
249 uuid,
250 config: HashMap::new(),
251 help,
252 relocatable,
253 cachable,
254 timestamp,
255 revision,
256 changelog,
257 release_message,
258 previous_version,
259 previous_revision,
260 vcs,
261 format_version,
262 base,
263 has_plugins,
264 plugin_for,
265 hashed_variants,
266 preprocess,
267 is_dev_package,
268 filepath: None,
269 includes: None,
270 })
271 }
272
273 fn visit_map<V>(self, mut map: V) -> Result<Package, V::Error>
274 where
275 V: MapAccess<'de>,
276 {
277 let mut name = None;
278 let mut version = None;
279 let mut description = None;
280 let mut authors = None;
281 let mut requires = None;
282 let mut build_requires = None;
283 let mut private_build_requires = None;
284 let mut variants = None;
285 let mut tools = None;
286 let mut commands = None;
287 let mut build_command = None;
288 let mut build_system = None;
289 let mut pre_commands = None;
290 let mut post_commands = None;
291 let mut pre_test_commands = None;
292 let mut pre_build_commands = None;
293 let mut tests = None;
294 let mut requires_rez_version = None;
295 let mut uuid = None;
296 let mut help = None;
297 let mut relocatable = None;
298 let mut cachable = None;
299 let mut timestamp = None;
300 let mut revision = None;
301 let mut changelog = None;
302 let mut release_message = None;
303 let mut previous_version = None;
304 let mut previous_revision = None;
305 let mut vcs = None;
306 let mut format_version = None;
307 let mut base = None;
308 let mut has_plugins = None;
309 let mut plugin_for = None;
310 let mut hashed_variants = None;
311 let mut preprocess = None;
312 let mut is_dev_package = None;
313
314 while let Some(key) = map.next_key()? {
315 match key {
316 Field::Name => {
317 if name.is_some() {
318 return Err(de::Error::duplicate_field("name"));
319 }
320 name = Some(map.next_value()?);
321 }
322 Field::Version => {
323 if version.is_some() {
324 return Err(de::Error::duplicate_field("version"));
325 }
326 version = Some(map.next_value()?);
327 }
328 Field::Description => {
329 if description.is_some() {
330 return Err(de::Error::duplicate_field("description"));
331 }
332 description = Some(map.next_value()?);
333 }
334 Field::Authors => {
335 if authors.is_some() {
336 return Err(de::Error::duplicate_field("authors"));
337 }
338 authors = Some(map.next_value()?);
339 }
340 Field::Requires => {
341 if requires.is_some() {
342 return Err(de::Error::duplicate_field("requires"));
343 }
344 requires = Some(map.next_value()?);
345 }
346 Field::BuildRequires => {
347 if build_requires.is_some() {
348 return Err(de::Error::duplicate_field("build_requires"));
349 }
350 build_requires = Some(map.next_value()?);
351 }
352 Field::PrivateBuildRequires => {
353 if private_build_requires.is_some() {
354 return Err(de::Error::duplicate_field("private_build_requires"));
355 }
356 private_build_requires = Some(map.next_value()?);
357 }
358 Field::Variants => {
359 if variants.is_some() {
360 return Err(de::Error::duplicate_field("variants"));
361 }
362 variants = Some(map.next_value()?);
363 }
364 Field::Tools => {
365 if tools.is_some() {
366 return Err(de::Error::duplicate_field("tools"));
367 }
368 tools = Some(map.next_value()?);
369 }
370 Field::Commands => {
371 if commands.is_some() {
372 return Err(de::Error::duplicate_field("commands"));
373 }
374 commands = Some(map.next_value()?);
375 }
376 Field::BuildCommand => {
377 if build_command.is_some() {
378 return Err(de::Error::duplicate_field("build_command"));
379 }
380 build_command = Some(map.next_value()?);
381 }
382 Field::BuildSystem => {
383 if build_system.is_some() {
384 return Err(de::Error::duplicate_field("build_system"));
385 }
386 build_system = Some(map.next_value()?);
387 }
388 Field::PreCommands => {
389 if pre_commands.is_some() {
390 return Err(de::Error::duplicate_field("pre_commands"));
391 }
392 pre_commands = Some(map.next_value()?);
393 }
394 Field::PostCommands => {
395 if post_commands.is_some() {
396 return Err(de::Error::duplicate_field("post_commands"));
397 }
398 post_commands = Some(map.next_value()?);
399 }
400 Field::PreTestCommands => {
401 if pre_test_commands.is_some() {
402 return Err(de::Error::duplicate_field("pre_test_commands"));
403 }
404 pre_test_commands = Some(map.next_value()?);
405 }
406 Field::PreBuildCommands => {
407 if pre_build_commands.is_some() {
408 return Err(de::Error::duplicate_field("pre_build_commands"));
409 }
410 pre_build_commands = Some(map.next_value()?);
411 }
412 Field::Tests => {
413 if tests.is_some() {
414 return Err(de::Error::duplicate_field("tests"));
415 }
416 tests = Some(map.next_value()?);
417 }
418 Field::RequiresRezVersion => {
419 if requires_rez_version.is_some() {
420 return Err(de::Error::duplicate_field("requires_rez_version"));
421 }
422 requires_rez_version = Some(map.next_value()?);
423 }
424 Field::Uuid => {
425 if uuid.is_some() {
426 return Err(de::Error::duplicate_field("uuid"));
427 }
428 uuid = Some(map.next_value()?);
429 }
430 Field::Help => {
431 if help.is_some() {
432 return Err(de::Error::duplicate_field("help"));
433 }
434 help = Some(map.next_value()?);
435 }
436 Field::Relocatable => {
437 if relocatable.is_some() {
438 return Err(de::Error::duplicate_field("relocatable"));
439 }
440 relocatable = Some(map.next_value()?);
441 }
442 Field::Cachable => {
443 if cachable.is_some() {
444 return Err(de::Error::duplicate_field("cachable"));
445 }
446 cachable = Some(map.next_value()?);
447 }
448 Field::Timestamp => {
449 if timestamp.is_some() {
450 return Err(de::Error::duplicate_field("timestamp"));
451 }
452 timestamp = Some(map.next_value()?);
453 }
454 Field::Revision => {
455 if revision.is_some() {
456 return Err(de::Error::duplicate_field("revision"));
457 }
458 revision = Some(map.next_value()?);
459 }
460 Field::Changelog => {
461 if changelog.is_some() {
462 return Err(de::Error::duplicate_field("changelog"));
463 }
464 changelog = Some(map.next_value()?);
465 }
466 Field::ReleaseMessage => {
467 if release_message.is_some() {
468 return Err(de::Error::duplicate_field("release_message"));
469 }
470 release_message = Some(map.next_value()?);
471 }
472 Field::PreviousVersion => {
473 if previous_version.is_some() {
474 return Err(de::Error::duplicate_field("previous_version"));
475 }
476 previous_version = Some(map.next_value()?);
477 }
478 Field::PreviousRevision => {
479 if previous_revision.is_some() {
480 return Err(de::Error::duplicate_field("previous_revision"));
481 }
482 previous_revision = Some(map.next_value()?);
483 }
484 Field::Vcs => {
485 if vcs.is_some() {
486 return Err(de::Error::duplicate_field("vcs"));
487 }
488 vcs = Some(map.next_value()?);
489 }
490 Field::FormatVersion => {
491 if format_version.is_some() {
492 return Err(de::Error::duplicate_field("format_version"));
493 }
494 format_version = Some(map.next_value()?);
495 }
496 Field::Base => {
497 if base.is_some() {
498 return Err(de::Error::duplicate_field("base"));
499 }
500 base = Some(map.next_value()?);
501 }
502 Field::HasPlugins => {
503 if has_plugins.is_some() {
504 return Err(de::Error::duplicate_field("has_plugins"));
505 }
506 has_plugins = Some(map.next_value()?);
507 }
508 Field::PluginFor => {
509 if plugin_for.is_some() {
510 return Err(de::Error::duplicate_field("plugin_for"));
511 }
512 plugin_for = Some(map.next_value()?);
513 }
514 Field::HashedVariants => {
515 if hashed_variants.is_some() {
516 return Err(de::Error::duplicate_field("hashed_variants"));
517 }
518 hashed_variants = Some(map.next_value()?);
519 }
520 Field::Preprocess => {
521 if preprocess.is_some() {
522 return Err(de::Error::duplicate_field("preprocess"));
523 }
524 preprocess = Some(map.next_value()?);
525 }
526 Field::IsDevPackage => {
527 if is_dev_package.is_some() {
528 return Err(de::Error::duplicate_field("is_dev_package"));
529 }
530 is_dev_package = Some(map.next_value()?);
531 }
532 }
533 }
534
535 let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
536 Ok(Package {
537 name,
538 version: version.unwrap_or(None),
539 description: description.unwrap_or(None),
540 authors: authors.unwrap_or_default(),
541 requires: requires.unwrap_or_default(),
542 build_requires: build_requires.unwrap_or_default(),
543 private_build_requires: private_build_requires.unwrap_or_default(),
544 variants: variants.unwrap_or_default(),
545 tools: tools.unwrap_or_default(),
546 commands: commands.unwrap_or(None),
547 commands_function: None,
548 build_command: build_command.unwrap_or(None),
549 build_system: build_system.unwrap_or(None),
550 pre_commands: pre_commands.unwrap_or(None),
551 post_commands: post_commands.unwrap_or(None),
552 pre_test_commands: pre_test_commands.unwrap_or(None),
553 pre_build_commands: pre_build_commands.unwrap_or(None),
554 tests: tests.unwrap_or_default(),
555 requires_rez_version: requires_rez_version.unwrap_or(None),
556 uuid: uuid.unwrap_or(None),
557 config: HashMap::new(),
558 help: help.unwrap_or(None),
559 relocatable: relocatable.unwrap_or(None),
560 cachable: cachable.unwrap_or(None),
561 timestamp: timestamp.unwrap_or(None),
562 revision: revision.unwrap_or(None),
563 changelog: changelog.unwrap_or(None),
564 release_message: release_message.unwrap_or(None),
565 previous_version: previous_version.unwrap_or(None),
566 previous_revision: previous_revision.unwrap_or(None),
567 vcs: vcs.unwrap_or(None),
568 format_version: format_version.unwrap_or(None),
569 base: base.unwrap_or(None),
570 has_plugins: has_plugins.unwrap_or(None),
571 plugin_for: plugin_for.unwrap_or_default(),
572 hashed_variants: hashed_variants.unwrap_or(None),
573 preprocess: preprocess.unwrap_or(None),
574 is_dev_package: is_dev_package.unwrap_or(None),
575 filepath: None,
576 includes: None,
577 })
578 }
579 }
580
581 const FIELDS: &[&str] = &[
582 "name",
583 "version",
584 "description",
585 "authors",
586 "requires",
587 "build_requires",
588 "private_build_requires",
589 "variants",
590 "tools",
591 "commands",
592 "build_command",
593 "build_system",
594 "pre_commands",
595 "post_commands",
596 "pre_test_commands",
597 "pre_build_commands",
598 "tests",
599 "requires_rez_version",
600 "uuid",
601 "help",
602 "relocatable",
603 "cachable",
604 "timestamp",
605 "revision",
606 "changelog",
607 "release_message",
608 "previous_version",
609 "previous_revision",
610 "vcs",
611 "format_version",
612 "base",
613 "has_plugins",
614 "plugin_for",
615 "hashed_variants",
616 "preprocess",
617 "is_dev_package",
618 ];
619 deserializer.deserialize_struct("Package", FIELDS, PackageVisitor)
620 }
621}