| 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 | |