1use cmake_parser_derive::CMake;
2
3use crate::{
4 command::common::{FindRoot, WindowsRegistryView},
5 doc::command_scope::{CommandScope, ToCommandScope},
6 Token,
7};
8
9#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[cmake(pkg = "crate", untagged)]
14pub enum FindPackage<'t> {
15 Full(FindPackageFull<'t>),
16 Basic(FindPackageBasic<'t>),
17}
18
19impl<'t> ToCommandScope for FindPackage<'t> {
20 fn to_command_scope(&self) -> CommandScope {
21 CommandScope::Scripting
22 }
23}
24
25#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
26#[cmake(pkg = "crate", complete, default = "version")]
27pub struct FindPackageBasic<'t> {
28 #[cmake(positional)]
29 pub package_name: Token<'t>,
30 #[cmake(rename = "")]
31 pub version: Option<Token<'t>>,
32 pub exact: bool,
33 pub quiet: bool,
34 pub module: bool,
35 pub components: Option<PackageComponents<'t>>,
36 pub optional_components: Option<Vec<Token<'t>>>,
37 pub registry_view: Option<WindowsRegistryView>,
38 pub global: bool,
39 pub no_policy_scope: bool,
40 pub bypass_provider: bool,
41}
42
43#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
44#[cmake(pkg = "crate", complete, default = "version", except = ["MODULE"])]
45pub struct FindPackageFull<'t> {
46 #[cmake(positional)]
47 pub package_name: Token<'t>,
48 #[cmake(rename = "")]
49 pub version: Option<Token<'t>>,
50 pub exact: bool,
51 pub quiet: bool,
52 pub components: Option<PackageComponents<'t>>,
53 pub optional_components: Option<Vec<Token<'t>>>,
54 pub config_mode: Option<ConfigMode>,
55 pub global: bool,
56 pub no_policy_scope: bool,
57 pub bypass_provider: bool,
58 pub names: Option<Vec<Token<'t>>>,
59 pub configs: Option<Vec<Token<'t>>>,
60 pub hints: Option<Vec<Token<'t>>>,
61 pub paths: Option<Vec<Token<'t>>>,
62 pub registry_view: Option<WindowsRegistryView>,
63 pub path_suffixes: Option<Vec<Token<'t>>>,
64 pub no_default_path: bool,
65 pub no_package_root_path: bool,
66 pub no_cmake_path: bool,
67 pub no_cmake_environment_path: bool,
68 pub no_system_environment_path: bool,
69 pub no_cmake_package_registry: bool,
70 pub no_cmake_builds_path: bool,
71 pub no_cmake_system_path: bool,
72 pub no_cmake_install_prefix: bool,
73 pub find_root: Option<FindRoot>,
74}
75
76#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
77#[cmake(pkg = "crate", positional, complete)]
78pub enum PackageComponents<'t> {
79 Components(Components<'t>),
80 #[cmake(transparent)]
81 Required(Option<Components<'t>>),
82}
83
84#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
85#[cmake(pkg = "crate", default = "components")]
86pub struct Components<'t> {
87 pub components: Vec<Token<'t>>,
88}
89
90#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
91#[cmake(pkg = "crate")]
92pub enum ConfigMode {
93 Config,
94 NoModule,
95}
96#[cfg(test)]
97mod tests {
98 use super::*;
99 use crate::doc::cmake_parse::tests::{token, tokens_vec};
100 use crate::*;
101 use pretty_assertions::assert_eq;
102
103 #[test]
104 fn package_components() {
105 #[derive(CMake, Debug, PartialEq, Eq)]
106 #[cmake(pkg = "crate", allow_empty)]
107 struct Test<'t> {
108 components: Option<PackageComponents<'t>>,
109 }
110 assert_eq!(
111 CMakeParse::complete(&tokens_vec([])),
112 Ok(Test { components: None })
113 );
114 assert_eq!(
115 CMakeParse::complete(&tokens_vec([b"COMPONENTS", b"component1"])),
116 Ok(Test {
117 components: Some(PackageComponents::Components(Components {
118 components: tokens_vec([b"component1"]),
119 })),
120 })
121 );
122 assert_eq!(
123 CMakeParse::complete(&tokens_vec([b"REQUIRED"])),
124 Ok(Test {
125 components: Some(PackageComponents::Required(None)),
126 })
127 );
128 assert_eq!(
129 CMakeParse::complete(&tokens_vec([b"REQUIRED", b"COMPONENTS", b"component1"])),
130 Ok(Test {
131 components: Some(PackageComponents::Required(Some(Components {
132 components: tokens_vec([b"component1"]),
133 }))),
134 })
135 );
136 assert_eq!(
137 CMakeParse::complete(&tokens_vec([b"REQUIRED", b"component1", b"component2"])),
138 Ok(Test {
139 components: Some(PackageComponents::Required(Some(Components {
140 components: tokens_vec([b"component1", b"component2"]),
141 }))),
142 })
143 );
144 }
145
146 #[test]
147 fn find_package() {
148 let src = include_bytes!("../../../../../fixture/commands/scripting/find_package");
149 let cmakelists = parse_cmakelists(src).unwrap();
150 let doc = Doc::from(cmakelists);
151 assert_eq!(
152 doc.commands(),
153 Ok(vec![
154 Command::FindPackage(Box::new(FindPackage::Full(FindPackageFull {
155 package_name: token(b"package_name1"),
156 version: None,
157 exact: false,
158 quiet: false,
159 components: None,
160 optional_components: None,
161 config_mode: None,
162 global: false,
163 no_policy_scope: false,
164 bypass_provider: false,
165 names: None,
166 configs: None,
167 hints: None,
168 paths: None,
169 registry_view: None,
170 path_suffixes: None,
171 no_default_path: false,
172 no_package_root_path: false,
173 no_cmake_path: false,
174 no_cmake_environment_path: false,
175 no_system_environment_path: false,
176 no_cmake_package_registry: false,
177 no_cmake_builds_path: false,
178 no_cmake_system_path: false,
179 no_cmake_install_prefix: false,
180 find_root: None,
181 }))),
182 Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
183 package_name: token(b"package_name1"),
184 version: None,
185 exact: false,
186 quiet: false,
187 module: true,
188 components: None,
189 optional_components: None,
190 global: false,
191 no_policy_scope: false,
192 bypass_provider: false,
193 registry_view: None,
194 }))),
195 Command::FindPackage(Box::new(FindPackage::Full(FindPackageFull {
196 package_name: token(b"package_name1"),
197 version: None,
198 exact: false,
199 quiet: false,
200 components: Some(PackageComponents::Required(Some(Components {
201 components: tokens_vec([b"component1", b"component2"]),
202 }))),
203 optional_components: None,
204 config_mode: None,
205 global: false,
206 no_policy_scope: false,
207 bypass_provider: false,
208 names: None,
209 configs: None,
210 hints: None,
211 paths: None,
212 registry_view: None,
213 path_suffixes: None,
214 no_default_path: false,
215 no_package_root_path: false,
216 no_cmake_path: false,
217 no_cmake_environment_path: false,
218 no_system_environment_path: false,
219 no_cmake_package_registry: false,
220 no_cmake_builds_path: false,
221 no_cmake_system_path: false,
222 no_cmake_install_prefix: false,
223 find_root: None,
224 }))),
225 Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
226 package_name: token(b"package_name1"),
227 version: None,
228 exact: false,
229 quiet: false,
230 module: true,
231 components: Some(PackageComponents::Required(Some(Components {
232 components: tokens_vec([b"component1", b"component2"]),
233 }))),
234 optional_components: None,
235 global: false,
236 no_policy_scope: false,
237 bypass_provider: false,
238 registry_view: None,
239 }))),
240 Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
241 package_name: token(b"package_name1"),
242 version: None,
243 exact: false,
244 quiet: false,
245 module: true,
246 components: Some(PackageComponents::Components(Components {
247 components: tokens_vec([b"component1", b"component2"]),
248 })),
249 optional_components: None,
250 global: false,
251 no_policy_scope: false,
252 bypass_provider: false,
253 registry_view: None,
254 }))),
255 Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
256 package_name: token(b"package_name1"),
257 version: None,
258 exact: false,
259 quiet: false,
260 module: true,
261 components: Some(PackageComponents::Required(None)),
262 optional_components: None,
263 global: false,
264 no_policy_scope: false,
265 bypass_provider: false,
266 registry_view: None,
267 }))),
268 Command::FindPackage(Box::new(FindPackage::Full(FindPackageFull {
269 package_name: token(b"package_name1"),
270 version: Some(token(b"version1")),
271 exact: true,
272 quiet: true,
273 components: Some(PackageComponents::Required(Some(Components {
274 components: tokens_vec([b"component1", b"component2"]),
275 }))),
276 optional_components: Some(tokens_vec([b"component1", b"component2"])),
277 config_mode: Some(ConfigMode::NoModule),
278 global: true,
279 no_policy_scope: true,
280 bypass_provider: true,
281 names: Some(tokens_vec([b"name1", b"name2"])),
282 configs: Some(tokens_vec([b"config1", b"config2"])),
283 hints: Some(tokens_vec([b"hint1", b"hint2"])),
284 paths: Some(tokens_vec([b"path1", b"path2"])),
285 registry_view: Some(WindowsRegistryView::Bits64Fallback32),
286 path_suffixes: Some(tokens_vec([b"suffix1", b"suffix2"])),
287 no_default_path: true,
288 no_package_root_path: true,
289 no_cmake_path: true,
290 no_cmake_environment_path: true,
291 no_system_environment_path: true,
292 no_cmake_package_registry: true,
293 no_cmake_builds_path: true,
294 no_cmake_system_path: true,
295 no_cmake_install_prefix: true,
296 find_root: Some(FindRoot::OnlyCMakeFindRootPath),
297 }))),
298 Command::FindPackage(Box::new(FindPackage::Basic(FindPackageBasic {
299 package_name: token(b"package_name1"),
300 version: Some(token(b"version1")),
301 exact: true,
302 quiet: true,
303 module: true,
304 components: Some(PackageComponents::Components(Components {
305 components: tokens_vec([b"component1", b"component2"]),
306 })),
307 optional_components: Some(tokens_vec([b"component1", b"component2"])),
308 registry_view: Some(WindowsRegistryView::Host),
309 global: true,
310 no_policy_scope: true,
311 bypass_provider: true,
312 }))),
313 ])
314 )
315 }
316}