1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use serde::ser::{self, Serialize};
use core::resolver::Resolve;
use core::{Package, PackageId, Workspace};
use ops::{self, Packages};
use util::CargoResult;
const VERSION: u32 = 1;
pub struct OutputMetadataOptions {
pub features: Vec<String>,
pub no_default_features: bool,
pub all_features: bool,
pub no_deps: bool,
pub version: u32,
}
pub fn output_metadata(ws: &Workspace,
opt: &OutputMetadataOptions) -> CargoResult<ExportInfo> {
if opt.version != VERSION {
bail!("metadata version {} not supported, only {} is currently supported",
opt.version, VERSION);
}
if opt.no_deps {
metadata_no_deps(ws, opt)
} else {
metadata_full(ws, opt)
}
}
fn metadata_no_deps(ws: &Workspace,
_opt: &OutputMetadataOptions) -> CargoResult<ExportInfo> {
Ok(ExportInfo {
packages: ws.members().cloned().collect(),
workspace_members: ws.members().map(|pkg| pkg.package_id().clone()).collect(),
resolve: None,
version: VERSION,
})
}
fn metadata_full(ws: &Workspace,
opt: &OutputMetadataOptions) -> CargoResult<ExportInfo> {
let specs = Packages::All.into_package_id_specs(ws)?;
let deps = ops::resolve_ws_precisely(ws,
None,
&opt.features,
opt.all_features,
opt.no_default_features,
&specs)?;
let (packages, resolve) = deps;
let packages = packages.package_ids()
.map(|i| packages.get(i).map(|p| p.clone()))
.collect::<CargoResult<Vec<_>>>()?;
Ok(ExportInfo {
packages: packages,
workspace_members: ws.members().map(|pkg| pkg.package_id().clone()).collect(),
resolve: Some(MetadataResolve{
resolve: resolve,
root: ws.current_opt().map(|pkg| pkg.package_id().clone()),
}),
version: VERSION,
})
}
#[derive(Serialize)]
pub struct ExportInfo {
packages: Vec<Package>,
workspace_members: Vec<PackageId>,
resolve: Option<MetadataResolve>,
version: u32,
}
#[derive(Serialize)]
struct MetadataResolve {
#[serde(rename = "nodes", serialize_with = "serialize_resolve")]
resolve: Resolve,
root: Option<PackageId>,
}
fn serialize_resolve<S>(resolve: &Resolve, s: S) -> Result<S::Ok, S::Error>
where S: ser::Serializer,
{
#[derive(Serialize)]
struct Node<'a> {
id: &'a PackageId,
dependencies: Vec<&'a PackageId>,
}
resolve.iter().map(|id| {
Node {
id: id,
dependencies: resolve.deps(id).collect(),
}
}).collect::<Vec<_>>().serialize(s)
}