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 new(map: Vec<(Identifier, ArgumentValue)>, src_ref: SrcRef) -> Self {
24 Self { map, src_ref }
25 }
26
27 pub fn get_single(&self) -> EvalResult<(&Identifier, &ArgumentValue)> {
31 if self.map.len() == 1 {
32 if let Some(a) = self.map.first() {
33 return Ok((&a.0, &a.1));
34 }
35 }
36
37 Err(EvalError::ArgumentCountMismatch {
38 args: self.to_string(),
39 expected: 1,
40 found: self.map.len(),
41 })
42 }
43
44 pub fn get_by_type(&self, ty: &Type) -> Option<(&Identifier, &ArgumentValue)> {
46 let arg = self.map.iter().find(|(_, arg)| arg.value.ty() == *ty);
47 arg.map(|arg| (&arg.0, &arg.1))
48 }
49}
50
51impl ValueAccess for ArgumentValueList {
52 fn by_id(&self, id: &Identifier) -> Option<&Value> {
53 self.map
54 .iter()
55 .find(|(i, _)| i == id)
56 .map(|arg| &arg.1.value)
57 }
58
59 fn by_ty(&self, ty: &Type) -> Option<&Value> {
60 self.get_by_type(ty).map(|(_, arg)| &arg.value)
61 }
62}
63
64impl SrcReferrer for ArgumentValueList {
65 fn src_ref(&self) -> SrcRef {
66 self.src_ref.clone()
67 }
68}
69
70impl std::fmt::Display for ArgumentValueList {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 write!(f, "{}", {
73 let mut v = self
74 .map
75 .iter()
76 .map(|(id, p)| format!("{id}{p}"))
77 .collect::<Vec<_>>();
78 v.sort();
79 v.join(", ")
80 })
81 }
82}
83
84impl std::fmt::Debug for ArgumentValueList {
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 write!(f, "{}", {
87 let mut v = self
88 .map
89 .iter()
90 .map(|(id, av)| format!("{id:?}{av:?}"))
91 .collect::<Vec<_>>();
92 v.sort();
93 v.join(", ")
94 })
95 }
96}
97
98impl FromIterator<(Identifier, ArgumentValue)> for ArgumentValueList {
99 fn from_iter<T: IntoIterator<Item = (Identifier, ArgumentValue)>>(iter: T) -> Self {
100 let map: Vec<_> = iter.into_iter().collect();
101 Self {
102 src_ref: SrcRef::merge_all(map.iter().map(|(_, v)| v.src_ref())),
103 map,
104 }
105 }
106}
107
108#[test]
109fn test_argument_value_debug() {
110 let arg1 = ArgumentValue::new(
111 Value::Target(Target::new("my::name1".into(), Some("my::target1".into()))),
112 Some("id1".into()),
113 SrcRef(None),
114 );
115
116 let arg2 = ArgumentValue::new(
117 Value::Target(Target::new("my::name2".into(), None)),
118 Some("id2".into()),
119 SrcRef(None),
120 );
121
122 let mut args = ArgumentValueList::default();
123
124 args.push(("id1".into(), arg1));
125 args.push(("id2".into(), arg2));
126
127 log::info!("{args}");
128 log::info!("{args:?}");
129}