microcad_lang/value/
array.rs1use crate::{ty::*, value::*};
7use derive_more::{Deref, DerefMut};
8
9#[derive(Clone, Deref, DerefMut)]
11pub struct Array {
12 #[deref]
14 #[deref_mut]
15 items: ValueList,
16 ty: Type,
18}
19
20impl Array {
21 pub fn new(ty: Type) -> Self {
23 Self {
24 items: ValueList::default(),
25 ty,
26 }
27 }
28
29 pub fn from_values(items: ValueList, ty: Type) -> Self {
31 Self { items, ty }
32 }
33
34 pub fn fetch(&self) -> Vec<Value> {
36 self.items.iter().cloned().collect::<Vec<_>>()
37 }
38}
39
40impl PartialEq for Array {
41 fn eq(&self, other: &Self) -> bool {
42 self.ty == other.ty && self.items == other.items
43 }
44}
45
46impl IntoIterator for Array {
47 type Item = Value;
48 type IntoIter = std::vec::IntoIter<Self::Item>;
49
50 fn into_iter(self) -> Self::IntoIter {
51 self.items.into_iter()
52 }
53}
54
55impl TryFrom<ValueList> for Array {
56 type Error = ValueError;
57 fn try_from(items: ValueList) -> ValueResult<Array> {
58 match items.types().common_type() {
59 Some(ty) => Ok(Array::from_values(items, ty)),
60 None => Err(ValueError::CommonTypeExpected),
61 }
62 }
63}
64
65impl FromIterator<Value> for Array {
66 fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self {
67 let items: ValueList = iter.into_iter().collect();
68 let ty = items.types().common_type().expect("Common type");
69 Self { ty, items }
70 }
71}
72
73impl std::fmt::Display for Array {
74 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
75 write!(
76 f,
77 "[{items}]",
78 items = self
79 .items
80 .iter()
81 .map(|v| v.to_string())
82 .collect::<Vec<_>>()
83 .join(", ")
84 )
85 }
86}
87
88impl std::fmt::Debug for Array {
89 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
90 write!(
91 f,
92 "[{items}]",
93 items = self
94 .items
95 .iter()
96 .map(|v| format!("{v:?}"))
97 .collect::<Vec<_>>()
98 .join(", ")
99 )
100 }
101}
102
103impl crate::ty::Ty for Array {
104 fn ty(&self) -> Type {
105 Type::Array(Box::new(self.ty.clone()))
106 }
107}
108
109impl std::ops::Add<Value> for Array {
111 type Output = ValueResult;
112
113 fn add(self, rhs: Value) -> Self::Output {
114 if self.ty.is_compatible_to(&rhs.ty()) {
115 Ok(Value::Array(Self::from_values(
116 ValueList::new(
117 self.items
118 .iter()
119 .map(|value| value.clone() + rhs.clone())
120 .collect::<Result<Vec<_>, _>>()?,
121 ),
122 self.ty,
123 )))
124 } else {
125 Err(ValueError::InvalidOperator("+".into()))
126 }
127 }
128}
129
130impl std::ops::Sub<Value> for Array {
132 type Output = ValueResult;
133
134 fn sub(self, rhs: Value) -> Self::Output {
135 if self.ty.is_compatible_to(&rhs.ty()) {
136 Ok(Value::Array(Self::from_values(
137 ValueList::new(
138 self.items
139 .iter()
140 .map(|value| value.clone() - rhs.clone())
141 .collect::<Result<Vec<_>, _>>()?,
142 ),
143 self.ty,
144 )))
145 } else {
146 Err(ValueError::InvalidOperator("-".into()))
147 }
148 }
149}
150
151impl std::ops::Mul<Value> for Array {
153 type Output = ValueResult;
154
155 fn mul(self, rhs: Value) -> Self::Output {
156 match self.ty {
157 Type::Quantity(_) | Type::Integer => Ok(Value::Array(Array::from_values(
159 ValueList::new({
160 self.iter()
161 .map(|value| value.clone() * rhs.clone())
162 .collect::<Result<Vec<_>, _>>()?
163 }),
164 self.ty * rhs.ty().clone(),
165 ))),
166 _ => Err(ValueError::InvalidOperator("*".into())),
167 }
168 }
169}
170
171impl std::ops::Div<Value> for Array {
173 type Output = ValueResult;
174
175 fn div(self, rhs: Value) -> Self::Output {
176 let values = ValueList::new(
177 self.iter()
178 .map(|value| value.clone() / rhs.clone())
179 .collect::<Result<Vec<_>, _>>()?,
180 );
181
182 match (&self.ty, rhs.ty()) {
183 (Type::Integer, Type::Integer) => Ok(Value::Array(Array::from_values(
185 values,
186 self.ty / rhs.ty().clone(),
187 ))),
188 (Type::Quantity(_), _) => Ok(Value::Array(values.try_into()?)),
189 _ => Err(ValueError::InvalidOperator("/".into())),
190 }
191 }
192}
193
194impl std::ops::Neg for Array {
195 type Output = ValueResult;
196
197 fn neg(self) -> Self::Output {
198 let items: ValueList = self
199 .iter()
200 .map(|value| -value.clone())
201 .collect::<Result<Vec<_>, _>>()?
202 .into_iter()
203 .collect();
204 Ok(Value::Array(items.try_into()?))
205 }
206}
207
208#[test]
209fn test_array_debug() {
210 let val1 = Value::Target(Target::new("my::name1".into(), Some("my::target1".into())));
211 let val2 = Value::Target(Target::new("my::name2".into(), None));
212
213 let mut array = Array::new(Type::Target);
214 array.push(val1);
215 array.push(val2);
216
217 log::info!("{array}");
218 log::info!("{array:?}");
219}