1use crate::{prelude::*, CheckerTool, XString};
2use cargo_metadata::Metadata;
3use std::fmt;
4
5#[derive(Serialize, Deserialize, Encode, Decode)]
11pub struct CargoMetaData {
12 pub meta_data: String,
13}
14
15impl CargoMetaData {
16 pub fn meta_data(&self) -> serde_json::Result<Metadata> {
17 serde_json::from_str(&self.meta_data)
18 }
19
20 pub fn from_meta_data(meta_data: &Metadata) -> serde_json::Result<Self> {
21 serde_json::to_string(meta_data).map(|meta_data| Self { meta_data })
22 }
23}
24
25pub type Workspaces = IndexMap<Utf8PathBuf, CargoMetaData>;
26
27#[derive(Encode, Decode, Default)]
28pub struct CacheLayout {
29 #[musli(with = musli::serde)]
31 pub root_path: Utf8PathBuf,
32 #[musli(with = musli::serde)]
37 pub cargo_tomls: Box<[Utf8PathBuf]>,
38 #[musli(with = musli::serde)]
39 pub workspaces: Workspaces,
40 #[musli(with = musli::serde)]
42 pub packages_info: Box<[CachePackageInfo]>,
43 pub resolves: Box<[CacheResolve]>,
44}
45
46redb_value!(CacheLayout, name: "OsCheckerCacheLayout",
47 read_err: "Not a valid cache layout.",
48 write_err: "Cache layout can't be encoded to bytes."
49);
50
51impl fmt::Debug for CacheLayout {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 f.debug_struct("CacheLayout")
54 .field("root_path", &self.root_path)
55 .field("cargo_tomls", &self.cargo_tomls)
56 .field("packages_info", &self.packages_info)
58 .finish()
59 }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
66pub enum TargetSource {
67 RustToolchainToml(Utf8PathBuf),
68 CargoConfigToml(Utf8PathBuf),
69 CargoTomlDocsrsInPkgDefault(Utf8PathBuf),
70 CargoTomlDocsrsInWorkspaceDefault(Utf8PathBuf),
71 CargoTomlDocsrsInPkg(Utf8PathBuf),
72 CargoTomlDocsrsInWorkspace(Utf8PathBuf),
73 DetectedByPkgScripts(Utf8PathBuf),
74 DetectedByRepoGithub(Utf8PathBuf),
75 DetectedByRepoScripts(Utf8PathBuf),
76 SpecifiedInOsCheckerConfig,
78 UnspecifiedDefaultToHostTarget,
80}
81
82impl TargetSource {
83 pub fn descibe(&self) -> (&'static str, Option<&Utf8Path>) {
84 match self {
85 TargetSource::RustToolchainToml(p) => ("RustToolchainToml", Some(p)),
86 TargetSource::CargoConfigToml(p) => ("CargoConfigToml", Some(p)),
87 TargetSource::CargoTomlDocsrsInPkgDefault(p) => {
88 ("CargoTomlDocsrsInPkgDefault", Some(p))
89 }
90 TargetSource::CargoTomlDocsrsInWorkspaceDefault(p) => {
91 ("CargoTomlDocsrsInWorkspaceDefault", Some(p))
92 }
93 TargetSource::CargoTomlDocsrsInPkg(p) => ("CargoTomlDocsrsInPkg", Some(p)),
94 TargetSource::CargoTomlDocsrsInWorkspace(p) => ("CargoTomlDocsrsInWorkspace", Some(p)),
95 TargetSource::DetectedByPkgScripts(p) => ("DetectedByPkgScripts", Some(p)),
96 TargetSource::DetectedByRepoGithub(p) => ("DetectedByRepoGithub", Some(p)),
97 TargetSource::DetectedByRepoScripts(p) => ("DetectedByRepoScripts", Some(p)),
98 TargetSource::SpecifiedInOsCheckerConfig => ("SpecifiedInOsCheckerConfig", None),
99 TargetSource::UnspecifiedDefaultToHostTarget => {
100 ("UnspecifiedDefaultToHostTarget", None)
101 }
102 }
103 }
104}
105
106#[derive(Debug, Default, Serialize, Deserialize)]
109pub struct Targets {
110 pub map: IndexMap<String, Vec<TargetSource>>,
111}
112
113#[derive(Debug, Serialize, Deserialize)]
114pub struct CachePackageInfo {
115 pub pkg_name: XString,
116 pub pkg_dir: Utf8PathBuf,
118 pub targets: Targets,
119 pub channel: String,
120}
121
122#[derive(Debug, Encode, Decode)]
123pub struct CacheResolve {
124 #[musli(with = musli::serde)]
125 pub pkg_name: XString,
126 pub target: String,
127 pub target_overridden: bool,
129 pub features_args: Vec<String>,
130 pub channel: String,
131 pub checker: CheckerTool,
132 pub cmd: String,
135}
136
137#[derive(Serialize, Deserialize, Debug)]
138pub struct ListTargets {
139 pub user: XString,
140 pub repo: XString,
141 pub pkg: XString,
142 pub targets: Vec<String>,
143}
144
145#[test]
146fn workspaces() {
147 #[derive(Encode, Decode)]
148 struct Meta {
149 #[musli(with=musli::serde)]
150 data: Metadata,
151 }
152
153 let metadata = cargo_metadata::MetadataCommand::new()
154 .manifest_path("../Cargo.toml")
155 .exec()
156 .unwrap();
157
158 let meta = Meta { data: metadata };
159 let _bytes = musli::storage::to_vec(&meta).unwrap();
160
161 let metadata = meta.data;
167
168 let meta = CargoMetaData {
169 meta_data: serde_json::to_string_pretty(&metadata).unwrap(),
170 };
171 let bytes = musli::storage::to_vec(&meta).unwrap();
172 let meta_string: CargoMetaData = musli::storage::from_slice(&bytes).unwrap();
173 assert!(meta_string.meta_data().is_ok());
174}