1 | use crate::dependencies::{Dependency, Patch, RegistryPatch, TargetDependencies}; |
2 | use serde::ser::{SerializeMap, Serializer}; |
3 | use serde_derive::{Deserialize, Serialize}; |
4 | use std::collections::BTreeMap as Map; |
5 | use std::ffi::OsStr; |
6 | use std::path::PathBuf; |
7 | |
8 | #[derive(Serialize, Debug)] |
9 | pub struct Manifest { |
10 | pub package: Package, |
11 | #[serde(skip_serializing_if = "Map::is_empty" )] |
12 | pub features: Map<String, Vec<String>>, |
13 | pub dependencies: Map<String, Dependency>, |
14 | #[serde(skip_serializing_if = "Map::is_empty" )] |
15 | pub target: Map<String, TargetDependencies>, |
16 | #[serde(rename = "bin" )] |
17 | pub bins: Vec<Bin>, |
18 | #[serde(skip_serializing_if = "Option::is_none" )] |
19 | pub workspace: Option<Workspace>, |
20 | #[serde( |
21 | serialize_with = "serialize_patch" , |
22 | skip_serializing_if = "empty_patch" |
23 | )] |
24 | pub patch: Map<String, RegistryPatch>, |
25 | #[serde(skip_serializing_if = "Map::is_empty" )] |
26 | pub replace: Map<String, Patch>, |
27 | } |
28 | |
29 | #[derive(Serialize, Debug)] |
30 | pub struct Package { |
31 | pub name: String, |
32 | pub version: String, |
33 | pub edition: Edition, |
34 | #[serde(skip_serializing_if = "Option::is_none" )] |
35 | pub resolver: Option<String>, |
36 | pub publish: bool, |
37 | } |
38 | |
39 | #[derive(Serialize, Deserialize, Debug)] |
40 | pub enum Edition { |
41 | #[serde(rename = "2015" )] |
42 | E2015, |
43 | #[serde(rename = "2018" )] |
44 | E2018, |
45 | #[serde(rename = "2021" )] |
46 | E2021, |
47 | } |
48 | |
49 | #[derive(Serialize, Debug)] |
50 | pub struct Bin { |
51 | pub name: Name, |
52 | pub path: PathBuf, |
53 | } |
54 | |
55 | #[derive(Serialize, Clone, Debug)] |
56 | pub struct Name(pub String); |
57 | |
58 | #[derive(Serialize, Debug)] |
59 | pub struct Config { |
60 | pub build: Build, |
61 | } |
62 | |
63 | #[derive(Serialize, Debug)] |
64 | pub struct Build { |
65 | pub rustflags: Vec<&'static str>, |
66 | } |
67 | |
68 | #[derive(Serialize, Debug)] |
69 | pub struct Workspace { |
70 | #[serde(skip_serializing_if = "Map::is_empty" )] |
71 | pub dependencies: Map<String, Dependency>, |
72 | } |
73 | |
74 | impl Default for Edition { |
75 | fn default() -> Self { |
76 | Edition::E2018 |
77 | } |
78 | } |
79 | |
80 | impl AsRef<OsStr> for Name { |
81 | fn as_ref(&self) -> &OsStr { |
82 | self.0.as_ref() |
83 | } |
84 | } |
85 | |
86 | fn serialize_patch<S>(patch: &Map<String, RegistryPatch>, serializer: S) -> Result<S::Ok, S::Error> |
87 | where |
88 | S: Serializer, |
89 | { |
90 | let mut map = serializer.serialize_map(None)?; |
91 | for (registry, patch) in patch { |
92 | if !patch.crates.is_empty() { |
93 | map.serialize_entry(registry, patch)?; |
94 | } |
95 | } |
96 | map.end() |
97 | } |
98 | |
99 | fn empty_patch(patch: &Map<String, RegistryPatch>) -> bool { |
100 | patch |
101 | .values() |
102 | .all(|registry_patch| registry_patch.crates.is_empty()) |
103 | } |
104 | |