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