xref: /aosp_15_r20/external/bazelbuild-rules_rust/crate_universe/src/select.rs (revision d4726bddaa87cc4778e7472feed243fa4b6c267f)
1 use std::collections::{BTreeMap, BTreeSet};
2 use std::fmt::Debug;
3 
4 use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize};
5 
6 /// A wrapper around values where some values may be conditionally included (e.g. only on a certain platform), and others are unconditional.
7 #[derive(Debug, Clone, PartialEq, Eq, Serialize)]
8 pub struct Select<T>
9 where
10     T: Selectable,
11 {
12     common: T::CommonType,
13     selects: BTreeMap<String, T::SelectsType>,
14 }
15 
16 pub trait Selectable
17 where
18     Self: SelectableValue,
19 {
20     type ItemType: SelectableValue;
21     type CommonType: SelectableValue + Default;
22     type SelectsType: SelectableValue;
23 
is_empty(this: &Select<Self>) -> bool24     fn is_empty(this: &Select<Self>) -> bool;
insert(this: &mut Select<Self>, value: Self::ItemType, configuration: Option<String>)25     fn insert(this: &mut Select<Self>, value: Self::ItemType, configuration: Option<String>);
26 
items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)>27     fn items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)>;
values(this: &Select<Self>) -> Vec<Self::ItemType>28     fn values(this: &Select<Self>) -> Vec<Self::ItemType>;
29 
merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self>30     fn merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self>;
31 }
32 
33 // Replace with `trait_alias` once stabilized.
34 // https://github.com/rust-lang/rust/issues/41517
35 pub trait SelectableValue
36 where
37     Self: Debug + Clone + PartialEq + Eq + Serialize + DeserializeOwned,
38 {
39 }
40 
41 impl<T> SelectableValue for T where T: Debug + Clone + PartialEq + Eq + Serialize + DeserializeOwned {}
42 
43 // Replace with `trait_alias` once stabilized.
44 // https://github.com/rust-lang/rust/issues/41517
45 pub trait SelectableOrderedValue
46 where
47     Self: SelectableValue + PartialOrd + Ord,
48 {
49 }
50 
51 impl<T> SelectableOrderedValue for T where T: SelectableValue + PartialOrd + Ord {}
52 
53 pub(crate) trait SelectableScalar
54 where
55     Self: SelectableValue,
56 {
57 }
58 
59 impl SelectableScalar for String {}
60 impl SelectableScalar for bool {}
61 impl SelectableScalar for i64 {}
62 
63 // General
64 impl<T> Select<T>
65 where
66     T: Selectable,
67 {
new() -> Self68     pub(crate) fn new() -> Self {
69         Self {
70             common: T::CommonType::default(),
71             selects: BTreeMap::new(),
72         }
73     }
74 
from_value(value: T::CommonType) -> Self75     pub(crate) fn from_value(value: T::CommonType) -> Self {
76         Self {
77             common: value,
78             selects: BTreeMap::new(),
79         }
80     }
81 
82     /// Whether there zero values in this collection, common or configuration-specific.
is_empty(&self) -> bool83     pub fn is_empty(&self) -> bool {
84         T::is_empty(self)
85     }
86 
87     /// A list of the configurations which have some configuration-specific value associated.
configurations(&self) -> BTreeSet<String>88     pub fn configurations(&self) -> BTreeSet<String> {
89         self.selects.keys().cloned().collect()
90     }
91 
92     /// All values and their associated configurations, if any.
items(&self) -> Vec<(Option<String>, T::ItemType)>93     pub fn items(&self) -> Vec<(Option<String>, T::ItemType)> {
94         T::items(self)
95     }
96 
97     /// All values, whether common or configured.
values(&self) -> Vec<T::ItemType>98     pub fn values(&self) -> Vec<T::ItemType> {
99         T::values(self)
100     }
101 
insert(&mut self, value: T::ItemType, configuration: Option<String>)102     pub(crate) fn insert(&mut self, value: T::ItemType, configuration: Option<String>) {
103         T::insert(self, value, configuration);
104     }
105 
into_parts(self) -> (T::CommonType, BTreeMap<String, T::SelectsType>)106     pub(crate) fn into_parts(self) -> (T::CommonType, BTreeMap<String, T::SelectsType>) {
107         (self.common, self.selects)
108     }
109 
merge(lhs: Self, rhs: Self) -> Self110     pub(crate) fn merge(lhs: Self, rhs: Self) -> Self {
111         T::merge(lhs, rhs)
112     }
113 }
114 
115 impl<T> Default for Select<T>
116 where
117     T: Selectable,
118 {
default() -> Self119     fn default() -> Self {
120         Self::new()
121     }
122 }
123 
124 impl<'de, T> Deserialize<'de> for Select<T>
125 where
126     T: Selectable,
127 {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,128     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
129     where
130         D: Deserializer<'de>,
131     {
132         #[derive(Debug, Deserialize)]
133         #[serde(untagged)]
134         enum Either<T>
135         where
136             T: Selectable,
137         {
138             Select {
139                 common: T::CommonType,
140                 selects: BTreeMap<String, T::SelectsType>,
141             },
142             Value(T::CommonType),
143         }
144 
145         let either = Either::<T>::deserialize(deserializer)?;
146         match either {
147             Either::Select { common, selects } => Ok(Self { common, selects }),
148             Either::Value(common) => Ok(Self {
149                 common,
150                 selects: BTreeMap::new(),
151             }),
152         }
153     }
154 }
155 
156 // Scalar
157 impl<T> Selectable for T
158 where
159     T: SelectableScalar,
160 {
161     type ItemType = T;
162     type CommonType = Option<Self::ItemType>;
163     type SelectsType = Self::ItemType;
164 
is_empty(this: &Select<Self>) -> bool165     fn is_empty(this: &Select<Self>) -> bool {
166         this.common.is_none() && this.selects.is_empty()
167     }
168 
items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)>169     fn items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)> {
170         let mut result = Vec::new();
171         if let Some(value) = this.common.as_ref() {
172             result.push((None, value.clone()));
173         }
174         result.extend(
175             this.selects
176                 .iter()
177                 .map(|(configuration, value)| (Some(configuration.clone()), value.clone())),
178         );
179         result
180     }
181 
values(this: &Select<Self>) -> Vec<Self::ItemType>182     fn values(this: &Select<Self>) -> Vec<Self::ItemType> {
183         let mut result = Vec::new();
184         if let Some(value) = this.common.as_ref() {
185             result.push(value.clone());
186         }
187         result.extend(this.selects.values().cloned());
188         result
189     }
190 
insert(this: &mut Select<Self>, value: Self::ItemType, configuration: Option<String>)191     fn insert(this: &mut Select<Self>, value: Self::ItemType, configuration: Option<String>) {
192         match configuration {
193             None => {
194                 this.selects
195                     .retain(|_, existing_value| existing_value != &value);
196                 this.common = Some(value);
197             }
198             Some(configuration) => {
199                 if Some(&value) != this.common.as_ref() {
200                     this.selects.insert(configuration, value);
201                 }
202             }
203         }
204     }
205 
merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self>206     fn merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self> {
207         let mut result: Select<Self> = Select::new();
208 
209         if let Some(value) = lhs.common {
210             result.insert(value, None);
211         }
212         if let Some(value) = rhs.common {
213             result.insert(value, None);
214         }
215 
216         for (configuration, value) in lhs.selects.into_iter() {
217             result.insert(value, Some(configuration));
218         }
219         for (configuration, value) in rhs.selects.into_iter() {
220             result.insert(value, Some(configuration));
221         }
222 
223         result
224     }
225 }
226 
227 // Vec<T>
228 impl<T> Selectable for Vec<T>
229 where
230     T: SelectableValue,
231 {
232     type ItemType = T;
233     type CommonType = Vec<T>;
234     type SelectsType = Vec<T>;
235 
is_empty(this: &Select<Self>) -> bool236     fn is_empty(this: &Select<Self>) -> bool {
237         this.common.is_empty() && this.selects.is_empty()
238     }
239 
items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)>240     fn items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)> {
241         let mut result = Vec::new();
242         result.extend(this.common.iter().map(|value| (None, value.clone())));
243         result.extend(this.selects.iter().flat_map(|(configuration, values)| {
244             values
245                 .iter()
246                 .map(|value| (Some(configuration.clone()), value.clone()))
247         }));
248         result
249     }
250 
values(this: &Select<Self>) -> Vec<Self::ItemType>251     fn values(this: &Select<Self>) -> Vec<Self::ItemType> {
252         let mut result = Vec::new();
253         result.extend(this.common.iter().cloned());
254         result.extend(
255             this.selects
256                 .values()
257                 .flat_map(|values| values.iter().cloned()),
258         );
259         result
260     }
261 
insert(this: &mut Select<Self>, value: Self::ItemType, configuration: Option<String>)262     fn insert(this: &mut Select<Self>, value: Self::ItemType, configuration: Option<String>) {
263         match configuration {
264             None => this.common.push(value),
265             Some(configuration) => this.selects.entry(configuration).or_default().push(value),
266         }
267     }
268 
merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self>269     fn merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self> {
270         let mut result: Select<Self> = Select::new();
271 
272         for value in lhs.common.into_iter() {
273             result.insert(value, None);
274         }
275         for value in rhs.common.into_iter() {
276             result.insert(value, None);
277         }
278 
279         for (configuration, values) in lhs.selects.into_iter() {
280             for value in values.into_iter() {
281                 result.insert(value, Some(configuration.clone()));
282             }
283         }
284         for (configuration, values) in rhs.selects.into_iter() {
285             for value in values.into_iter() {
286                 result.insert(value, Some(configuration.clone()));
287             }
288         }
289 
290         result
291     }
292 }
293 
294 // BTreeSet<T>
295 impl<T> Selectable for BTreeSet<T>
296 where
297     T: SelectableOrderedValue,
298 {
299     type ItemType = T;
300     type CommonType = BTreeSet<T>;
301     type SelectsType = BTreeSet<T>;
302 
is_empty(this: &Select<Self>) -> bool303     fn is_empty(this: &Select<Self>) -> bool {
304         this.common.is_empty() && this.selects.is_empty()
305     }
306 
items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)>307     fn items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)> {
308         let mut result = Vec::new();
309         result.extend(this.common.iter().map(|value| (None, value.clone())));
310         result.extend(this.selects.iter().flat_map(|(configuration, values)| {
311             values
312                 .iter()
313                 .map(|value| (Some(configuration.clone()), value.clone()))
314         }));
315         result
316     }
317 
values(this: &Select<Self>) -> Vec<Self::ItemType>318     fn values(this: &Select<Self>) -> Vec<Self::ItemType> {
319         let mut result = Vec::new();
320         result.extend(this.common.iter().cloned());
321         result.extend(
322             this.selects
323                 .values()
324                 .flat_map(|values| values.iter().cloned()),
325         );
326         result
327     }
328 
insert(this: &mut Select<Self>, value: Self::ItemType, configuration: Option<String>)329     fn insert(this: &mut Select<Self>, value: Self::ItemType, configuration: Option<String>) {
330         match configuration {
331             None => {
332                 this.selects.retain(|_, set| {
333                     set.remove(&value);
334                     !set.is_empty()
335                 });
336                 this.common.insert(value);
337             }
338             Some(configuration) => {
339                 if !this.common.contains(&value) {
340                     this.selects.entry(configuration).or_default().insert(value);
341                 }
342             }
343         }
344     }
345 
merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self>346     fn merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self> {
347         let mut result: Select<Self> = Select::new();
348 
349         for value in lhs.common.into_iter() {
350             result.insert(value, None);
351         }
352         for value in rhs.common.into_iter() {
353             result.insert(value, None);
354         }
355 
356         for (configuration, values) in lhs.selects.into_iter() {
357             for value in values {
358                 result.insert(value, Some(configuration.clone()));
359             }
360         }
361         for (configuration, values) in rhs.selects.into_iter() {
362             for value in values {
363                 result.insert(value, Some(configuration.clone()));
364             }
365         }
366 
367         result
368     }
369 }
370 
371 impl<T> Select<BTreeSet<T>>
372 where
373     T: SelectableOrderedValue,
374 {
map<U, F>(self, func: F) -> Select<BTreeSet<U>> where U: SelectableOrderedValue, F: Copy + FnMut(T) -> U,375     pub(crate) fn map<U, F>(self, func: F) -> Select<BTreeSet<U>>
376     where
377         U: SelectableOrderedValue,
378         F: Copy + FnMut(T) -> U,
379     {
380         Select {
381             common: self.common.into_iter().map(func).collect(),
382             selects: self
383                 .selects
384                 .into_iter()
385                 .map(|(configuration, values)| {
386                     (configuration, values.into_iter().map(func).collect())
387                 })
388                 .collect(),
389         }
390     }
391 }
392 
393 // BTreeMap<U, T>
394 impl<U, T> Selectable for BTreeMap<U, T>
395 where
396     U: SelectableOrderedValue,
397     T: SelectableValue,
398 {
399     type ItemType = (U, T);
400     type CommonType = BTreeMap<U, T>;
401     type SelectsType = BTreeMap<U, T>;
402 
is_empty(this: &Select<Self>) -> bool403     fn is_empty(this: &Select<Self>) -> bool {
404         this.common.is_empty() && this.selects.is_empty()
405     }
406 
items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)>407     fn items(this: &Select<Self>) -> Vec<(Option<String>, Self::ItemType)> {
408         let mut result = Vec::new();
409         result.extend(
410             this.common
411                 .iter()
412                 .map(|(key, value)| (None, (key.clone(), value.clone()))),
413         );
414         result.extend(this.selects.iter().flat_map(|(configuration, values)| {
415             values
416                 .iter()
417                 .map(|(key, value)| (Some(configuration.clone()), (key.clone(), value.clone())))
418         }));
419         result
420     }
421 
values(this: &Select<Self>) -> Vec<Self::ItemType>422     fn values(this: &Select<Self>) -> Vec<Self::ItemType> {
423         let mut result = Vec::new();
424         result.extend(
425             this.common
426                 .iter()
427                 .map(|(key, value)| (key.clone(), value.clone())),
428         );
429         result.extend(this.selects.values().flat_map(|values| {
430             values
431                 .iter()
432                 .map(|(key, value)| (key.clone(), value.clone()))
433         }));
434         result
435     }
436 
insert( this: &mut Select<Self>, (key, value): Self::ItemType, configuration: Option<String>, )437     fn insert(
438         this: &mut Select<Self>,
439         (key, value): Self::ItemType,
440         configuration: Option<String>,
441     ) {
442         match configuration {
443             None => {
444                 this.selects.retain(|_, map| {
445                     map.remove(&key);
446                     !map.is_empty()
447                 });
448                 this.common.insert(key, value);
449             }
450             Some(configuration) => {
451                 if !this.common.contains_key(&key) {
452                     this.selects
453                         .entry(configuration)
454                         .or_default()
455                         .insert(key, value);
456                 }
457             }
458         }
459     }
460 
merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self>461     fn merge(lhs: Select<Self>, rhs: Select<Self>) -> Select<Self> {
462         let mut result: Select<Self> = Select::new();
463 
464         for (key, value) in lhs.common.into_iter() {
465             result.insert((key, value), None);
466         }
467         for (key, value) in rhs.common.into_iter() {
468             result.insert((key, value), None);
469         }
470 
471         for (configuration, entries) in lhs.selects.into_iter() {
472             for (key, value) in entries {
473                 result.insert((key, value), Some(configuration.clone()));
474             }
475         }
476         for (configuration, entries) in rhs.selects.into_iter() {
477             for (key, value) in entries {
478                 result.insert((key, value), Some(configuration.clone()));
479             }
480         }
481 
482         result
483     }
484 }
485