1use core::prelude::rust_2024::*;
2use core::result::Result;
3use datex_macros::FromCoreValue;
4
5use crate::libs::core::{CoreLibPointerId, get_core_lib_type_reference};
6use crate::stdlib::string::String;
7use crate::stdlib::string::ToString;
8use crate::stdlib::vec::Vec;
9use crate::traits::structural_eq::StructuralEq;
10use crate::traits::value_eq::ValueEq;
11use crate::types::definition::TypeDefinition;
12use crate::values::core_values::boolean::Boolean;
13use crate::values::core_values::callable::Callable;
14use crate::values::core_values::decimal::Decimal;
15use crate::values::core_values::decimal::typed_decimal::{
16 DecimalTypeVariant, TypedDecimal,
17};
18use crate::values::core_values::endpoint::Endpoint;
19use crate::values::core_values::integer::Integer;
20use crate::values::core_values::integer::typed_integer::{
21 IntegerTypeVariant, TypedInteger,
22};
23use crate::values::core_values::list::List;
24use crate::values::core_values::map::Map;
25use crate::values::core_values::text::Text;
26use crate::values::core_values::r#type::Type;
27use crate::values::value_container::{ValueContainer, ValueError};
28use core::fmt::{Display, Formatter};
29use core::ops::{Add, AddAssign, Neg, Not, Sub};
30
31#[derive(Clone, Debug, PartialEq, Eq, Hash, FromCoreValue)]
32pub enum CoreValue {
33 Null,
34 Boolean(Boolean),
35 Integer(Integer),
36 TypedInteger(TypedInteger),
37 Decimal(Decimal),
38 TypedDecimal(TypedDecimal),
39 Text(Text),
40 Endpoint(Endpoint),
41 List(List),
42 Map(Map),
43 Type(Type),
44 Callable(Callable),
45}
46impl StructuralEq for CoreValue {
47 fn structural_eq(&self, other: &Self) -> bool {
48 match (self, other) {
49 (CoreValue::Boolean(a), CoreValue::Boolean(b)) => {
50 a.structural_eq(b)
51 }
52
53 (CoreValue::Integer(a), CoreValue::Integer(b)) => {
55 a.structural_eq(b)
56 }
57
58 (CoreValue::TypedInteger(a), CoreValue::TypedInteger(b)) => {
60 a.structural_eq(b)
61 }
62
63 (CoreValue::Integer(a), CoreValue::TypedInteger(b))
65 | (CoreValue::TypedInteger(b), CoreValue::Integer(a)) => {
66 TypedInteger::IBig(a.clone()).structural_eq(b)
67 }
68
69 (CoreValue::Decimal(a), CoreValue::Decimal(b)) => {
71 a.structural_eq(b)
72 }
73
74 (CoreValue::TypedDecimal(a), CoreValue::TypedDecimal(b)) => {
76 a.structural_eq(b)
77 }
78
79 (CoreValue::Decimal(a), CoreValue::TypedDecimal(b))
81 | (CoreValue::TypedDecimal(b), CoreValue::Decimal(a)) => {
82 TypedDecimal::Decimal(a.clone()).structural_eq(b)
83 }
84
85 (CoreValue::Text(a), CoreValue::Text(b)) => a.structural_eq(b),
86 (CoreValue::Null, CoreValue::Null) => true,
87 (CoreValue::Endpoint(a), CoreValue::Endpoint(b)) => {
88 a.structural_eq(b)
89 }
90 (CoreValue::List(a), CoreValue::List(b)) => a.structural_eq(b),
91 (CoreValue::Map(a), CoreValue::Map(b)) => a.structural_eq(b),
92 (CoreValue::Type(a), CoreValue::Type(b)) => a.structural_eq(b),
93 (CoreValue::Callable(a), CoreValue::Callable(b)) => {
94 a.structural_eq(b)
95 }
96 _ => false,
97 }
98 }
99}
100
101impl ValueEq for CoreValue {
105 fn value_eq(&self, other: &Self) -> bool {
106 match (self, other) {
107 (CoreValue::Decimal(a), CoreValue::Decimal(b)) => a.value_eq(b),
108 (CoreValue::TypedDecimal(a), CoreValue::TypedDecimal(b)) => {
109 a.value_eq(b)
110 }
111 _ => self == other,
112 }
113 }
114}
115
116impl From<&str> for CoreValue {
117 fn from(value: &str) -> Self {
118 CoreValue::Text(value.into())
119 }
120}
121impl From<String> for CoreValue {
122 fn from(value: String) -> Self {
123 CoreValue::Text(Text(value))
124 }
125}
126
127impl<T> From<Vec<T>> for CoreValue
128where
129 T: Into<ValueContainer>,
130{
131 fn from(vec: Vec<T>) -> Self {
132 CoreValue::List(vec.into())
133 }
134}
135
136impl<T> FromIterator<T> for CoreValue
137where
138 T: Into<ValueContainer>,
139{
140 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
141 CoreValue::List(List::new(iter.into_iter().map(Into::into).collect()))
142 }
143}
144
145impl From<bool> for CoreValue {
146 fn from(value: bool) -> Self {
147 CoreValue::Boolean(value.into())
148 }
149}
150
151impl From<i8> for CoreValue {
152 fn from(value: i8) -> Self {
153 CoreValue::TypedInteger(value.into())
154 }
155}
156impl From<i16> for CoreValue {
157 fn from(value: i16) -> Self {
158 CoreValue::TypedInteger(value.into())
159 }
160}
161impl From<i32> for CoreValue {
162 fn from(value: i32) -> Self {
163 CoreValue::TypedInteger(value.into())
164 }
165}
166impl From<i64> for CoreValue {
167 fn from(value: i64) -> Self {
168 CoreValue::TypedInteger(value.into())
169 }
170}
171impl From<i128> for CoreValue {
172 fn from(value: i128) -> Self {
173 CoreValue::TypedInteger(value.into())
174 }
175}
176
177impl From<u8> for CoreValue {
178 fn from(value: u8) -> Self {
179 CoreValue::TypedInteger(value.into())
180 }
181}
182impl From<u16> for CoreValue {
183 fn from(value: u16) -> Self {
184 CoreValue::TypedInteger(value.into())
185 }
186}
187impl From<u32> for CoreValue {
188 fn from(value: u32) -> Self {
189 CoreValue::TypedInteger(value.into())
190 }
191}
192impl From<u64> for CoreValue {
193 fn from(value: u64) -> Self {
194 CoreValue::TypedInteger(value.into())
195 }
196}
197impl From<u128> for CoreValue {
198 fn from(value: u128) -> Self {
199 CoreValue::TypedInteger(value.into())
200 }
201}
202
203impl From<f32> for CoreValue {
204 fn from(value: f32) -> Self {
205 CoreValue::TypedDecimal(value.into())
206 }
207}
208impl From<f64> for CoreValue {
209 fn from(value: f64) -> Self {
210 CoreValue::TypedDecimal(value.into())
211 }
212}
213
214impl From<&CoreValue> for CoreLibPointerId {
215 fn from(value: &CoreValue) -> Self {
216 match value {
217 CoreValue::Map(_) => CoreLibPointerId::Map,
218 CoreValue::List(_) => CoreLibPointerId::List,
219 CoreValue::Text(_) => CoreLibPointerId::Text,
220 CoreValue::Boolean(_) => CoreLibPointerId::Boolean,
221 CoreValue::TypedInteger(i) => CoreLibPointerId::from(i),
222 CoreValue::TypedDecimal(d) => CoreLibPointerId::from(d),
223 CoreValue::Integer(_) => CoreLibPointerId::Integer(None),
224 CoreValue::Decimal(_) => CoreLibPointerId::Decimal(None),
225 CoreValue::Endpoint(_) => CoreLibPointerId::Endpoint,
226 CoreValue::Null => CoreLibPointerId::Null,
227 CoreValue::Type(_) => CoreLibPointerId::Type,
228 CoreValue::Callable(_) => CoreLibPointerId::Callable,
229 }
230 }
231}
232
233impl CoreValue {
234 pub fn new<T>(value: T) -> CoreValue
235 where
236 CoreValue: From<T>,
237 {
238 value.into()
239 }
240
241 pub fn is_collection_value(&self) -> bool {
244 core::matches!(self, CoreValue::List(_) | CoreValue::Map(_))
245 }
246
247 pub fn default_type_definition(&self) -> TypeDefinition {
252 TypeDefinition::Reference(get_core_lib_type_reference(
253 CoreLibPointerId::from(self),
254 ))
255 }
256
257 pub fn cast_to_type(&self) -> Option<&Type> {
260 match self {
261 CoreValue::Type(ty) => Some(ty),
262 _ => None,
263 }
264 }
265
266 pub fn cast_to_text(&self) -> Text {
267 match self {
268 CoreValue::Text(text) => text.clone(),
269 _ => Text(self.to_string()),
270 }
271 }
272
273 pub fn cast_to_bool(&self) -> Option<Boolean> {
274 match self {
275 CoreValue::Text(text) => Some(Boolean(!text.0.is_empty())),
276 CoreValue::Boolean(bool) => Some(bool.clone()),
277 CoreValue::TypedInteger(int) => Some(Boolean(int.as_i128()? != 0)),
278 CoreValue::Null => Some(Boolean(false)),
279 _ => None,
280 }
281 }
282
283 pub fn cast_to_decimal(&self) -> Option<Decimal> {
284 match self {
285 CoreValue::Text(text) => {
286 text.to_string().parse::<f64>().ok().map(Decimal::from)
287 }
288 CoreValue::TypedInteger(int) => {
289 Some(Decimal::from(int.as_i128()? as f64))
290 }
291 CoreValue::TypedDecimal(decimal) => {
292 Some(Decimal::from(decimal.clone()))
293 }
294 CoreValue::Integer(int) => {
295 Some(Decimal::from(int.as_i128()? as f64))
296 }
297 CoreValue::Decimal(decimal) => Some(decimal.clone()),
298 _ => None,
299 }
300 }
301
302 pub fn cast_to_typed_decimal(
303 &self,
304 variant: DecimalTypeVariant,
305 ) -> Option<TypedDecimal> {
306 match self {
307 CoreValue::Text(text) => {
308 TypedDecimal::from_string_and_variant_in_range(
309 text.as_str(),
310 variant,
311 )
312 .ok()
313 }
314 CoreValue::TypedInteger(int) => Some(
315 TypedDecimal::from_string_and_variant_in_range(
316 &int.to_string(),
317 variant,
318 )
319 .ok()?,
320 ),
321 CoreValue::TypedDecimal(decimal) => Some(
322 TypedDecimal::from_string_and_variant_in_range(
323 &decimal.to_string(),
324 variant,
325 )
326 .ok()?,
327 ),
328 CoreValue::Integer(int) => Some(
329 TypedDecimal::from_string_and_variant_in_range(
330 &int.to_string(),
331 variant,
332 )
333 .ok()?,
334 ),
335 CoreValue::Decimal(decimal) => Some(
336 TypedDecimal::from_string_and_variant_in_range(
337 &decimal.to_string(),
338 variant,
339 )
340 .ok()?,
341 ),
342 _ => None,
343 }
344 }
345
346 pub fn _cast_to_integer_internal(&self) -> Option<TypedInteger> {
348 match self {
349 CoreValue::Text(text) => Integer::from_string(&text.to_string())
350 .map(|x| Some(x.to_smallest_fitting()))
351 .unwrap_or(None),
352 CoreValue::TypedInteger(int) => {
353 Some(int.to_smallest_fitting().clone())
354 }
355 CoreValue::Integer(int) => {
356 Some(TypedInteger::IBig(int.clone()).to_smallest_fitting())
357 }
358 CoreValue::Decimal(decimal) => Some(
359 TypedInteger::from(decimal.into_f64() as i128)
360 .to_smallest_fitting(),
361 ),
362 CoreValue::TypedDecimal(decimal) => Some(
363 TypedInteger::from(decimal.as_f64() as i64)
364 .to_smallest_fitting(),
365 ),
366 _ => None,
367 }
368 }
369
370 pub fn cast_to_integer(&self) -> Option<Integer> {
372 match self {
373 CoreValue::Text(text) => {
374 Integer::from_string(&text.to_string()).ok()
375 }
376 CoreValue::TypedInteger(int) => Some(int.as_integer()),
377 CoreValue::Integer(int) => Some(int.clone()),
378 CoreValue::Decimal(decimal) => {
379 Some(Integer::from(decimal.into_f64() as i128))
382 }
383 CoreValue::TypedDecimal(decimal) => {
384 decimal.as_integer().map(Integer::from)
385 }
386 _ => None,
387 }
388 }
389
390 pub fn cast_to_typed_integer(
391 &self,
392 variant: IntegerTypeVariant,
393 ) -> Option<TypedInteger> {
394 match self {
395 CoreValue::Text(text) => {
396 TypedInteger::from_string_with_variant(text.as_str(), variant)
397 .ok()
398 }
399 CoreValue::TypedInteger(int) => {
400 TypedInteger::from_string_with_variant(
401 &int.to_string(),
402 variant,
403 )
404 .ok()
405 }
406 CoreValue::Integer(int) => TypedInteger::from_string_with_variant(
407 int.to_string().as_str(),
408 variant,
409 )
410 .ok(),
411 CoreValue::Decimal(decimal) => {
412 Some(TypedInteger::from(decimal.into_f64() as i128))
413 }
414 CoreValue::TypedDecimal(decimal) => {
415 decimal.as_integer().map(TypedInteger::from)
416 }
417 _ => None,
418 }
419 }
420
421 pub fn cast_to_endpoint(&self) -> Option<Endpoint> {
422 match self {
423 CoreValue::Text(text) => Endpoint::try_from(text.as_str()).ok(),
424 CoreValue::Endpoint(endpoint) => Some(endpoint.clone()),
425 _ => None,
426 }
427 }
428
429 pub fn cast_to_list(&self) -> Option<List> {
430 match self {
431 CoreValue::List(list) => Some(list.clone()),
432 _ => None,
433 }
434 }
435
436 pub fn cast_to_map(&self) -> Option<Map> {
437 match self {
438 CoreValue::Map(map) => Some(map.clone()),
439 _ => None,
440 }
441 }
442}
443
444impl Add for CoreValue {
445 type Output = Result<CoreValue, ValueError>;
446 fn add(self, rhs: CoreValue) -> Self::Output {
447 match (&self, &rhs) {
448 (CoreValue::Text(text), other) => {
450 let other = other.cast_to_text();
451 return Ok(CoreValue::Text(text + other));
452 }
453 (other, CoreValue::Text(text)) => {
454 let other = other.cast_to_text();
455 return Ok(CoreValue::Text(other + text));
456 }
457
458 (CoreValue::TypedInteger(lhs), CoreValue::TypedInteger(rhs)) => {
460 return Ok(CoreValue::TypedInteger(
461 (lhs + rhs).ok_or(ValueError::IntegerOverflow)?,
462 ));
463 }
464 (CoreValue::Integer(lhs), CoreValue::Integer(rhs)) => {
465 return Ok(CoreValue::Integer(lhs + rhs));
466 }
467 (CoreValue::TypedDecimal(lhs), CoreValue::TypedDecimal(rhs)) => {
468 return Ok(CoreValue::TypedDecimal(lhs + rhs));
469 }
470 (CoreValue::Decimal(lhs), CoreValue::Decimal(rhs)) => {
471 return Ok(CoreValue::Decimal(lhs + rhs));
472 }
473
474 _ => {}
475 }
476
477 match &self {
479 CoreValue::Integer(lhs) => match &rhs {
481 CoreValue::TypedInteger(rhs) => {
482 Ok(CoreValue::Integer(lhs.clone() + rhs.as_integer()))
483 }
484 CoreValue::Decimal(_) => {
485 let integer = rhs
486 ._cast_to_integer_internal()
487 .ok_or(ValueError::InvalidOperation)?;
488 Ok(CoreValue::Integer(lhs.clone() + integer.as_integer()))
489 }
490 CoreValue::TypedDecimal(rhs) => {
491 let decimal = rhs.as_f64();
492 let integer = TypedInteger::from(decimal as i128);
493 Ok(CoreValue::Integer(lhs.clone() + integer.as_integer()))
494 }
495 _ => Err(ValueError::InvalidOperation),
496 },
497
498 CoreValue::TypedInteger(lhs) => match &rhs {
500 CoreValue::Integer(rhs) => {
501 core::todo!(
502 "#317 TypedInteger + Integer not implemented yet"
503 );
504 }
506 CoreValue::Decimal(_) => {
507 let integer = rhs
508 ._cast_to_integer_internal()
509 .ok_or(ValueError::InvalidOperation)?;
510 Ok(CoreValue::TypedInteger(
511 (lhs + &integer).ok_or(ValueError::IntegerOverflow)?,
512 ))
513 }
514 CoreValue::TypedDecimal(rhs) => {
515 let decimal = rhs.as_f64();
516 let integer = TypedInteger::from(decimal as i128);
517 Ok(CoreValue::TypedInteger(
518 (lhs + &integer).ok_or(ValueError::IntegerOverflow)?,
519 ))
520 }
521 _ => Err(ValueError::InvalidOperation),
522 },
523
524 CoreValue::Decimal(lhs) => match rhs {
526 CoreValue::TypedDecimal(rhs) => {
527 Ok(CoreValue::Decimal(lhs + &Decimal::from(rhs)))
528 }
529 CoreValue::TypedInteger(rhs) => {
530 let decimal = Decimal::from(
531 rhs.as_i128().ok_or(ValueError::IntegerOverflow)?
532 as f64,
533 );
534 Ok(CoreValue::Decimal(lhs + &decimal))
535 }
536 CoreValue::Integer(rhs) => {
537 let decimal = Decimal::from(
538 rhs.as_i128().ok_or(ValueError::IntegerOverflow)?
539 as f64,
540 );
541 Ok(CoreValue::Decimal(lhs + &decimal))
542 }
543 _ => Err(ValueError::InvalidOperation),
544 },
545
546 CoreValue::TypedDecimal(lhs) => match rhs {
548 CoreValue::Decimal(rhs) => Ok(CoreValue::TypedDecimal(
549 lhs + &TypedDecimal::Decimal(rhs),
550 )),
551 CoreValue::TypedInteger(rhs) => {
552 let decimal = TypedDecimal::from(
553 rhs.as_i128().ok_or(ValueError::IntegerOverflow)?
554 as f64,
555 );
556 Ok(CoreValue::TypedDecimal(lhs + &decimal))
557 }
558 CoreValue::Integer(rhs) => {
559 let decimal = TypedDecimal::from(
560 rhs.as_i128().ok_or(ValueError::IntegerOverflow)?
561 as f64,
562 );
563 Ok(CoreValue::TypedDecimal(lhs + &decimal))
564 }
565 _ => Err(ValueError::InvalidOperation),
566 },
567
568 _ => Err(ValueError::InvalidOperation),
569 }
570 }
571}
572
573impl Add for &CoreValue {
574 type Output = Result<CoreValue, ValueError>;
575 fn add(self, rhs: &CoreValue) -> Self::Output {
576 CoreValue::add(self.clone(), rhs.clone())
577 }
578}
579
580impl Sub for CoreValue {
581 type Output = Result<CoreValue, ValueError>;
582 fn sub(self, rhs: CoreValue) -> Self::Output {
583 match (&self, &rhs) {
585 (CoreValue::TypedInteger(lhs), CoreValue::TypedInteger(rhs)) => {
586 return Ok(CoreValue::TypedInteger(
587 (lhs - rhs).ok_or(ValueError::IntegerOverflow)?,
588 ));
589 }
590 (CoreValue::Integer(lhs), CoreValue::Integer(rhs)) => {
591 return Ok(CoreValue::Integer(lhs - rhs));
592 }
593 (CoreValue::TypedDecimal(lhs), CoreValue::TypedDecimal(rhs)) => {
594 return Ok(CoreValue::TypedDecimal(lhs - rhs));
595 }
596 (CoreValue::Decimal(lhs), CoreValue::Decimal(rhs)) => {
597 return Ok(CoreValue::Decimal(lhs - rhs));
598 }
599
600 _ => {}
601 }
602
603 match &self {
605 CoreValue::Integer(lhs) => match &rhs {
607 CoreValue::TypedInteger(rhs) => {
608 Ok(CoreValue::Integer(lhs - &rhs.as_integer()))
609 }
610 CoreValue::Decimal(_) => {
611 let integer = rhs
612 ._cast_to_integer_internal()
613 .ok_or(ValueError::InvalidOperation)?;
614 Ok(CoreValue::Integer(lhs - &integer.as_integer()))
615 }
616 CoreValue::TypedDecimal(rhs) => {
617 let decimal = rhs.as_f64();
618 let integer = TypedInteger::from(decimal as i128);
619 Ok(CoreValue::Integer(lhs - &integer.as_integer()))
620 }
621 _ => Err(ValueError::InvalidOperation),
622 },
623
624 CoreValue::TypedInteger(lhs) => match &rhs {
626 CoreValue::Integer(rhs) => {
627 core::todo!(
628 "#318 TypedInteger - Integer not implemented yet"
629 );
630 }
632 CoreValue::Decimal(_) => {
636 let integer = rhs
637 ._cast_to_integer_internal()
638 .ok_or(ValueError::InvalidOperation)?;
639 Ok(CoreValue::TypedInteger(
640 (lhs - &integer).ok_or(ValueError::IntegerOverflow)?,
641 ))
642 }
643 CoreValue::TypedDecimal(rhs) => {
644 let decimal = rhs.as_f64();
645 let integer = TypedInteger::from(decimal as i128);
646 Ok(CoreValue::TypedInteger(
647 (lhs - &integer).ok_or(ValueError::IntegerOverflow)?,
648 ))
649 }
650 _ => Err(ValueError::InvalidOperation),
651 },
652
653 CoreValue::Decimal(lhs) => match rhs {
655 CoreValue::TypedDecimal(rhs) => {
656 Ok(CoreValue::Decimal(lhs - &Decimal::from(rhs)))
657 }
658 CoreValue::TypedInteger(rhs) => {
659 let decimal = Decimal::from(
660 rhs.as_i128().ok_or(ValueError::IntegerOverflow)?
661 as f64,
662 );
663 Ok(CoreValue::Decimal(lhs - &decimal))
664 }
665 CoreValue::Integer(rhs) => {
666 let decimal = Decimal::from(
667 rhs.as_i128().ok_or(ValueError::IntegerOverflow)?
668 as f64,
669 );
670 Ok(CoreValue::Decimal(lhs - &decimal))
671 }
672 _ => Err(ValueError::InvalidOperation),
673 },
674
675 CoreValue::TypedDecimal(lhs) => match rhs {
677 CoreValue::Decimal(rhs) => Ok(CoreValue::TypedDecimal(
678 lhs - &TypedDecimal::Decimal(rhs),
679 )),
680 CoreValue::TypedInteger(rhs) => {
681 let decimal = TypedDecimal::from(
682 rhs.as_i128().ok_or(ValueError::IntegerOverflow)?
683 as f64,
684 );
685 Ok(CoreValue::TypedDecimal(lhs - &decimal))
686 }
687 CoreValue::Integer(rhs) => {
688 let decimal = TypedDecimal::from(
689 rhs.as_i128().ok_or(ValueError::IntegerOverflow)?
690 as f64,
691 );
692 Ok(CoreValue::TypedDecimal(lhs - &decimal))
693 }
694 _ => Err(ValueError::InvalidOperation),
695 },
696 _ => Err(ValueError::InvalidOperation),
697 }
698 }
699}
700
701impl Sub for &CoreValue {
702 type Output = Result<CoreValue, ValueError>;
703 fn sub(self, rhs: &CoreValue) -> Self::Output {
704 CoreValue::sub(self.clone(), rhs.clone())
705 }
706}
707
708impl AddAssign<CoreValue> for CoreValue {
709 fn add_assign(&mut self, rhs: CoreValue) {
710 let res = self.clone() + rhs;
711 if let Ok(value) = res {
712 *self = value;
713 } else {
714 core::panic!("Failed to add value: {res:?}");
715 }
716 }
717}
718
719impl Not for CoreValue {
720 type Output = Option<CoreValue>;
721
722 fn not(self) -> Self::Output {
723 match self {
724 CoreValue::Boolean(bool) => Some(CoreValue::Boolean(!bool)),
725 _ => None, }
727 }
728}
729
730impl Neg for CoreValue {
731 type Output = Result<CoreValue, ValueError>;
732
733 fn neg(self) -> Self::Output {
734 match self {
735 CoreValue::TypedInteger(int) => {
736 Ok(CoreValue::TypedInteger(int.neg()?))
737 }
738 CoreValue::Integer(int) => Ok(CoreValue::Integer(int.neg())),
739 CoreValue::TypedDecimal(decimal) => {
740 Ok(CoreValue::TypedDecimal(decimal.neg()))
741 }
742 CoreValue::Decimal(decimal) => {
743 Ok(CoreValue::Decimal(decimal.neg()))
744 }
745 _ => Err(ValueError::InvalidOperation), }
747 }
748}
749
750impl Display for CoreValue {
751 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
752 match self {
753 CoreValue::Type(ty) => core::write!(f, "{ty}"),
754 CoreValue::Boolean(bool) => core::write!(f, "{bool}"),
755 CoreValue::TypedInteger(int) => core::write!(f, "{int}"),
756 CoreValue::TypedDecimal(decimal) => core::write!(f, "{decimal}"),
757 CoreValue::Text(text) => core::write!(f, "{text}"),
758 CoreValue::Null => core::write!(f, "null"),
759 CoreValue::Endpoint(endpoint) => core::write!(f, "{endpoint}"),
760 CoreValue::Map(map) => core::write!(f, "{map}"),
761 CoreValue::Integer(integer) => core::write!(f, "{integer}"),
762 CoreValue::Decimal(decimal) => core::write!(f, "{decimal}"),
763 CoreValue::List(list) => core::write!(f, "{list}"),
764 CoreValue::Callable(callable) => core::write!(f, "[[ callable ]]"), }
766 }
767}
768
769#[cfg(test)]
770mod tests {
774 use log::{debug, info};
775
776 use crate::logger::init_logger_debug;
777
778 use super::*;
779
780 #[test]
781 fn type_construct() {
782 init_logger_debug();
783 let a = CoreValue::from(42i32);
784 assert_eq!(a.default_type_definition().to_string(), "integer/i32");
785 }
786
787 #[test]
788 fn addition() {
789 init_logger_debug();
790 let a = CoreValue::from(42i32);
791 let b = CoreValue::from(11i32);
792 let c = CoreValue::from("11");
793
794 let a_plus_b = (a.clone() + b.clone()).unwrap();
795 assert_eq!(a_plus_b.clone(), CoreValue::from(53));
796 info!("{} + {} = {}", a.clone(), b.clone(), a_plus_b.clone());
797 }
798
799 #[test]
800 fn endpoint() {
801 let endpoint: Endpoint = CoreValue::from("@test").try_into().unwrap();
802 debug!("Endpoint: {endpoint}");
803 assert_eq!(endpoint.to_string(), "@test");
804 }
805}