1use cmake_parser_derive::CMake;
2
3use crate::{
4 doc::command_scope::{CommandScope, ToCommandScope},
5 Token,
6};
7
8#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[cmake(pkg = "crate", transparent)]
13pub enum CMakeLanguage<'t> {
14 Call(CMakeLanguageCall<'t>),
15 Eval(CMakeLanguageEval<'t>),
16 Defer(CMakeLanguageDefer<'t>),
17 SetDependencyProvider(CMakeLanguageSetDependencyProvider<'t>),
18 GetMessageLogLevel(CMakeLanguageGetMessageLogLevel<'t>),
19}
20
21impl<'t> ToCommandScope for CMakeLanguage<'t> {
22 fn to_command_scope(&self) -> CommandScope {
23 CommandScope::Scripting
24 }
25}
26
27#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
28#[cmake(pkg = "crate", positional)]
29pub struct CMakeLanguageCall<'t> {
30 pub command: Token<'t>,
31 pub args: Option<Vec<Token<'t>>>,
32}
33
34#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
35#[cmake(pkg = "crate")]
36pub struct CMakeLanguageEval<'t> {
37 pub code: Vec<Token<'t>>,
38}
39
40#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
41#[cmake(pkg = "crate", untagged)]
42pub enum CMakeLanguageDefer<'t> {
43 Call(CMakeLanguageDeferCall<'t>),
44 GetCallIds(CMakeLanguageDeferGetCallIds<'t>),
45 GetCall(CMakeLanguageDeferGetCall<'t>),
46 CancelCall(CMakeLanguageDeferCancelCall<'t>),
47}
48
49#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
50#[cmake(pkg = "crate", default = "options")]
51pub struct CMakeLanguageDeferCall<'t> {
52 #[cmake(rename = "")]
53 pub options: Option<Vec<DeferCallOption<'t>>>,
54 pub call: CMakeLanguageCall<'t>,
55}
56
57#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
58#[cmake(pkg = "crate", list, transparent)]
59pub enum DeferCallOption<'t> {
60 Directory(Token<'t>),
61 Id(Token<'t>),
62 IdVar(Token<'t>),
63}
64
65#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
66#[cmake(pkg = "crate", positional, transparent)]
67pub struct CMakeLanguageDeferGetCallIds<'t> {
68 pub directory: Option<Token<'t>>,
69 #[cmake(rename = "GET_CALL_IDS")]
70 pub var: Token<'t>,
71}
72
73#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
74#[cmake(pkg = "crate", positional)]
75pub struct CMakeLanguageDeferGetCall<'t> {
76 #[cmake(transparent)]
77 pub directory: Option<Token<'t>>,
78 #[cmake(transparent, rename = "GET_CALL")]
79 pub id: Token<'t>,
80 pub var: Token<'t>,
81}
82
83#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
84#[cmake(pkg = "crate", positional, transparent)]
85pub struct CMakeLanguageDeferCancelCall<'t> {
86 pub directory: Option<Token<'t>>,
87 #[cmake(rename = "CANCEL_CALL")]
88 pub ids: Vec<Token<'t>>,
89}
90
91#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
92#[cmake(pkg = "crate", positional)]
93pub struct CMakeLanguageSetDependencyProvider<'t> {
94 pub command: Token<'t>,
95 #[cmake(transparent)]
96 pub supported_methods: Vec<SuportedMethod>,
97}
98
99#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
100#[cmake(pkg = "crate", list)]
101pub enum SuportedMethod {
102 FindPackage,
103 #[cmake(rename = "FETCHCONTENT_MAKEAVAILABLE_SERIAL")]
104 FetchContentMakeAvailableSerial,
105}
106
107#[derive(CMake, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
108#[cmake(pkg = "crate", positional)]
109pub struct CMakeLanguageGetMessageLogLevel<'t> {
110 pub out_var: Token<'t>,
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116 use crate::doc::cmake_parse::tests::{quoted_token, quoted_tokens_vec, token, tokens_vec};
117 use crate::*;
118 use pretty_assertions::assert_eq;
119
120 #[test]
121 fn cmake_language() {
122 let src = include_bytes!("../../../../../fixture/commands/scripting/cmake_language");
123 let cmakelists = parse_cmakelists(src).unwrap();
124 let doc = Doc::from(cmakelists);
125 assert_eq!(
126 doc.commands(),
127 Ok(vec![
128 Command::CMakeLanguage(Box::new(CMakeLanguage::Call(CMakeLanguageCall {
129 command: token(b"${message_command}"),
130 args: Some(vec![token(b"STATUS"), quoted_token(b"Hello World!")]),
131 }))),
132 Command::CMakeLanguage(Box::new(CMakeLanguage::Eval(CMakeLanguageEval {
133 code: quoted_tokens_vec([br###"
134 if (${condition})
135 message(STATUS TRUE)
136 else()
137 message(STATUS FALSE)
138 endif()"###]),
139 }))),
140 Command::CMakeLanguage(Box::new(CMakeLanguage::Defer(CMakeLanguageDefer::Call(
141 CMakeLanguageDeferCall {
142 options: None,
143 call: CMakeLanguageCall {
144 command: token(b"message"),
145 args: Some(vec![quoted_token(b"${deferred_message}")]),
146 }
147 }
148 )))),
149 Command::CMakeLanguage(Box::new(CMakeLanguage::Defer(CMakeLanguageDefer::Call(
150 CMakeLanguageDeferCall {
151 options: Some(vec![DeferCallOption::IdVar(token(b"id"))]),
152 call: CMakeLanguageCall {
153 command: token(b"message"),
154 args: Some(vec![quoted_token(b"Canceled Message")]),
155 }
156 }
157 )))),
158 Command::CMakeLanguage(Box::new(CMakeLanguage::Defer(
159 CMakeLanguageDefer::GetCallIds(CMakeLanguageDeferGetCallIds {
160 directory: None,
161 var: token(b"ids1"),
162 })
163 ))),
164 Command::CMakeLanguage(Box::new(CMakeLanguage::Defer(
165 CMakeLanguageDefer::GetCallIds(CMakeLanguageDeferGetCallIds {
166 directory: Some(token(b"dir1")),
167 var: token(b"ids1"),
168 })
169 ))),
170 Command::CMakeLanguage(Box::new(CMakeLanguage::Defer(
171 CMakeLanguageDefer::GetCall(CMakeLanguageDeferGetCall {
172 directory: None,
173 id: token(b"id1"),
174 var: token(b"var1"),
175 })
176 ))),
177 Command::CMakeLanguage(Box::new(CMakeLanguage::Defer(
178 CMakeLanguageDefer::GetCall(CMakeLanguageDeferGetCall {
179 directory: Some(token(b"dir1")),
180 id: token(b"id1"),
181 var: token(b"var1"),
182 })
183 ))),
184 Command::CMakeLanguage(Box::new(CMakeLanguage::Defer(
185 CMakeLanguageDefer::CancelCall(CMakeLanguageDeferCancelCall {
186 directory: None,
187 ids: tokens_vec([b"${id}"]),
188 })
189 ))),
190 Command::CMakeLanguage(Box::new(CMakeLanguage::Defer(
191 CMakeLanguageDefer::CancelCall(CMakeLanguageDeferCancelCall {
192 directory: Some(token(b"dir1")),
193 ids: tokens_vec([b"id1", b"id2"]),
194 })
195 ))),
196 Command::CMakeLanguage(Box::new(CMakeLanguage::SetDependencyProvider(
197 CMakeLanguageSetDependencyProvider {
198 command: token(b"cmd1"),
199 supported_methods: vec![
200 SuportedMethod::FindPackage,
201 SuportedMethod::FetchContentMakeAvailableSerial
202 ],
203 }
204 ))),
205 Command::CMakeLanguage(Box::new(CMakeLanguage::GetMessageLogLevel(
206 CMakeLanguageGetMessageLogLevel {
207 out_var: token(b"out_var1"),
208 }
209 ))),
210 ])
211 )
212 }
213}