1use crate::write::WriteFmt;
2use crate::{Flag, LibraryKind, LinkKind};
3use std::ffi::{OsStr, OsString};
4
5impl IntoIterator for Flag {
6 type Item = OsString;
7 type IntoIter = iter::Iter;
8
9 fn into_iter(self) -> Self::IntoIter {
10 let mut flags = Vec::new();
11
12 match self {
13 Flag::Help => {
14 flags.push(OsString::from("--help"));
15 }
16
17 Flag::Cfg { name, value } => {
18 flags.push(OsString::from("--cfg"));
19 if let Some(value) = value {
20 flags.push(OsString::from(format!("{}=\"{}\"", name, value)));
21 } else {
22 flags.push(OsString::from(name));
23 }
24 }
25
26 Flag::LibrarySearchPath { kind, path } => {
27 flags.push(OsString::from("-L"));
28 if kind == LibraryKind::All {
29 flags.push(OsString::from(path));
30 } else {
31 let mut flag = OsString::new();
32 write!(flag, "{}=", kind);
33 flag.push(path);
34 flags.push(flag);
35 }
36 }
37
38 Flag::Link {
39 kind,
40 modifiers,
41 name,
42 rename,
43 } => {
44 flags.push(OsString::from("-l"));
45 let mut flag = OsString::new();
46 if kind != LinkKind::default() || !modifiers.is_empty() {
47 write!(flag, "{}", kind);
48 }
49 for (i, (prefix, modifier)) in modifiers.iter().enumerate() {
50 flag.push(if i == 0 { ":" } else { "," });
51 write!(flag, "{}{}", prefix, modifier);
52 }
53 if !flag.is_empty() {
54 flag.push("=");
55 }
56 flag.push(name);
57 if let Some(rename) = rename {
58 flag.push(":");
59 flag.push(rename);
60 }
61 flags.push(flag);
62 }
63
64 Flag::CrateType(crate_type) => {
65 flags.push(OsString::from("--crate-type"));
66 flags.push(OsString::from(crate_type.to_string()));
67 }
68
69 Flag::CrateName(crate_name) => {
70 flags.push(OsString::from("--crate-name"));
71 flags.push(OsString::from(crate_name));
72 }
73
74 Flag::Edition(edition) => {
75 flags.push(OsString::from("--edition"));
76 flags.push(OsString::from(edition.to_string()));
77 }
78
79 Flag::Emit(emit) => {
80 flags.push(OsString::from("--emit"));
81 flags.push(OsString::from(emit.to_string()));
82 }
83
84 Flag::Print(print) => {
85 flags.push(OsString::from("--print"));
86 flags.push(OsString::from(print));
87 }
88
89 Flag::Out(filename) => {
90 flags.push(OsString::from("-o"));
91 flags.push(OsString::from(filename));
92 }
93
94 Flag::OutDir(dir) => {
95 flags.push(OsString::from("--out-dir"));
96 flags.push(OsString::from(dir));
97 }
98
99 Flag::Explain(code) => {
100 flags.push(OsString::from("--explain"));
101 flags.push(OsString::from(code));
102 }
103
104 Flag::Test => {
105 flags.push(OsString::from("--test"));
106 }
107
108 Flag::Target(target) => {
109 flags.push(OsString::from("--target"));
110 flags.push(OsString::from(target));
111 }
112
113 Flag::Allow(lint) => {
114 flags.push(OsString::from("--allow"));
115 flags.push(OsString::from(lint));
116 }
117
118 Flag::Warn(lint) => {
119 flags.push(OsString::from("--warn"));
120 flags.push(OsString::from(lint));
121 }
122
123 Flag::ForceWarn(lint) => {
124 flags.push(OsString::from("--force-warn"));
125 flags.push(OsString::from(lint));
126 }
127
128 Flag::Deny(lint) => {
129 flags.push(OsString::from("--deny"));
130 flags.push(OsString::from(lint));
131 }
132
133 Flag::Forbid(lint) => {
134 flags.push(OsString::from("--forbid"));
135 flags.push(OsString::from(lint));
136 }
137
138 Flag::CapLints(lint_level) => {
139 flags.push(OsString::from("--cap-lints"));
140 flags.push(OsString::from(lint_level.to_string()));
141 }
142
143 Flag::Codegen { opt, value } => {
144 flags.push(OsString::from("-C"));
145 if let Some(value) = value {
146 flags.push(OsString::from(format!("{}={}", opt, value)));
147 } else {
148 flags.push(OsString::from(opt));
149 }
150 }
151
152 Flag::Version => {
153 flags.push(OsString::from("--version"));
154 }
155
156 Flag::Verbose => {
157 flags.push(OsString::from("--verbose"));
158 }
159
160 Flag::Extern { name, path } => {
161 flags.push(OsString::from("--extern"));
162 if let Some(path) = path {
163 flags.push(kv(name, path));
164 } else {
165 flags.push(OsString::from(name));
166 }
167 }
168
169 Flag::ExternLocation { name, location } => {
170 flags.push(OsString::from("--extern-location"));
171 flags.push(kv(name, location));
172 }
173
174 Flag::Sysroot(sysroot) => {
175 flags.push(OsString::from("--sysroot"));
176 flags.push(OsString::from(sysroot));
177 }
178
179 Flag::Z(flag) => {
180 flags.push(OsString::from("-Z"));
181 flags.push(OsString::from(flag));
182 }
183
184 Flag::ErrorFormat(error_format) => {
185 flags.push(OsString::from("--error-format"));
186 flags.push(OsString::from(error_format.to_string()));
187 }
188
189 Flag::Json(json) => {
190 flags.push(OsString::from("--json"));
191 flags.push(OsString::from(json));
192 }
193
194 Flag::Color(color) => {
195 flags.push(OsString::from("--color"));
196 flags.push(OsString::from(color.to_string()));
197 }
198
199 Flag::RemapPathPrefix { from, to } => {
200 flags.push(OsString::from("--remap-path-prefix"));
201 flags.push(kv(from, to));
202 }
203 }
204
205 iter::Iter {
206 items: flags.into_iter(),
207 }
208 }
209}
210
211fn kv(k: impl AsRef<OsStr>, v: impl AsRef<OsStr>) -> OsString {
212 let k = k.as_ref();
213 let v = v.as_ref();
214 let mut string = OsString::with_capacity(k.len() + 1 + v.len());
215 string.push(k);
216 string.push("=");
217 string.push(v);
218 string
219}
220
221mod iter {
222 use std::ffi::OsString;
223 use std::vec;
224
225 pub struct Iter {
226 pub(crate) items: vec::IntoIter<OsString>,
227 }
228
229 impl Iterator for Iter {
230 type Item = OsString;
231
232 fn next(&mut self) -> Option<Self::Item> {
233 self.items.next()
234 }
235 }
236}