1use std::{
14 cmp::Ordering,
15 fmt::{Display, Formatter},
16};
17
18use num_traits::ToPrimitive;
19use serde::{Deserialize, Serialize};
20pub mod as_string;
21pub mod blob;
22pub mod boolean;
23pub mod constraint;
24pub mod container;
25pub mod date;
26pub mod datetime;
27pub mod decimal;
28pub mod dictionary;
29pub mod duration;
30pub mod frame;
31pub mod identity;
32pub mod int;
33pub mod into;
34pub mod is;
35pub mod iso;
36pub mod json;
37pub mod number;
38pub mod ordered_f32;
39pub mod ordered_f64;
40pub mod partition;
41pub mod row_number;
42pub mod sumtype;
43pub mod temporal;
44pub mod time;
45pub mod to_value;
46pub mod try_from;
47pub mod uint;
48pub mod uuid;
49pub mod value_type;
50
51use std::{fmt, hash, mem};
52
53use blob::Blob;
54use date::Date;
55use datetime::DateTime;
56use decimal::Decimal;
57use dictionary::DictionaryEntryId;
58use duration::Duration;
59use identity::IdentityId;
60use int::Int;
61use ordered_f32::OrderedF32;
62use ordered_f64::OrderedF64;
63use time::Time;
64use uint::Uint;
65use uuid::{Uuid4, Uuid7};
66use value_type::ValueType;
67
68#[derive(Clone, Debug, Serialize, Deserialize)]
69pub enum Value {
70 None {
71 inner: ValueType,
72 },
73
74 Boolean(bool),
75
76 Float4(OrderedF32),
77
78 Float8(OrderedF64),
79
80 Int1(i8),
81
82 Int2(i16),
83
84 Int4(i32),
85
86 Int8(i64),
87
88 Int16(i128),
89
90 Utf8(String),
91
92 Uint1(u8),
93
94 Uint2(u16),
95
96 Uint4(u32),
97
98 Uint8(u64),
99
100 Uint16(u128),
101
102 Date(Date),
103
104 DateTime(DateTime),
105
106 Time(Time),
107
108 Duration(Duration),
109
110 IdentityId(IdentityId),
111
112 Uuid4(Uuid4),
113
114 Uuid7(Uuid7),
115
116 Blob(Blob),
117
118 Int(Int),
119
120 Uint(Uint),
121
122 Decimal(Decimal),
123
124 Any(Box<Value>),
125
126 DictionaryId(DictionaryEntryId),
127
128 Type(ValueType),
129
130 List(Vec<Value>),
131
132 Record(Vec<(String, Value)>),
133
134 Tuple(Vec<Value>),
135}
136
137impl Value {
138 pub fn none() -> Self {
139 Value::None {
140 inner: ValueType::Any,
141 }
142 }
143
144 pub fn none_of(ty: ValueType) -> Self {
145 Value::None {
146 inner: ty,
147 }
148 }
149
150 pub fn bool(v: impl Into<bool>) -> Self {
151 Value::Boolean(v.into())
152 }
153
154 pub fn float4(v: impl Into<f32>) -> Self {
155 OrderedF32::try_from(v.into()).map(Value::Float4).unwrap_or(Value::None {
156 inner: ValueType::Float4,
157 })
158 }
159
160 pub fn float8(v: impl Into<f64>) -> Self {
161 OrderedF64::try_from(v.into()).map(Value::Float8).unwrap_or(Value::None {
162 inner: ValueType::Float8,
163 })
164 }
165
166 pub fn int1(v: impl Into<i8>) -> Self {
167 Value::Int1(v.into())
168 }
169
170 pub fn int2(v: impl Into<i16>) -> Self {
171 Value::Int2(v.into())
172 }
173
174 pub fn int4(v: impl Into<i32>) -> Self {
175 Value::Int4(v.into())
176 }
177
178 pub fn int8(v: impl Into<i64>) -> Self {
179 Value::Int8(v.into())
180 }
181
182 pub fn int16(v: impl Into<i128>) -> Self {
183 Value::Int16(v.into())
184 }
185
186 pub fn utf8(v: impl Into<String>) -> Self {
187 Value::Utf8(v.into())
188 }
189
190 pub fn uint1(v: impl Into<u8>) -> Self {
191 Value::Uint1(v.into())
192 }
193
194 pub fn uint2(v: impl Into<u16>) -> Self {
195 Value::Uint2(v.into())
196 }
197
198 pub fn uint4(v: impl Into<u32>) -> Self {
199 Value::Uint4(v.into())
200 }
201
202 pub fn uint8(v: impl Into<u64>) -> Self {
203 Value::Uint8(v.into())
204 }
205
206 pub fn uint16(v: impl Into<u128>) -> Self {
207 Value::Uint16(v.into())
208 }
209
210 pub fn date(v: impl Into<Date>) -> Self {
211 Value::Date(v.into())
212 }
213
214 pub fn datetime(v: impl Into<DateTime>) -> Self {
215 Value::DateTime(v.into())
216 }
217
218 pub fn time(v: impl Into<Time>) -> Self {
219 Value::Time(v.into())
220 }
221
222 pub fn duration(v: impl Into<Duration>) -> Self {
223 Value::Duration(v.into())
224 }
225
226 pub fn duration_nanoseconds(nanoseconds: i64) -> Self {
227 Value::Duration(Duration::from_nanoseconds_const(nanoseconds))
228 }
229
230 pub fn duration_microseconds(microseconds: i64) -> Self {
231 Value::Duration(Duration::from_microseconds_const(microseconds))
232 }
233
234 pub fn duration_milliseconds(milliseconds: i64) -> Self {
235 Value::Duration(Duration::from_milliseconds_const(milliseconds))
236 }
237
238 pub fn duration_seconds(seconds: i64) -> Self {
239 Value::Duration(Duration::from_seconds_const(seconds))
240 }
241
242 pub fn duration_minutes(minutes: i64) -> Self {
243 Value::Duration(Duration::from_minutes_const(minutes))
244 }
245
246 pub fn duration_hours(hours: i64) -> Self {
247 Value::Duration(Duration::from_hours_const(hours))
248 }
249
250 pub fn identity_id(v: impl Into<IdentityId>) -> Self {
251 Value::IdentityId(v.into())
252 }
253
254 pub fn uuid4(v: impl Into<Uuid4>) -> Self {
255 Value::Uuid4(v.into())
256 }
257
258 pub fn uuid7(v: impl Into<Uuid7>) -> Self {
259 Value::Uuid7(v.into())
260 }
261
262 pub fn blob(v: impl Into<Blob>) -> Self {
263 Value::Blob(v.into())
264 }
265
266 pub fn any(v: impl Into<Value>) -> Self {
267 Value::Any(Box::new(v.into()))
268 }
269
270 pub fn list(items: Vec<Value>) -> Self {
271 Value::List(items)
272 }
273
274 pub fn record(fields: Vec<(String, Value)>) -> Self {
275 Value::Record(fields)
276 }
277
278 pub fn to_usize(&self) -> Option<usize> {
279 match self {
280 Value::Uint1(v) => Some(*v as usize),
281 Value::Uint2(v) => Some(*v as usize),
282 Value::Uint4(v) => Some(*v as usize),
283 Value::Uint8(v) => usize::try_from(*v).ok(),
284 Value::Uint16(v) => usize::try_from(*v).ok(),
285 Value::Int1(v) => usize::try_from(*v).ok(),
286 Value::Int2(v) => usize::try_from(*v).ok(),
287 Value::Int4(v) => usize::try_from(*v).ok(),
288 Value::Int8(v) => usize::try_from(*v).ok(),
289 Value::Int16(v) => usize::try_from(*v).ok(),
290 Value::Float4(v) => {
291 let f = v.value();
292 if f >= 0.0 {
293 Some(f as usize)
294 } else {
295 None
296 }
297 }
298 Value::Float8(v) => {
299 let f = v.value();
300 if f >= 0.0 {
301 Some(f as usize)
302 } else {
303 None
304 }
305 }
306 Value::Int(v) => v.0.to_u64().and_then(|n| usize::try_from(n).ok()),
307 Value::Uint(v) => v.0.to_u64().and_then(|n| usize::try_from(n).ok()),
308 Value::Decimal(v) => v.0.to_u64().and_then(|n| usize::try_from(n).ok()),
309 Value::Utf8(s) => {
310 let s = s.trim();
311 if let Ok(n) = s.parse::<u64>() {
312 usize::try_from(n).ok()
313 } else if let Ok(f) = s.parse::<f64>() {
314 if f >= 0.0 {
315 Some(f as usize)
316 } else {
317 None
318 }
319 } else {
320 None
321 }
322 }
323 _ => None,
324 }
325 }
326}
327
328impl PartialEq for Value {
329 fn eq(&self, other: &Self) -> bool {
330 match (self, other) {
331 (
332 Value::None {
333 inner: l,
334 },
335 Value::None {
336 inner: r,
337 },
338 ) => l == r,
339 (Value::Boolean(l), Value::Boolean(r)) => l == r,
340 (Value::Float4(l), Value::Float4(r)) => l == r,
341 (Value::Float8(l), Value::Float8(r)) => l == r,
342 (Value::Int1(l), Value::Int1(r)) => l == r,
343 (Value::Int2(l), Value::Int2(r)) => l == r,
344 (Value::Int4(l), Value::Int4(r)) => l == r,
345 (Value::Int8(l), Value::Int8(r)) => l == r,
346 (Value::Int16(l), Value::Int16(r)) => l == r,
347 (Value::Utf8(l), Value::Utf8(r)) => l == r,
348 (Value::Uint1(l), Value::Uint1(r)) => l == r,
349 (Value::Uint2(l), Value::Uint2(r)) => l == r,
350 (Value::Uint4(l), Value::Uint4(r)) => l == r,
351 (Value::Uint8(l), Value::Uint8(r)) => l == r,
352 (Value::Uint16(l), Value::Uint16(r)) => l == r,
353 (Value::Date(l), Value::Date(r)) => l == r,
354 (Value::DateTime(l), Value::DateTime(r)) => l == r,
355 (Value::Time(l), Value::Time(r)) => l == r,
356 (Value::Duration(l), Value::Duration(r)) => l == r,
357 (Value::IdentityId(l), Value::IdentityId(r)) => l == r,
358 (Value::Uuid4(l), Value::Uuid4(r)) => l == r,
359 (Value::Uuid7(l), Value::Uuid7(r)) => l == r,
360 (Value::Blob(l), Value::Blob(r)) => l == r,
361 (Value::Int(l), Value::Int(r)) => l == r,
362 (Value::Uint(l), Value::Uint(r)) => l == r,
363 (Value::Decimal(l), Value::Decimal(r)) => l == r,
364 (Value::Any(l), Value::Any(r)) => l == r,
365 (Value::DictionaryId(l), Value::DictionaryId(r)) => l == r,
366 (Value::Type(l), Value::Type(r)) => l == r,
367 (Value::List(l), Value::List(r)) => l == r,
368 (Value::Record(l), Value::Record(r)) => l == r,
369 (Value::Tuple(l), Value::Tuple(r)) => l == r,
370 _ => false,
371 }
372 }
373}
374
375impl Eq for Value {}
376
377#[cfg(reifydb_assertions)]
378pub fn assert_equal_with_tolerance(left: &[Value], right: &[Value]) {
379 const REL_EPS: f64 = 1e-9;
380 const ABS_EPS: f64 = 1e-6;
381 fn close(x: f64, y: f64) -> bool {
382 if x.is_nan() && y.is_nan() {
383 return true;
384 }
385 (x - y).abs() <= ABS_EPS.max(REL_EPS * x.abs().max(y.abs()))
386 }
387 fn matches(a: &Value, b: &Value) -> bool {
388 match (a, b) {
389 (Value::Float8(x), Value::Float8(y)) => close(x.value(), y.value()),
390 (Value::Float4(x), Value::Float4(y)) => close(x.value() as f64, y.value() as f64),
391 _ => a == b,
392 }
393 }
394 assert_eq!(left.len(), right.len(), "value count diverges beyond tolerance: {} vs {}", left.len(), right.len());
395 for (i, (l, r)) in left.iter().zip(right).enumerate() {
396 assert!(matches(l, r), "value {i} diverges beyond tolerance: {l:?} vs {r:?}");
397 }
398}
399
400impl hash::Hash for Value {
401 fn hash<H: hash::Hasher>(&self, state: &mut H) {
402 mem::discriminant(self).hash(state);
403 match self {
404 Value::None {
405 ..
406 } => {}
407 Value::Boolean(v) => v.hash(state),
408 Value::Float4(v) => v.hash(state),
409 Value::Float8(v) => v.hash(state),
410 Value::Int1(v) => v.hash(state),
411 Value::Int2(v) => v.hash(state),
412 Value::Int4(v) => v.hash(state),
413 Value::Int8(v) => v.hash(state),
414 Value::Int16(v) => v.hash(state),
415 Value::Utf8(v) => v.hash(state),
416 Value::Uint1(v) => v.hash(state),
417 Value::Uint2(v) => v.hash(state),
418 Value::Uint4(v) => v.hash(state),
419 Value::Uint8(v) => v.hash(state),
420 Value::Uint16(v) => v.hash(state),
421 Value::Date(v) => v.hash(state),
422 Value::DateTime(v) => v.hash(state),
423 Value::Time(v) => v.hash(state),
424 Value::Duration(v) => v.hash(state),
425 Value::IdentityId(v) => v.hash(state),
426 Value::Uuid4(v) => v.hash(state),
427 Value::Uuid7(v) => v.hash(state),
428 Value::Blob(v) => v.hash(state),
429 Value::Int(v) => v.hash(state),
430 Value::Uint(v) => v.hash(state),
431 Value::Decimal(v) => v.hash(state),
432 Value::Any(v) => v.hash(state),
433 Value::DictionaryId(v) => v.hash(state),
434 Value::Type(v) => v.hash(state),
435 Value::List(v) => v.hash(state),
436 Value::Record(fields) => {
437 for (k, v) in fields {
438 k.hash(state);
439 v.hash(state);
440 }
441 }
442 Value::Tuple(v) => v.hash(state),
443 }
444 }
445}
446
447impl PartialOrd for Value {
448 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
449 Some(self.cmp(other))
450 }
451}
452
453impl Ord for Value {
454 fn cmp(&self, other: &Self) -> Ordering {
455 match (self, other) {
456 (
457 Value::None {
458 ..
459 },
460 Value::None {
461 ..
462 },
463 ) => Ordering::Equal,
464 (
465 Value::None {
466 ..
467 },
468 _,
469 ) => Ordering::Greater,
470 (
471 _,
472 Value::None {
473 ..
474 },
475 ) => Ordering::Less,
476 (Value::Boolean(l), Value::Boolean(r)) => l.cmp(r),
477 (Value::Float4(l), Value::Float4(r)) => l.cmp(r),
478 (Value::Float8(l), Value::Float8(r)) => l.cmp(r),
479 (Value::Int1(l), Value::Int1(r)) => l.cmp(r),
480 (Value::Int2(l), Value::Int2(r)) => l.cmp(r),
481 (Value::Int4(l), Value::Int4(r)) => l.cmp(r),
482 (Value::Int8(l), Value::Int8(r)) => l.cmp(r),
483 (Value::Int16(l), Value::Int16(r)) => l.cmp(r),
484 (Value::Utf8(l), Value::Utf8(r)) => l.cmp(r),
485 (Value::Uint1(l), Value::Uint1(r)) => l.cmp(r),
486 (Value::Uint2(l), Value::Uint2(r)) => l.cmp(r),
487 (Value::Uint4(l), Value::Uint4(r)) => l.cmp(r),
488 (Value::Uint8(l), Value::Uint8(r)) => l.cmp(r),
489 (Value::Uint16(l), Value::Uint16(r)) => l.cmp(r),
490 (Value::Date(l), Value::Date(r)) => l.cmp(r),
491 (Value::DateTime(l), Value::DateTime(r)) => l.cmp(r),
492 (Value::Time(l), Value::Time(r)) => l.cmp(r),
493 (Value::Duration(l), Value::Duration(r)) => l.cmp(r),
494 (Value::IdentityId(l), Value::IdentityId(r)) => l.cmp(r),
495 (Value::Uuid4(l), Value::Uuid4(r)) => l.cmp(r),
496 (Value::Uuid7(l), Value::Uuid7(r)) => l.cmp(r),
497 (Value::Blob(l), Value::Blob(r)) => l.cmp(r),
498 (Value::Int(l), Value::Int(r)) => l.cmp(r),
499 (Value::Uint(l), Value::Uint(r)) => l.cmp(r),
500 (Value::Decimal(l), Value::Decimal(r)) => l.cmp(r),
501 (Value::DictionaryId(l), Value::DictionaryId(r)) => l.to_u128().cmp(&r.to_u128()),
502 (Value::Type(l), Value::Type(r)) => l.cmp(r),
503 (Value::List(_), Value::List(_)) => unreachable!("List values are not orderable"),
504 (Value::Record(_), Value::Record(_)) => unreachable!("Record values are not orderable"),
505 (Value::Tuple(_), Value::Tuple(_)) => unreachable!("Tuple values are not orderable"),
506 (Value::Any(_), Value::Any(_)) => unreachable!("Any values are not orderable"),
507 _ => unimplemented!(),
508 }
509 }
510}
511
512impl Display for Value {
513 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
514 match self {
515 Value::Boolean(true) => f.write_str("true"),
516 Value::Boolean(false) => f.write_str("false"),
517 Value::Float4(value) => Display::fmt(value, f),
518 Value::Float8(value) => Display::fmt(value, f),
519 Value::Int1(value) => Display::fmt(value, f),
520 Value::Int2(value) => Display::fmt(value, f),
521 Value::Int4(value) => Display::fmt(value, f),
522 Value::Int8(value) => Display::fmt(value, f),
523 Value::Int16(value) => Display::fmt(value, f),
524 Value::Utf8(value) => Display::fmt(value, f),
525 Value::Uint1(value) => Display::fmt(value, f),
526 Value::Uint2(value) => Display::fmt(value, f),
527 Value::Uint4(value) => Display::fmt(value, f),
528 Value::Uint8(value) => Display::fmt(value, f),
529 Value::Uint16(value) => Display::fmt(value, f),
530 Value::Date(value) => Display::fmt(value, f),
531 Value::DateTime(value) => Display::fmt(value, f),
532 Value::Time(value) => Display::fmt(value, f),
533 Value::Duration(value) => Display::fmt(value, f),
534 Value::IdentityId(value) => Display::fmt(value, f),
535 Value::Uuid4(value) => Display::fmt(value, f),
536 Value::Uuid7(value) => Display::fmt(value, f),
537 Value::Blob(value) => Display::fmt(value, f),
538 Value::Int(value) => Display::fmt(value, f),
539 Value::Uint(value) => Display::fmt(value, f),
540 Value::Decimal(value) => Display::fmt(value, f),
541 Value::Any(value) => Display::fmt(value, f),
542 Value::DictionaryId(value) => Display::fmt(value, f),
543 Value::Type(value) => Display::fmt(value, f),
544 Value::List(items) => {
545 f.write_str("[")?;
546 for (i, item) in items.iter().enumerate() {
547 if i > 0 {
548 f.write_str(", ")?;
549 }
550 Display::fmt(item, f)?;
551 }
552 f.write_str("]")
553 }
554 Value::Record(fields) => {
555 f.write_str("{")?;
556 for (i, (key, value)) in fields.iter().enumerate() {
557 if i > 0 {
558 f.write_str(", ")?;
559 }
560 write!(f, "{}: {}", key, value)?;
561 }
562 f.write_str("}")
563 }
564 Value::Tuple(items) => {
565 f.write_str("(")?;
566 for (i, item) in items.iter().enumerate() {
567 if i > 0 {
568 f.write_str(", ")?;
569 }
570 Display::fmt(item, f)?;
571 }
572 f.write_str(")")
573 }
574 Value::None {
575 ..
576 } => f.write_str("none"),
577 }
578 }
579}
580
581impl Value {
582 pub fn get_type(&self) -> ValueType {
583 match self {
584 Value::None {
585 inner,
586 } => ValueType::Option(Box::new(inner.clone())),
587 Value::Boolean(_) => ValueType::Boolean,
588 Value::Float4(_) => ValueType::Float4,
589 Value::Float8(_) => ValueType::Float8,
590 Value::Int1(_) => ValueType::Int1,
591 Value::Int2(_) => ValueType::Int2,
592 Value::Int4(_) => ValueType::Int4,
593 Value::Int8(_) => ValueType::Int8,
594 Value::Int16(_) => ValueType::Int16,
595 Value::Utf8(_) => ValueType::Utf8,
596 Value::Uint1(_) => ValueType::Uint1,
597 Value::Uint2(_) => ValueType::Uint2,
598 Value::Uint4(_) => ValueType::Uint4,
599 Value::Uint8(_) => ValueType::Uint8,
600 Value::Uint16(_) => ValueType::Uint16,
601 Value::Date(_) => ValueType::Date,
602 Value::DateTime(_) => ValueType::DateTime,
603 Value::Time(_) => ValueType::Time,
604 Value::Duration(_) => ValueType::Duration,
605 Value::IdentityId(_) => ValueType::IdentityId,
606 Value::Uuid4(_) => ValueType::Uuid4,
607 Value::Uuid7(_) => ValueType::Uuid7,
608 Value::Blob(_) => ValueType::Blob,
609 Value::Int(_) => ValueType::Int,
610 Value::Uint(_) => ValueType::Uint,
611 Value::Decimal(_) => ValueType::Decimal,
612 Value::Any(_) => ValueType::Any,
613 Value::DictionaryId(_) => ValueType::DictionaryId,
614 Value::Type(t) => t.clone(),
615 Value::List(items) => {
616 let element_type = items.first().map(|v| v.get_type()).unwrap_or(ValueType::Any);
617 ValueType::list_of(element_type)
618 }
619 Value::Record(fields) => {
620 ValueType::Record(fields.iter().map(|(k, v)| (k.clone(), v.get_type())).collect())
621 }
622 Value::Tuple(items) => ValueType::Tuple(items.iter().map(|v| v.get_type()).collect()),
623 }
624 }
625}
626
627#[cfg(test)]
628mod tests {
629 use std::str::FromStr;
630
631 use super::*;
632
633 #[test]
636 fn to_usize_uint1() {
637 assert_eq!(Value::uint1(42u8).to_usize(), Some(42));
638 }
639
640 #[test]
641 fn to_usize_uint2() {
642 assert_eq!(Value::uint2(1000u16).to_usize(), Some(1000));
643 }
644
645 #[test]
646 fn to_usize_uint4() {
647 assert_eq!(Value::uint4(100_000u32).to_usize(), Some(100_000));
648 }
649
650 #[test]
651 fn to_usize_uint8() {
652 assert_eq!(Value::uint8(1_000_000u64).to_usize(), Some(1_000_000));
653 }
654
655 #[test]
656 fn to_usize_uint16() {
657 assert_eq!(Value::Uint16(500u128).to_usize(), Some(500));
658 }
659
660 #[test]
661 fn to_usize_int1() {
662 assert_eq!(Value::int1(100i8).to_usize(), Some(100));
663 }
664
665 #[test]
666 fn to_usize_int2() {
667 assert_eq!(Value::int2(5000i16).to_usize(), Some(5000));
668 }
669
670 #[test]
671 fn to_usize_int4() {
672 assert_eq!(Value::int4(50_000i32).to_usize(), Some(50_000));
673 }
674
675 #[test]
676 fn to_usize_int8() {
677 assert_eq!(Value::int8(1_000_000i64).to_usize(), Some(1_000_000));
678 }
679
680 #[test]
681 fn to_usize_int16() {
682 assert_eq!(Value::Int16(999i128).to_usize(), Some(999));
683 }
684
685 #[test]
686 fn to_usize_float4() {
687 assert_eq!(Value::float4(42.0f32).to_usize(), Some(42));
688 }
689
690 #[test]
691 fn to_usize_float8() {
692 assert_eq!(Value::float8(42.0f64).to_usize(), Some(42));
693 }
694
695 #[test]
696 fn to_usize_int_bigint() {
697 assert_eq!(Value::Int(Int::from_i64(42)).to_usize(), Some(42));
698 }
699
700 #[test]
701 fn to_usize_uint_bigint() {
702 assert_eq!(Value::Uint(Uint::from_u64(42)).to_usize(), Some(42));
703 }
704
705 #[test]
706 fn to_usize_decimal() {
707 assert_eq!(Value::Decimal(Decimal::from_i64(42)).to_usize(), Some(42));
708 }
709
710 #[test]
713 fn to_usize_int1_negative() {
714 assert_eq!(Value::int1(-1i8).to_usize(), None);
715 }
716
717 #[test]
718 fn to_usize_int2_negative() {
719 assert_eq!(Value::int2(-100i16).to_usize(), None);
720 }
721
722 #[test]
723 fn to_usize_int4_negative() {
724 assert_eq!(Value::int4(-1i32).to_usize(), None);
725 }
726
727 #[test]
728 fn to_usize_int8_negative() {
729 assert_eq!(Value::int8(-1i64).to_usize(), None);
730 }
731
732 #[test]
733 fn to_usize_int16_negative() {
734 assert_eq!(Value::Int16(-1i128).to_usize(), None);
735 }
736
737 #[test]
738 fn to_usize_float4_negative() {
739 assert_eq!(Value::float4(-1.0f32).to_usize(), None);
740 }
741
742 #[test]
743 fn to_usize_float8_negative() {
744 assert_eq!(Value::float8(-1.0f64).to_usize(), None);
745 }
746
747 #[test]
748 fn to_usize_int_bigint_negative() {
749 assert_eq!(Value::Int(Int::from_i64(-5)).to_usize(), None);
750 }
751
752 #[test]
755 fn to_usize_zero() {
756 assert_eq!(Value::uint1(0u8).to_usize(), Some(0));
757 }
758
759 #[test]
760 fn to_usize_int1_zero() {
761 assert_eq!(Value::int1(0i8).to_usize(), Some(0));
762 }
763
764 #[test]
765 fn to_usize_float4_zero() {
766 assert_eq!(Value::float4(0.0f32).to_usize(), Some(0));
767 }
768
769 #[test]
772 fn to_usize_boolean_none() {
773 assert_eq!(Value::bool(true).to_usize(), None);
774 }
775
776 #[test]
777 fn to_usize_utf8_integer() {
778 assert_eq!(Value::utf8("42").to_usize(), Some(42));
779 }
780
781 #[test]
782 fn to_usize_utf8_float() {
783 assert_eq!(Value::utf8("3.7").to_usize(), Some(3));
784 }
785
786 #[test]
787 fn to_usize_utf8_negative() {
788 assert_eq!(Value::utf8("-5").to_usize(), None);
789 }
790
791 #[test]
792 fn to_usize_utf8_negative_float() {
793 assert_eq!(Value::utf8("-1.5").to_usize(), None);
794 }
795
796 #[test]
797 fn to_usize_utf8_whitespace() {
798 assert_eq!(Value::utf8(" 42 ").to_usize(), Some(42));
799 }
800
801 #[test]
802 fn to_usize_utf8_zero() {
803 assert_eq!(Value::utf8("0").to_usize(), Some(0));
804 }
805
806 #[test]
807 fn to_usize_utf8_non_numeric() {
808 assert_eq!(Value::utf8("hello").to_usize(), None);
809 }
810
811 #[test]
812 fn to_usize_utf8_empty() {
813 assert_eq!(Value::utf8("").to_usize(), None);
814 }
815
816 #[test]
817 fn to_usize_none_none() {
818 assert_eq!(Value::none().to_usize(), None);
819 }
820
821 #[test]
824 fn to_usize_float8_fractional() {
825 assert_eq!(Value::float8(3.7f64).to_usize(), Some(3));
826 }
827
828 #[test]
829 fn to_usize_decimal_fractional() {
830 assert_eq!(Value::Decimal(Decimal::from_str("3.7").unwrap()).to_usize(), Some(3));
831 }
832
833 #[test]
841 fn test_none_with_same_inner_type_are_equal() {
842 assert_eq!(Value::none_of(ValueType::Duration), Value::none_of(ValueType::Duration));
843 }
844
845 #[test]
846 fn test_none_with_different_inner_type_are_not_equal() {
847 assert_ne!(Value::none_of(ValueType::Duration), Value::none_of(ValueType::Boolean));
848 }
849
850 #[test]
851 fn test_none_with_different_nesting_depth_are_not_equal() {
852 let option_duration = Value::none_of(ValueType::Option(Box::new(ValueType::Duration)));
853 let duration = Value::none_of(ValueType::Duration);
854 assert_ne!(option_duration, duration);
855 }
856
857 #[test]
858 fn test_none_any_is_not_equal_to_none_of_concrete_type() {
859 assert_ne!(Value::none(), Value::none_of(ValueType::Duration));
860 }
861}