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