cargo_options/
metadata.rs1use std::path::PathBuf;
2use std::process::Command;
3
4use clap::{ArgAction, Parser};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use crate::heading;
10use crate::CommonOptions;
11
12#[derive(Clone, Debug, Default, Parser)]
16#[command(
17 display_order = 1,
18 after_help = "Run `cargo help metadata` for more detailed information."
19)]
20#[group(skip)]
21#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
22pub struct Metadata {
23 #[arg(short = 'q', long)]
25 #[cfg_attr(feature = "serde", serde(default))]
26 pub quiet: bool,
27
28 #[arg(
30 short = 'F',
31 long,
32 action = ArgAction::Append,
33 help_heading = heading::FEATURE_SELECTION,
34 )]
35 #[cfg_attr(feature = "serde", serde(default))]
36 pub features: Vec<String>,
37
38 #[arg(long, help_heading = heading::FEATURE_SELECTION)]
40 #[cfg_attr(feature = "serde", serde(default))]
41 pub all_features: bool,
42
43 #[arg(long, help_heading = heading::FEATURE_SELECTION)]
45 #[cfg_attr(feature = "serde", serde(default))]
46 pub no_default_features: bool,
47
48 #[arg(short = 'v', long, action = ArgAction::Count)]
50 #[cfg_attr(feature = "serde", serde(default))]
51 pub verbose: u8,
52
53 #[arg(long, value_name = "TRIPLE", action = ArgAction::Append)]
55 #[cfg_attr(feature = "serde", serde(default))]
56 pub filter_platform: Vec<String>,
57
58 #[arg(long)]
61 #[cfg_attr(feature = "serde", serde(default))]
62 pub no_deps: bool,
63
64 #[arg(long, value_name = "PATH")]
66 #[cfg_attr(feature = "serde", serde(default))]
67 pub manifest_path: Option<PathBuf>,
68
69 #[arg(long, value_name = "VERSION", value_parser = ["1"])]
71 #[cfg_attr(feature = "serde", serde(default))]
72 pub format_version: Option<String>,
73
74 #[arg(long, value_name = "WHEN")]
76 #[cfg_attr(feature = "serde", serde(default))]
77 pub color: Option<String>,
78
79 #[arg(long, help_heading = heading::MANIFEST_OPTIONS)]
81 #[cfg_attr(feature = "serde", serde(default))]
82 pub frozen: bool,
83
84 #[arg(long, help_heading = heading::MANIFEST_OPTIONS)]
86 #[cfg_attr(feature = "serde", serde(default))]
87 pub locked: bool,
88
89 #[arg(long, help_heading = heading::MANIFEST_OPTIONS)]
91 #[cfg_attr(feature = "serde", serde(default))]
92 pub offline: bool,
93
94 #[arg(long, value_name = "KEY=VALUE", action = ArgAction::Append)]
96 #[cfg_attr(feature = "serde", serde(default))]
97 pub config: Vec<String>,
98
99 #[arg(short = 'Z', value_name = "FLAG", action = ArgAction::Append)]
101 #[cfg_attr(feature = "serde", serde(default))]
102 pub unstable_flags: Vec<String>,
103}
104
105impl Metadata {
106 pub fn command(&self) -> Command {
108 let mut cmd = CommonOptions::cargo_command();
109 cmd.arg("metadata");
110 if self.quiet {
111 cmd.arg("--quiet");
112 }
113 if self.verbose > 0 {
114 cmd.arg(format!("-{}", "v".repeat(self.verbose.into())));
115 }
116 for feature in &self.features {
117 cmd.arg("--features").arg(feature);
118 }
119 if self.all_features {
120 cmd.arg("--all-features");
121 }
122 if self.no_default_features {
123 cmd.arg("--no-default-features");
124 }
125 for platform in &self.filter_platform {
126 cmd.arg("--filter-platform").arg(platform);
127 }
128 if self.no_deps {
129 cmd.arg("--no-deps");
130 }
131 if let Some(path) = self.manifest_path.as_ref() {
132 cmd.arg("--manifest-path").arg(path);
133 }
134 if let Some(format_version) = self.format_version.as_ref() {
135 cmd.arg("--format-version").arg(format_version);
136 }
137 if let Some(color) = self.color.as_ref() {
138 cmd.arg("--color").arg(color);
139 }
140 if self.frozen {
141 cmd.arg("--frozen");
142 }
143 if self.locked {
144 cmd.arg("--locked");
145 }
146 if self.offline {
147 cmd.arg("--offline");
148 }
149 for config in &self.config {
150 cmd.arg("--config").arg(config);
151 }
152 for flag in &self.unstable_flags {
153 cmd.arg("-Z").arg(flag);
154 }
155 cmd
156 }
157}
158
159#[cfg(test)]
160mod test {
161 use super::Metadata;
162 use clap::CommandFactory;
163
164 #[test]
165 fn verify_cli() {
166 <Metadata as CommandFactory>::command().debug_assert()
167 }
168}