1use std::fmt::Display;
2use std::marker::PhantomData;
3use std::ops::{Deref, Index};
4use std::str::FromStr;
5
6use fugue_arch::ArchitectureDef;
7use fugue_bytes::Endian;
8
9use serde::de::{Error, Visitor};
10use serde::ser::SerializeMap;
11use serde::{Deserialize, Deserializer, Serialize, Serializer};
12
13use thiserror::Error;
14
15#[derive(Clone, Deserialize, Serialize)]
16#[serde(untagged)]
17pub enum OneOrMany<T> {
18 One(T),
19 Many(Vec<T>),
20}
21
22impl<T> Default for OneOrMany<T> {
23 fn default() -> Self {
24 Self::Many(Vec::with_capacity(0))
25 }
26}
27
28impl<T> From<OneOrMany<T>> for Vec<T> {
29 fn from(value: OneOrMany<T>) -> Self {
30 match value {
31 OneOrMany::One(v) => vec![v],
32 OneOrMany::Many(vs) => vs,
33 }
34 }
35}
36
37impl<T> From<Vec<T>> for OneOrMany<T> {
38 fn from(value: Vec<T>) -> Self {
39 if value.len() == 1 {
40 Self::One(value.into_iter().next().unwrap())
41 } else {
42 Self::Many(value)
43 }
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Hash)]
48pub struct AttrWithVal<A, V> {
49 pub attr: A,
50 pub val: V,
51}
52
53struct AttrWithValVisitor<T, A>(PhantomData<(T, A)>);
54
55impl<T, A> Default for AttrWithValVisitor<T, A> {
56 fn default() -> Self {
57 AttrWithValVisitor(PhantomData)
58 }
59}
60
61impl<'de, A, V> Visitor<'de> for AttrWithValVisitor<A, V>
62where
63 A: FromStr,
64 V: Deserialize<'de>,
65{
66 type Value = AttrWithVal<A, V>;
67
68 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
69 formatter.write_str("attribute/value pair; e.g., key: value")
70 }
71
72 fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
73 where
74 M: serde::de::MapAccess<'de>,
75 {
76 let attr = if let Some(attr) = map.next_key::<String>()?.as_deref() {
77 attr.parse::<A>()
78 .map_err(|_| Error::custom("cannot parse attribute"))?
79 } else {
80 return Err(Error::custom(format!("expected attribute")))?;
81 };
82
83 let val = map.next_value::<V>()?;
84
85 Ok(AttrWithVal { attr, val })
86 }
87}
88
89impl<'de, A, V> Deserialize<'de> for AttrWithVal<A, V>
90where
91 A: FromStr,
92 V: Deserialize<'de>,
93{
94 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
95 where
96 D: serde::Deserializer<'de>,
97 {
98 deserializer.deserialize_any(AttrWithValVisitor::default())
99 }
100}
101
102impl<A, V> Serialize for AttrWithVal<A, V>
103where
104 A: ToString,
105 V: Serialize,
106{
107 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
108 where
109 S: serde::Serializer,
110 {
111 let mut map = serializer.serialize_map(Some(1))?;
112 map.serialize_entry(&self.attr.to_string(), &self.val)?;
113 map.end()
114 }
115}
116
117#[derive(Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
118#[serde(
119 bound(deserialize = "A: FromStr, V: Deserialize<'de>"),
120 bound(serialize = "A: ToString, V: Serialize"),
121 untagged
122)]
123pub enum AttrOptWithVal<A, V> {
124 Val(V),
125 AttrWithVal(AttrWithVal<A, V>),
126}
127
128impl<A, V> From<AttrOptWithVal<A, V>> for (A, V)
129where
130 A: Default + FromStr,
131{
132 fn from(v: AttrOptWithVal<A, V>) -> Self {
133 match v {
134 AttrOptWithVal::Val(v) => (Default::default(), v),
135 AttrOptWithVal::AttrWithVal(av) => (av.attr, av.val),
136 }
137 }
138}
139
140#[derive(Debug, Deserialize, PartialEq, Eq, Hash, Serialize)]
141#[serde(
142 bound(deserialize = "A: FromStr, U: Deserialize<'de>, V: Deserialize<'de>"),
143 bound(serialize = "A: ToString, U: Serialize, V: Serialize"),
144 untagged
145)]
146pub enum AttrOptWithValOr<A, U, V>
147where
148 A: FromStr,
149{
150 Val(U),
151 AttrWithVal(AttrWithVal<A, V>),
152}
153
154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
155#[serde(rename_all = "kebab-case")]
156pub enum GroupKind {
157 All,
158 Any,
159 NotAll,
160 NotAny,
161}
162
163impl Default for GroupKind {
164 fn default() -> Self {
165 GroupKind::All
166 }
167}
168
169#[derive(Debug, Clone, PartialEq, Eq, Hash)]
170pub struct Group<T> {
171 kind: GroupKind,
172 values: Vec<T>,
173}
174
175impl<T> Group<T> {
176 #[inline]
177 pub fn kind(&self) -> GroupKind {
178 self.kind
179 }
180
181 #[inline]
182 pub fn values(&self) -> &[T] {
183 &self.values
184 }
185}
186
187impl<T> Index<usize> for Group<T> {
188 type Output = T;
189
190 fn index(&self, index: usize) -> &Self::Output {
191 &self.values[index]
192 }
193}
194
195#[derive(Debug, Clone, PartialEq, Eq, Hash)]
196#[repr(transparent)]
197pub struct Groups<T>(Vec<Group<T>>);
198
199impl<T> Deref for Groups<T> {
200 type Target = Vec<Group<T>>;
201
202 fn deref(&self) -> &Self::Target {
203 &self.0
204 }
205}
206
207impl<T> Index<usize> for Groups<T> {
208 type Output = Group<T>;
209
210 fn index(&self, index: usize) -> &Self::Output {
211 &self.0[index]
212 }
213}
214
215impl<T> Groups<T> {
216 #[inline]
217 pub fn is_empty(&self) -> bool {
218 self.0.is_empty()
219 }
220
221 #[inline]
222 pub fn len(&self) -> usize {
223 self.0.len()
224 }
225
226 #[inline]
227 pub fn iter(&self) -> impl ExactSizeIterator<Item = &Group<T>> {
228 self.0.iter()
229 }
230
231 #[inline]
232 pub fn groups(&self) -> &[Group<T>] {
233 &self.0
234 }
235}
236
237impl<T> Default for Groups<T> {
238 fn default() -> Self {
239 Self(Vec::new())
240 }
241}
242
243struct GroupVisitor<T>(PhantomData<T>);
244
245impl<T> Default for GroupVisitor<T> {
246 fn default() -> Self {
247 GroupVisitor(PhantomData)
248 }
249}
250
251impl<'de, T> Visitor<'de> for GroupVisitor<T>
252where
253 T: Deserialize<'de>,
254{
255 type Value = Groups<T>;
256
257 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
258 formatter.write_str("")
259 }
260
261 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
262 where
263 A: serde::de::SeqAccess<'de>,
264 {
265 let kind = Default::default();
266 let mut values = Vec::with_capacity(seq.size_hint().unwrap_or(0));
267
268 while let Some(value) = seq.next_element()? {
269 values.push(value);
270 }
271
272 Ok(Groups(vec![Group { kind, values }]))
273 }
274
275 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
276 where
277 A: serde::de::MapAccess<'de>,
278 {
279 let mut groups = Vec::with_capacity(map.size_hint().unwrap_or(0));
280
281 loop {
282 let mut is_not = false;
283
284 let kind = match map.next_key::<String>()?.as_deref() {
285 Some("and" | "all") => GroupKind::All,
286 Some("any" | "or") => GroupKind::Any,
287 Some("not-all") => GroupKind::NotAll,
288 Some("not-any") => GroupKind::NotAny,
289 Some("not") => {
290 is_not = true;
291 GroupKind::NotAny
292 }
293 Some(c) => {
294 return Err(Error::custom(format!("unknown grouping operator `{c}`")));
295 }
296 None => break,
297 };
298
299 let values = if is_not {
300 vec![map.next_value::<T>()?]
301 } else {
302 map.next_value::<Vec<T>>()?
303 };
304
305 groups.push(Group { kind, values });
306 }
307
308 Ok(Groups(groups))
309 }
310}
311
312impl<'de, T> Deserialize<'de> for Groups<T>
313where
314 T: Deserialize<'de>,
315{
316 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
317 where
318 D: serde::Deserializer<'de>,
319 {
320 deserializer.deserialize_any(GroupVisitor::default())
321 }
322}
323
324impl<T> Serialize for Groups<T>
325where
326 T: Serialize,
327{
328 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
329 where
330 S: Serializer,
331 {
332 let mut map = serializer.serialize_map(Some(self.len()))?;
333
334 for group in self.groups() {
335 map.serialize_entry(&group.kind(), group.values())?;
336 }
337
338 map.end()
339 }
340}
341
342#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
343#[serde(untagged)]
344pub enum GroupOrValue<T> {
345 Group(Groups<GroupOrValue<T>>),
346 Value(T),
347}
348
349pub trait GroupOrValueVisitor<T> {
350 fn matches_value(&self, value: &T) -> bool;
351}
352
353impl<T> GroupOrValue<T> {
354 pub fn matches<V>(&self, visitor: &V) -> bool
355 where
356 V: GroupOrValueVisitor<T>,
357 {
358 match self {
359 Self::Value(t) => visitor.matches_value(t),
360 Self::Group(group) => group.iter().any(|g| match g.kind() {
361 GroupKind::All => g.values().iter().all(|v| v.matches(visitor)),
362 GroupKind::Any => g.values().iter().any(|v| v.matches(visitor)),
363 GroupKind::NotAll => !g.values().iter().all(|v| v.matches(visitor)),
364 GroupKind::NotAny => !g.values().iter().any(|v| v.matches(visitor)),
365 }),
366 }
367 }
368}
369
370#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
371pub struct Language {
372 processor: String,
373 endian: Endian,
374 bits: Option<u32>,
375 variant: Option<String>,
376 convention: Option<String>,
377}
378
379impl Language {
380 pub fn new(processor: impl Into<String>, endian: Endian) -> Self {
381 Self::new_with(processor, endian, None, None, None)
382 }
383
384 pub fn new_with(
385 processor: impl Into<String>,
386 endian: Endian,
387 bits: impl Into<Option<u32>>,
388 variant: impl Into<Option<String>>,
389 convention: impl Into<Option<String>>,
390 ) -> Self {
391 Self {
392 processor: processor.into(),
393 endian,
394 bits: bits.into(),
395 variant: variant.into(),
396 convention: convention.into(),
397 }
398 }
399
400 pub fn matches(&self, other: &Self) -> bool {
401 (other.processor() == self.processor())
402 && (other.endian() == self.endian())
403 && (other.bits().is_none() || self.bits().is_none() || other.bits() == self.bits())
404 && (other.variant().is_none()
405 || self.variant().is_none()
406 || other.variant() == self.variant())
407 && (other.convention().is_none()
408 || self.convention().is_none()
409 || other.convention() == self.convention())
410 }
411
412 pub fn matches_arch(&self, arch: &ArchitectureDef) -> bool {
413 (arch.processor() == self.processor())
414 && (arch.endian() == self.endian())
415 && (self.bits().is_none() || arch.bits() as u32 == self.bits().unwrap())
416 && (self.variant().is_none() || arch.variant() == self.variant().unwrap())
417 }
418
419 pub fn processor(&self) -> &str {
420 &self.processor
421 }
422
423 pub fn endian(&self) -> Endian {
424 self.endian
425 }
426
427 pub fn bits(&self) -> Option<u32> {
428 self.bits
429 }
430
431 pub fn variant(&self) -> Option<&str> {
432 self.variant.as_deref()
433 }
434
435 pub fn convention(&self) -> Option<&str> {
436 self.convention.as_deref()
437 }
438}
439
440#[derive(Debug, Error)]
441pub enum LanguageParseError {
442 #[error("architecture format is invalid")]
443 Format,
444 #[error("invalid architecture processor (should be non-empty string and not '*')")]
445 Processor,
446 #[error("invalid architecture endian (should be LE or BE)")]
447 Endian,
448 #[error("invalid architecture bits (should be numeric or '*')")]
449 Bits,
450 #[error("invalid architecture variant (should be non-empty string or '*')")]
451 Variant,
452 #[error("invalid architecture convention (should be non-empty string or '*')")]
453 Convention,
454}
455
456impl FromStr for Language {
457 type Err = LanguageParseError;
458
459 fn from_str(s: &str) -> Result<Self, Self::Err> {
460 let parts = s.splitn(5, ':').collect::<Vec<_>>();
461 if parts.len() < 3 {
462 return Err(LanguageParseError::Format);
463 }
464
465 let processor = if parts[0] == "*" || parts[0].is_empty() {
466 return Err(LanguageParseError::Processor);
467 } else {
468 parts[0].to_owned()
469 };
470
471 let endian = match parts[1] {
472 "le" | "LE" => Endian::Little,
473 "be" | "BE" => Endian::Big,
474 _ => {
475 return Err(LanguageParseError::Endian);
476 }
477 };
478
479 let bits = if parts[2] == "*" {
480 None
481 } else {
482 match parts[2].parse::<u32>() {
483 Ok(bits) => Some(bits),
484 Err(_) => {
485 return Err(LanguageParseError::Bits);
486 }
487 }
488 };
489
490 let variant = if parts.len() < 4 || parts[3] == "*" {
491 None
492 } else if parts[3].is_empty() {
493 return Err(LanguageParseError::Variant);
494 } else {
495 Some(parts[3].to_owned())
496 };
497
498 let convention = if parts.len() < 5 || parts[4] == "*" {
499 None
500 } else if parts[4].is_empty() {
501 return Err(LanguageParseError::Convention);
502 } else {
503 Some(parts[4].to_owned())
504 };
505
506 Ok(Language {
507 processor,
508 endian,
509 bits,
510 variant,
511 convention,
512 })
513 }
514}
515
516impl Display for Language {
517 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
518 let endian = match self.endian {
519 Endian::Big => "BE",
520 Endian::Little => "LE",
521 };
522
523 let bits = self
524 .bits
525 .as_ref()
526 .map(|bits| bits as &dyn Display)
527 .unwrap_or_else(|| &"*" as &dyn Display);
528
529 let variant = self.variant.as_deref().unwrap_or("*");
530 let convention = self.convention.as_deref().unwrap_or("*");
531
532 write!(
533 f,
534 "{}:{}:{}:{}:{}",
535 self.processor, endian, bits, variant, convention
536 )
537 }
538}
539
540impl<'de> Deserialize<'de> for Language {
541 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
542 where
543 D: Deserializer<'de>,
544 {
545 let s = String::deserialize(deserializer)?;
546 Language::from_str(&s).map_err(D::Error::custom)
547 }
548}
549
550impl Serialize for Language {
551 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
552 where
553 S: Serializer,
554 {
555 let parts = self.to_string();
556 serializer.serialize_str(&parts)
557 }
558}
559
560#[cfg(test)]
561mod test {
562 use super::*;
563
564 #[test]
565 fn test_basic_groups() -> Result<(), Box<dyn std::error::Error>> {
566 let map1 = r"
567- blah
568- blah1
569- blah2
570";
571 let map2 = r"
572or:
573 - blah
574 - blah1
575 - blah2
576";
577
578 let map3 = r"
579or:
580 - blah
581 - blah1
582 - blah2
583and:
584 - blah4
585";
586
587 let map4 = r"
588or:
589 - not: blah0
590 - blah1
591 - blah2
592not: blah4
593";
594
595 let map5 = r"
596blah
597";
598
599 let map1_group: Groups<String> = serde_yaml::from_str(map1)?;
600
601 assert_eq!(
602 map1_group,
603 Groups(vec![Group {
604 kind: GroupKind::All,
605 values: vec!["blah".to_owned(), "blah1".to_owned(), "blah2".to_owned()],
606 }])
607 );
608
609 let map2_group: Groups<String> = serde_yaml::from_str(map2)?;
610
611 assert_eq!(
612 map2_group,
613 Groups(vec![Group {
614 kind: GroupKind::Any,
615 values: vec!["blah".to_owned(), "blah1".to_owned(), "blah2".to_owned()],
616 }])
617 );
618
619 let map3_group: Groups<String> = serde_yaml::from_str(map3)?;
620
621 assert_eq!(
622 map3_group,
623 Groups(vec![
624 Group {
625 kind: GroupKind::Any,
626 values: vec!["blah".to_owned(), "blah1".to_owned(), "blah2".to_owned()],
627 },
628 Group {
629 kind: GroupKind::All,
630 values: vec!["blah4".to_owned()],
631 },
632 ]),
633 );
634
635 let map4_group: GroupOrValue<String> = serde_yaml::from_str(map4)?;
636
637 assert_eq!(
638 map4_group,
639 GroupOrValue::Group(Groups(vec![
640 Group {
641 kind: GroupKind::Any,
642 values: vec![
643 GroupOrValue::Group(Groups(vec![Group {
644 kind: GroupKind::NotAny,
645 values: vec![GroupOrValue::Value("blah0".to_owned())]
646 }])),
647 GroupOrValue::Value("blah1".to_owned()),
648 GroupOrValue::Value("blah2".to_owned())
649 ],
650 },
651 Group {
652 kind: GroupKind::NotAny,
653 values: vec![GroupOrValue::Value("blah4".to_owned())],
654 },
655 ])),
656 );
657
658 let map5_group: GroupOrValue<String> = serde_yaml::from_str(map5)?;
659
660 assert_eq!(map5_group, GroupOrValue::Value("blah".to_owned()));
661
662 Ok(())
663 }
664}