microcad_lang/value/
argument_value_list.rs1use crate::{eval::*, value::*};
7use derive_more::{Deref, DerefMut};
8use microcad_lang_base::{SrcRef, SrcReferrer};
9
10#[derive(Clone, Default, Deref, DerefMut)]
15pub struct ArgumentValueList {
16 #[deref]
17 #[deref_mut]
18 map: Vec<(Identifier, ArgumentValue)>,
19 src_ref: SrcRef,
20}
21
22impl ArgumentValueList {
23 pub fn get_single(&self) -> EvalResult<(&Identifier, &ArgumentValue)> {
27 if self.map.len() == 1 {
28 if let Some(a) = self.map.first() {
29 return Ok((&a.0, &a.1));
30 }
31 }
32
33 Err(EvalError::ArgumentCountMismatch {
34 args: self.to_string(),
35 expected: 1,
36 found: self.map.len(),
37 })
38 }
39
40 pub fn get_by_type(&self, ty: &Type) -> Option<(&Identifier, &ArgumentValue)> {
42 let arg = self.map.iter().find(|(_, arg)| arg.value.ty() == *ty);
43 arg.map(|arg| (&arg.0, &arg.1))
44 }
45
46 pub fn get_by_index(&self, index: usize) -> Option<&(Identifier, ArgumentValue)> {
48 self.map.get(index)
49 }
50}
51
52impl ValueAccess for ArgumentValueList {
53 fn by_id(&self, id: &Identifier) -> Option<&Value> {
54 self.map
55 .iter()
56 .find(|(i, _)| i == id)
57 .map(|arg| &arg.1.value)
58 }
59
60 fn by_ty(&self, ty: &Type) -> Option<&Value> {
61 self.get_by_type(ty).map(|(_, arg)| &arg.value)
62 }
63}
64
65impl SrcReferrer for ArgumentValueList {
66 fn src_ref(&self) -> SrcRef {
67 self.src_ref.clone()
68 }
69}
70
71impl std::fmt::Display for ArgumentValueList {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 write!(f, "{}", {
74 let mut v = self
75 .map
76 .iter()
77 .map(|(id, val)| {
78 if !id.is_empty() {
79 format!("{id} = {}", val.value)
80 } else if let Some(id) = &val.inline_id {
81 format!("{id} = {}", val.value)
82 } else {
83 format!("{}", val.value)
84 }
85 })
86 .collect::<Vec<_>>();
87 v.sort();
88 v.join(", ")
89 })
90 }
91}
92
93impl std::fmt::Debug for ArgumentValueList {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 write!(f, "{}", {
96 let mut v = self
97 .map
98 .iter()
99 .map(|(id, val)| {
100 if !id.is_empty() {
101 format!("{id:?} = {:?}", val.value)
102 } else if let Some(id) = &val.inline_id {
103 format!("{id:?} = {:?}", val.value)
104 } else {
105 format!("{:?}", val.value)
106 }
107 })
108 .collect::<Vec<_>>();
109 v.sort();
110 v.join(", ")
111 })
112 }
113}
114
115impl FromIterator<(Identifier, ArgumentValue)> for ArgumentValueList {
116 fn from_iter<T: IntoIterator<Item = (Identifier, ArgumentValue)>>(iter: T) -> Self {
117 let map: Vec<_> = iter.into_iter().collect();
118 Self {
119 src_ref: SrcRef::merge_all(map.iter().map(|(_, v)| v.src_ref())),
120 map,
121 }
122 }
123}