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