1use crate::dif::update::{DIFKey, DIFUpdateData};
2use crate::dif::value::DIFValueContainer;
3use crate::libs::core::CoreLibPointerId;
4use crate::references::mutations::DIFUpdateDataOrMemory;
5use crate::references::observers::TransceiverId;
6use crate::references::reference::AccessError;
7use crate::references::type_reference::TypeReference;
8use crate::runtime::execution::ExecutionError;
9use crate::stdlib::boxed::Box;
10use crate::stdlib::format;
11use crate::stdlib::string::String;
12use crate::stdlib::string::ToString;
13use crate::traits::apply::Apply;
14use crate::traits::structural_eq::StructuralEq;
15use crate::traits::value_eq::ValueEq;
16use crate::types::definition::TypeDefinition;
17use crate::values::core_value::CoreValue;
18use crate::values::core_values::callable::{
19 Callable, CallableBody, CallableSignature,
20};
21use crate::values::core_values::integer::typed_integer::TypedInteger;
22use crate::values::value_container::{ValueContainer, ValueError, ValueKey};
23use core::fmt::{Display, Formatter};
24use core::ops::{Add, AddAssign, Deref, Neg, Not, Sub};
25use core::prelude::rust_2024::*;
26use core::result::Result;
27use log::error;
28
29#[derive(Clone, Debug, Eq, PartialEq, Hash)]
30pub struct Value {
31 pub inner: CoreValue,
32 pub actual_type: Box<TypeDefinition>,
33}
34
35impl StructuralEq for Value {
38 fn structural_eq(&self, other: &Self) -> bool {
39 self.inner.structural_eq(&other.inner)
40 }
41}
42
43impl ValueEq for Value {
46 fn value_eq(&self, other: &Self) -> bool {
47 self == other
48 }
49}
50
51impl Deref for Value {
52 type Target = CoreValue;
53
54 fn deref(&self) -> &Self::Target {
55 &self.inner
56 }
57}
58
59impl Apply for Value {
60 fn apply(
61 &self,
62 args: &[ValueContainer],
63 ) -> Result<Option<ValueContainer>, ExecutionError> {
64 match self.inner {
65 CoreValue::Callable(ref callable) => callable.apply(args),
66 _ => Err(ExecutionError::InvalidApply),
67 }
68 }
69 fn apply_single(
70 &self,
71 arg: &ValueContainer,
72 ) -> Result<Option<ValueContainer>, ExecutionError> {
73 match self.inner {
74 CoreValue::Callable(ref callable) => callable.apply_single(arg),
75 _ => Err(ExecutionError::InvalidApply),
76 }
77 }
78}
79
80impl<T: Into<CoreValue>> From<T> for Value {
81 fn from(inner: T) -> Self {
82 let inner = inner.into();
83 let new_type = inner.default_type_definition();
84 Value {
85 inner,
86 actual_type: Box::new(new_type),
87 }
88 }
89}
90impl Value {
91 pub fn null() -> Self {
92 CoreValue::Null.into()
93 }
94}
95
96impl Value {
97 pub fn callable(
98 name: Option<String>,
99 signature: CallableSignature,
100 body: CallableBody,
101 ) -> Self {
102 Value {
103 inner: CoreValue::Callable(Callable {
104 name,
105 signature: signature.clone(),
106 body,
107 }),
108 actual_type: Box::new(TypeDefinition::callable(signature)),
109 }
110 }
111
112 pub fn is_type(&self) -> bool {
113 core::matches!(self.inner, CoreValue::Type(_))
114 }
115 pub fn is_null(&self) -> bool {
116 core::matches!(self.inner, CoreValue::Null)
117 }
118 pub fn is_text(&self) -> bool {
119 core::matches!(self.inner, CoreValue::Text(_))
120 }
121 pub fn is_integer_i8(&self) -> bool {
122 core::matches!(
123 &self.inner,
124 CoreValue::TypedInteger(TypedInteger::I8(_))
125 )
126 }
127 pub fn is_bool(&self) -> bool {
128 core::matches!(self.inner, CoreValue::Boolean(_))
129 }
130 pub fn is_map(&self) -> bool {
131 core::matches!(self.inner, CoreValue::Map(_))
132 }
133 pub fn is_list(&self) -> bool {
134 core::matches!(self.inner, CoreValue::List(_))
135 }
136 pub fn actual_type(&self) -> &TypeDefinition {
137 self.actual_type.as_ref()
138 }
139
140 pub fn has_default_type(&self) -> bool {
150 if let TypeDefinition::Reference(type_reference) =
151 self.actual_type.as_ref()
152 && let TypeReference {
153 pointer_address: Some(pointer_address),
154 ..
155 } = &*type_reference.borrow()
156 && let Ok(actual_type_core_ptr_id) =
157 CoreLibPointerId::try_from(pointer_address)
158 {
159 let self_default_type_ptr_id = CoreLibPointerId::from(&self.inner);
161 self_default_type_ptr_id == actual_type_core_ptr_id
162 } else {
163 false
164 }
165 }
166
167 pub fn try_get_property<'a>(
169 &self,
170 key: impl Into<ValueKey<'a>>,
171 ) -> Result<ValueContainer, AccessError> {
172 match self.inner {
173 CoreValue::Map(ref map) => {
174 Ok(map.get(key)?.clone())
176 }
177 CoreValue::List(ref list) => {
178 if let Some(index) = key.into().try_as_index() {
179 Ok(list.get(index)?.clone())
180 } else {
181 Err(AccessError::InvalidIndexKey)
182 }
183 }
184 CoreValue::Text(ref text) => {
185 if let Some(index) = key.into().try_as_index() {
186 let char = text.char_at(index)?;
187 Ok(ValueContainer::from(char.to_string()))
188 } else {
189 Err(AccessError::InvalidIndexKey)
190 }
191 }
192 _ => {
193 Err(AccessError::InvalidOperation(
195 "Cannot get property".to_string(),
196 ))
197 }
198 }
199 }
200
201 pub fn try_set_property<'a>(
203 &mut self,
204 key: impl Into<ValueKey<'a>>,
205 val: ValueContainer,
206 ) -> Result<(), AccessError> {
207 let key = key.into();
208
209 match self.inner {
210 CoreValue::Map(ref mut map) => {
211 map.try_set(key, val)?;
213 }
214 CoreValue::List(ref mut list) => {
215 if let Some(index) = key.try_as_index() {
216 list.set(index, val)
217 .map_err(|err| AccessError::IndexOutOfBounds(err))?;
218 } else {
219 return Err(AccessError::InvalidIndexKey);
220 }
221 }
222 CoreValue::Text(ref mut text) => {
223 if let Some(index) = key.try_as_index() {
224 if let ValueContainer::Value(v) = &val
225 && let CoreValue::Text(new_char) = &v.inner
226 && new_char.0.len() == 1
227 {
228 let char = new_char.0.chars().next().unwrap_or('\0');
229 text.set_char_at(index, char).map_err(|err| {
230 AccessError::IndexOutOfBounds(err)
231 })?;
232 } else {
233 return Err(AccessError::InvalidOperation(
234 "Can only set char character in text".to_string(),
235 ));
236 }
237 } else {
238 return Err(AccessError::InvalidIndexKey);
239 }
240 }
241 _ => {
242 return Err(AccessError::InvalidOperation(format!(
244 "Cannot set property '{}' on non-map value: {:?}",
245 key, self
246 )));
247 }
248 }
249
250 Ok(())
251 }
252}
253
254impl Add for Value {
255 type Output = Result<Value, ValueError>;
256 fn add(self, rhs: Value) -> Self::Output {
257 Ok((&self.inner + &rhs.inner)?.into())
258 }
259}
260
261impl Add for &Value {
262 type Output = Result<Value, ValueError>;
263 fn add(self, rhs: &Value) -> Self::Output {
264 Value::add(self.clone(), rhs.clone())
265 }
266}
267
268impl Sub for Value {
269 type Output = Result<Value, ValueError>;
270 fn sub(self, rhs: Value) -> Self::Output {
271 Ok((&self.inner - &rhs.inner)?.into())
272 }
273}
274
275impl Sub for &Value {
276 type Output = Result<Value, ValueError>;
277 fn sub(self, rhs: &Value) -> Self::Output {
278 Value::sub(self.clone(), rhs.clone())
279 }
280}
281
282impl Neg for Value {
283 type Output = Result<Value, ValueError>;
284
285 fn neg(self) -> Self::Output {
286 (-self.inner).map(Value::from)
287 }
288}
289
290impl Not for Value {
291 type Output = Option<Value>;
292
293 fn not(self) -> Self::Output {
294 (!self.inner).map(Value::from)
295 }
296}
297
298impl<T> AddAssign<T> for Value
300where
301 Value: From<T>,
302{
303 fn add_assign(&mut self, rhs: T) {
304 let rhs: Value = rhs.into();
305 let res = self.inner.clone() + rhs.inner;
306 if let Ok(res) = res {
307 self.inner = res;
308 } else {
309 error!("Failed to add value: {res:?}");
310 }
311 }
312}
313
314impl Display for Value {
315 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
316 core::write!(f, "{}", self.inner)
317 }
318}
319
320impl<T> From<Option<T>> for Value
321where
322 T: Into<Value>,
323{
324 fn from(opt: Option<T>) -> Self {
325 match opt {
326 Some(v) => v.into(),
327 None => Value::null(),
328 }
329 }
330}
331
332#[cfg(test)]
333mod tests {
337 use super::*;
338 use crate::libs::core::{get_core_lib_type, get_core_lib_type_reference};
339 use crate::{
340 assert_structural_eq, datex_list,
341 logger::init_logger_debug,
342 values::core_values::{
343 endpoint::Endpoint,
344 integer::{Integer, typed_integer::TypedInteger},
345 list::List,
346 },
347 };
348 use core::str::FromStr;
349 use log::info;
350
351 #[test]
352 fn endpoint() {
353 init_logger_debug();
354 let endpoint = Value::from(Endpoint::from_str("@test").unwrap());
355 assert_eq!(endpoint.to_string(), "@test");
356 }
357
358 #[test]
359 fn new_addition_assignments() {
360 let mut x = Value::from(42i8);
361 let y = Value::from(27i8);
362
363 x += y.clone();
364 assert_eq!(x, Value::from(69i8));
365 }
366
367 #[test]
368 fn new_additions() {
369 let x = Value::from(42i8);
370 let y = Value::from(27i8);
371
372 let z = (x.clone() + y.clone()).unwrap();
373 assert_eq!(z, Value::from(69i8));
374 }
375
376 #[test]
377 fn list() {
378 init_logger_debug();
379 let mut a = List::from(vec![
380 Value::from("42"),
381 Value::from(42),
382 Value::from(true),
383 ]);
384
385 a.push(Value::from(42));
386 a.push(4);
387
388 assert_eq!(a.len(), 5);
389
390 let b = List::from(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
391 assert_eq!(b.len(), 11);
392
393 let c = datex_list![1, "test", 3, true, false];
394 assert_eq!(c.len(), 5);
395 assert_eq!(c[0], 1.into());
396 assert_eq!(c[1], "test".into());
397 assert_eq!(c[2], 3.into());
398 }
399
400 #[test]
401 fn boolean() {
402 init_logger_debug();
403 let a = Value::from(true);
404 let b = Value::from(false);
405 let c = Value::from(false);
406 assert_ne!(a, b);
407 assert_eq!(b, c);
408
409 let d = (!b.clone()).unwrap();
410 assert_eq!(a, d);
411
412 let a_plus_b = a.clone() + b.clone();
414 assert!(a_plus_b.is_err());
415 }
416
417 #[test]
418 fn equality_same_type() {
419 init_logger_debug();
420 let a = Value::from(42i8);
421 let b = Value::from(42i8);
422 let c = Value::from(27i8);
423
424 assert_eq!(a, b);
425 assert_ne!(a, c);
426 assert_ne!(b, c);
427
428 info!("{} === {}", a.clone(), b.clone());
429 info!("{} !== {}", a.clone(), c.clone());
430 }
431
432 #[test]
433 fn decimal() {
434 init_logger_debug();
435 let a = Value::from(42.1f32);
436 let b = Value::from(27f32);
437
438 let a_plus_b = (a.clone() + b.clone()).unwrap();
439 assert_eq!(a_plus_b, Value::from(69.1f32));
440 info!("{} + {} = {}", a.clone(), b.clone(), a_plus_b);
441 }
442
443 #[test]
444 fn null() {
445 init_logger_debug();
446
447 let null_value = Value::null();
448 assert_eq!(null_value.to_string(), "null");
449
450 let maybe_value: Option<i8> = None;
451 let null_value = Value::from(maybe_value);
452 assert_eq!(null_value.to_string(), "null");
453 assert!(null_value.is_null());
454 }
455
456 #[test]
457 fn addition() {
458 init_logger_debug();
459 let a = Value::from(42i8);
460 let b = Value::from(27i8);
461
462 let a_plus_b = (a.clone() + b.clone()).unwrap();
463 assert_eq!(a_plus_b, Value::from(69i8));
464 info!("{} + {} = {}", a.clone(), b.clone(), a_plus_b);
465 }
466
467 #[test]
468 fn string_concatenation() {
469 init_logger_debug();
470 let a = Value::from("Hello ");
471 let b = Value::from(42i8);
472
473 assert!(a.is_text());
474 assert!(b.is_integer_i8());
475
476 let a_plus_b = (a.clone() + b.clone()).unwrap();
477 let b_plus_a = (b.clone() + a.clone()).unwrap();
478
479 assert!(a_plus_b.is_text());
480 assert!(b_plus_a.is_text());
481
482 assert_eq!(a_plus_b, Value::from("Hello 42"));
483 assert_eq!(b_plus_a, Value::from("42Hello "));
484
485 info!("{} + {} = {}", a.clone(), b.clone(), a_plus_b);
486 info!("{} + {} = {}", b.clone(), a.clone(), b_plus_a);
487 }
488
489 #[test]
490 fn structural_equality() {
491 let a = Value::from(42_i8);
492 let b = Value::from(42_i32);
493 assert!(a.is_integer_i8());
494
495 assert_structural_eq!(a, b);
496
497 assert_structural_eq!(
498 Value::from(TypedInteger::I8(42)),
499 Value::from(TypedInteger::U32(42)),
500 );
501
502 assert_structural_eq!(
503 Value::from(42_i8),
504 Value::from(Integer::from(42_i8))
505 );
506 }
507
508 #[test]
509 fn default_types() {
510 let val = Value::from(Integer::from(42));
511 assert!(val.has_default_type());
512
513 let val = Value::from(42i8);
514 assert!(val.has_default_type());
515
516 let val = Value {
517 inner: CoreValue::Integer(Integer::from(42)),
518 actual_type: Box::new(TypeDefinition::ImplType(
519 Box::new(get_core_lib_type(CoreLibPointerId::Integer(None))),
520 vec![],
521 )),
522 };
523
524 assert!(!val.has_default_type());
525 }
526}