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