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