microcad_lang/value/
argument_value_list.rs1use crate::{eval::*, src_ref::*, value::*};
7use derive_more::Deref;
8
9#[derive(Clone, Debug, Default, Deref)]
14pub struct ArgumentValueList {
15 #[deref]
16 map: Vec<(Identifier, ArgumentValue)>,
17 src_ref: SrcRef,
18}
19
20impl ArgumentValueList {
21 pub fn new(map: Vec<(Identifier, ArgumentValue)>, src_ref: SrcRef) -> Self {
23 Self { map, src_ref }
24 }
25
26 pub fn get_single(&self) -> EvalResult<(&Identifier, &ArgumentValue)> {
30 if self.map.len() == 1 {
31 if let Some(a) = self.map.first() {
32 return Ok((&a.0, &a.1));
33 }
34 }
35
36 Err(EvalError::ArgumentCountMismatch {
37 args: self.clone(),
38 expected: 1,
39 found: self.map.len(),
40 })
41 }
42
43 pub fn get_by_type(&self, ty: &Type) -> Option<(&Identifier, &ArgumentValue)> {
45 let arg = self.map.iter().find(|(_, arg)| arg.value.ty() == *ty);
46 arg.map(|arg| (&arg.0, &arg.1))
47 }
48}
49
50impl ValueAccess for ArgumentValueList {
51 fn by_id(&self, id: &Identifier) -> Option<&Value> {
52 self.map
53 .iter()
54 .find(|(i, _)| i == id)
55 .map(|arg| &arg.1.value)
56 }
57
58 fn by_ty(&self, ty: &Type) -> Option<&Value> {
59 self.get_by_type(ty).map(|(_, arg)| &arg.value)
60 }
61}
62
63impl SrcReferrer for ArgumentValueList {
64 fn src_ref(&self) -> SrcRef {
65 self.src_ref.clone()
66 }
67}
68
69impl std::fmt::Display for ArgumentValueList {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 write!(f, "{}", {
72 let mut v = self
73 .map
74 .iter()
75 .map(|(id, p)| format!("{id:?}: {p}"))
76 .collect::<Vec<_>>();
77 v.sort();
78 v.join(", ")
79 })
80 }
81}
82
83impl FromIterator<(Identifier, ArgumentValue)> for ArgumentValueList {
84 fn from_iter<T: IntoIterator<Item = (Identifier, ArgumentValue)>>(iter: T) -> Self {
85 let map: Vec<_> = iter.into_iter().collect();
86 Self {
87 src_ref: SrcRef::merge_all(map.iter().map(|(_, v)| v.src_ref())),
88 map,
89 }
90 }
91}