cordis_include/
options.rs1use crate::node::Node;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq)]
16pub enum Disabled {
17 Flag(bool),
19 Expr(String),
22}
23
24impl Default for Disabled {
25 fn default() -> Self {
26 Self::Flag(false)
27 }
28}
29
30impl Disabled {
31 pub fn is_disabled(&self) -> bool {
34 matches!(self, Self::Flag(true))
35 }
36
37 pub fn as_expr(&self) -> Option<&str> {
39 match self {
40 Self::Expr(source) => Some(source),
41 _ => None,
42 }
43 }
44}
45
46fn disabled_is_default(value: &Disabled) -> bool {
48 matches!(value, Disabled::Flag(false))
49}
50
51impl Serialize for Disabled {
52 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
53 match self {
54 Self::Flag(flag) => serializer.serialize_bool(*flag),
55 Self::Expr(source) => serializer.serialize_str(source),
56 }
57 }
58}
59
60impl<'de> Deserialize<'de> for Disabled {
61 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
62 struct DisabledVisitor;
63
64 impl serde::de::Visitor<'_> for DisabledVisitor {
65 type Value = Disabled;
66
67 fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 f.write_str("a boolean or a `!!js` expression string")
69 }
70
71 fn visit_bool<E: serde::de::Error>(self, value: bool) -> Result<Disabled, E> {
72 Ok(Disabled::Flag(value))
73 }
74
75 fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<Disabled, E> {
76 Ok(Disabled::Expr(value.to_owned()))
77 }
78
79 fn visit_string<E: serde::de::Error>(self, value: String) -> Result<Disabled, E> {
80 Ok(Disabled::Expr(value))
81 }
82 }
83
84 deserializer.deserialize_any(DisabledVisitor)
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91
92 #[test]
95 fn disabled_serde_json_round_trips() {
96 let options: EntryOptions =
97 serde_json::from_str(r#"{"name":"n","disabled":true}"#).unwrap();
98 assert_eq!(options.disabled, Disabled::Flag(true));
99 let options: EntryOptions =
100 serde_json::from_str(r#"{"name":"n","disabled":"process.platform"}"#).unwrap();
101 assert_eq!(
102 options.disabled,
103 Disabled::Expr("process.platform".to_owned())
104 );
105 let text = serde_json::to_string(&options).unwrap();
106 assert_eq!(text, r#"{"name":"n","disabled":"process.platform"}"#);
107 let text = serde_json::to_string(&EntryOptions::new("n")).unwrap();
109 assert_eq!(text, r#"{"name":"n"}"#);
110 }
111}
112
113pub const IMPORT_NAME: &str = "import";
116
117pub const GROUP_NAME: &str = "group";
120
121#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
131pub struct EntryOptions {
132 #[serde(default, skip_serializing_if = "Option::is_none")]
136 pub id: Option<String>,
137 #[serde(default)]
139 pub name: String,
140 #[serde(default, skip_serializing_if = "disabled_is_default")]
144 pub disabled: Disabled,
145 #[serde(default, skip_serializing_if = "Vec::is_empty")]
147 pub inject: Vec<String>,
148 #[serde(default, skip_serializing_if = "Vec::is_empty")]
150 pub group: Vec<EntryOptions>,
151 #[serde(default, skip_serializing_if = "Option::is_none")]
153 pub config: Option<Node>,
154}
155
156impl EntryOptions {
157 pub fn new(name: impl Into<String>) -> Self {
159 Self {
160 name: name.into(),
161 ..Self::default()
162 }
163 }
164
165 pub fn with_id(mut self, id: impl Into<String>) -> Self {
167 self.id = Some(id.into());
168 self
169 }
170
171 pub fn with_config(mut self, config: Node) -> Self {
173 self.config = Some(config);
174 self
175 }
176
177 pub fn with_group(mut self, group: Vec<EntryOptions>) -> Self {
179 self.group = group;
180 self
181 }
182
183 pub fn with_disabled(mut self, disabled: bool) -> Self {
186 self.disabled = Disabled::Flag(disabled);
187 self
188 }
189
190 pub fn import_url(&self) -> Option<&str> {
193 if self.name != IMPORT_NAME {
194 return None;
195 }
196 self.config.as_ref()?.as_object()?.get("url")?.as_str()
197 }
198
199 pub fn with_inject<I, S>(mut self, inject: I) -> Self
201 where
202 I: IntoIterator<Item = S>,
203 S: Into<String>,
204 {
205 self.inject = inject.into_iter().map(Into::into).collect();
206 self
207 }
208}