1use chrono::{DateTime, NaiveDate, NaiveTime, Utc};
4use rust_decimal::Decimal;
5use std::collections::HashMap;
6
7use crate::error::{Error, Result};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ValueKind {
12 Null,
13 Int,
14 Bool,
15 String,
16 Decimal,
17 Array,
18 Object,
19 Bytea,
20 Date,
21 Time,
22 TimeTz,
23 Timestamp,
24 TimestampTz,
25 Interval,
26 Json,
27 Jsonb,
28 Xml,
29 Url,
30 Domain,
31 Uuid,
32 Enum,
33 BitString,
34 Range,
35}
36
37#[derive(Debug, Clone)]
39pub struct Range {
40 pub lower: Option<Box<Value>>,
41 pub upper: Option<Box<Value>>,
42 pub bounds: String,
43}
44
45#[derive(Debug, Clone)]
47pub struct Value {
48 pub kind: ValueKind,
49 int_value: i64,
50 bool_value: bool,
51 string_value: String,
52 decimal_value: Option<Decimal>,
53 #[allow(dead_code)] decimal_scale: String,
55 array_value: Vec<Value>,
56 object_value: HashMap<String, Value>,
57 bytes_value: Vec<u8>,
58 date_value: Option<NaiveDate>,
59 #[allow(dead_code)] time_value: Option<NaiveTime>,
61 timestamp_value: Option<DateTime<Utc>>,
62 range_value: Option<Range>,
63}
64
65impl Value {
66 pub fn null() -> Self {
68 Self {
69 kind: ValueKind::Null,
70 int_value: 0,
71 bool_value: false,
72 string_value: String::new(),
73 decimal_value: None,
74 decimal_scale: String::new(),
75 array_value: Vec::new(),
76 object_value: HashMap::new(),
77 bytes_value: Vec::new(),
78 date_value: None,
79 time_value: None,
80 timestamp_value: None,
81 range_value: None,
82 }
83 }
84
85 pub fn int(value: i64) -> Self {
87 Self {
88 kind: ValueKind::Int,
89 int_value: value,
90 ..Self::null()
91 }
92 }
93
94 pub fn bool(value: bool) -> Self {
96 Self {
97 kind: ValueKind::Bool,
98 bool_value: value,
99 ..Self::null()
100 }
101 }
102
103 pub fn string<S: Into<String>>(value: S) -> Self {
105 Self {
106 kind: ValueKind::String,
107 string_value: value.into(),
108 ..Self::null()
109 }
110 }
111
112 pub fn decimal(value: Decimal) -> Self {
114 Self {
115 kind: ValueKind::Decimal,
116 decimal_value: Some(value),
117 ..Self::null()
118 }
119 }
120
121 pub fn array(values: Vec<Value>) -> Self {
123 Self {
124 kind: ValueKind::Array,
125 array_value: values,
126 ..Self::null()
127 }
128 }
129
130 pub fn object(values: HashMap<String, Value>) -> Self {
132 Self {
133 kind: ValueKind::Object,
134 object_value: values,
135 ..Self::null()
136 }
137 }
138
139 pub fn is_null(&self) -> bool {
141 self.kind == ValueKind::Null
142 }
143
144 pub fn as_int(&self) -> Result<i64> {
146 if self.kind == ValueKind::Int {
147 Ok(self.int_value)
148 } else {
149 Err(Error::type_error(format!(
150 "Cannot convert {:?} to int",
151 self.kind
152 )))
153 }
154 }
155
156 pub fn as_bool(&self) -> Result<bool> {
158 if self.kind == ValueKind::Bool {
159 Ok(self.bool_value)
160 } else {
161 Err(Error::type_error(format!(
162 "Cannot convert {:?} to bool",
163 self.kind
164 )))
165 }
166 }
167
168 pub fn as_string(&self) -> Result<&str> {
170 match self.kind {
171 ValueKind::String
172 | ValueKind::Xml
173 | ValueKind::Json
174 | ValueKind::Jsonb
175 | ValueKind::Url
176 | ValueKind::Domain
177 | ValueKind::Uuid
178 | ValueKind::Enum
179 | ValueKind::BitString => Ok(&self.string_value),
180 _ => Err(Error::type_error(format!(
181 "Cannot convert {:?} to string",
182 self.kind
183 ))),
184 }
185 }
186
187 pub fn as_decimal(&self) -> Result<Decimal> {
189 if self.kind == ValueKind::Decimal {
190 self.decimal_value
191 .ok_or_else(|| Error::type_error("Decimal value is None"))
192 } else {
193 Err(Error::type_error(format!(
194 "Cannot convert {:?} to decimal",
195 self.kind
196 )))
197 }
198 }
199
200 pub fn as_array(&self) -> Result<&[Value]> {
202 if self.kind == ValueKind::Array {
203 Ok(&self.array_value)
204 } else {
205 Err(Error::type_error(format!(
206 "Cannot convert {:?} to array",
207 self.kind
208 )))
209 }
210 }
211
212 pub fn as_object(&self) -> Result<&HashMap<String, Value>> {
214 if self.kind == ValueKind::Object {
215 Ok(&self.object_value)
216 } else {
217 Err(Error::type_error(format!(
218 "Cannot convert {:?} to object",
219 self.kind
220 )))
221 }
222 }
223
224 pub fn as_bytes(&self) -> Result<&[u8]> {
226 if self.kind == ValueKind::Bytea {
227 Ok(&self.bytes_value)
228 } else {
229 Err(Error::type_error(format!(
230 "Cannot convert {:?} to bytes",
231 self.kind
232 )))
233 }
234 }
235
236 pub fn as_date(&self) -> Result<NaiveDate> {
238 if self.kind == ValueKind::Date {
239 self.date_value
240 .ok_or_else(|| Error::type_error("Date value is None"))
241 } else {
242 Err(Error::type_error(format!(
243 "Cannot convert {:?} to date",
244 self.kind
245 )))
246 }
247 }
248
249 pub fn as_timestamp(&self) -> Result<DateTime<Utc>> {
251 if self.kind == ValueKind::Timestamp || self.kind == ValueKind::TimestampTz {
252 self.timestamp_value
253 .ok_or_else(|| Error::type_error("Timestamp value is None"))
254 } else {
255 Err(Error::type_error(format!(
256 "Cannot convert {:?} to timestamp",
257 self.kind
258 )))
259 }
260 }
261
262 pub fn as_range(&self) -> Result<&Range> {
264 if self.kind == ValueKind::Range {
265 self.range_value
266 .as_ref()
267 .ok_or_else(|| Error::type_error("Range value is None"))
268 } else {
269 Err(Error::type_error(format!(
270 "Cannot convert {:?} to range",
271 self.kind
272 )))
273 }
274 }
275
276 pub fn to_json(&self) -> serde_json::Value {
278 match self.kind {
279 ValueKind::Null => serde_json::Value::Null,
280 ValueKind::Int => serde_json::Value::Number(self.int_value.into()),
281 ValueKind::Bool => serde_json::Value::Bool(self.bool_value),
282 ValueKind::String
283 | ValueKind::Xml
284 | ValueKind::Json
285 | ValueKind::Jsonb
286 | ValueKind::Url
287 | ValueKind::Domain
288 | ValueKind::Uuid
289 | ValueKind::Enum
290 | ValueKind::BitString => serde_json::Value::String(self.string_value.clone()),
291 ValueKind::Decimal => serde_json::Value::String(
292 self.decimal_value
293 .map(|d| d.to_string())
294 .unwrap_or_default(),
295 ),
296 ValueKind::Array => {
297 serde_json::Value::Array(self.array_value.iter().map(|v| v.to_json()).collect())
298 }
299 ValueKind::Object => {
300 let mut map = serde_json::Map::new();
301 for (k, v) in &self.object_value {
302 map.insert(k.clone(), v.to_json());
303 }
304 serde_json::Value::Object(map)
305 }
306 ValueKind::Bytea => {
307 if self.bytes_value.is_empty() {
308 serde_json::Value::String(self.string_value.clone())
309 } else {
310 serde_json::Value::String(format!("\\x{}", hex::encode(&self.bytes_value)))
311 }
312 }
313 ValueKind::Date
314 | ValueKind::Time
315 | ValueKind::TimeTz
316 | ValueKind::Timestamp
317 | ValueKind::TimestampTz
318 | ValueKind::Interval => serde_json::Value::String(self.string_value.clone()),
319 ValueKind::Range => {
320 if let Some(range) = &self.range_value {
321 let mut map = serde_json::Map::new();
322 if let Some(lower) = &range.lower {
323 map.insert("lower".to_string(), lower.to_json());
324 }
325 if let Some(upper) = &range.upper {
326 map.insert("upper".to_string(), upper.to_json());
327 }
328 map.insert(
329 "bounds".to_string(),
330 serde_json::Value::String(range.bounds.clone()),
331 );
332 serde_json::Value::Object(map)
333 } else {
334 serde_json::Value::Null
335 }
336 }
337 }
338 }
339
340 pub fn from_json(json: serde_json::Value) -> Self {
342 match json {
343 serde_json::Value::Null => Self::null(),
344 serde_json::Value::Bool(b) => Self::bool(b),
345 serde_json::Value::Number(n) => {
346 if let Some(i) = n.as_i64() {
347 Self::int(i)
348 } else if let Some(f) = n.as_f64() {
349 Self::string(f.to_string())
351 } else {
352 Self::null()
353 }
354 }
355 serde_json::Value::String(s) => Self::string(s),
356 serde_json::Value::Array(arr) => {
357 let values: Vec<Value> = arr.into_iter().map(Self::from_json).collect();
358 Self::array(values)
359 }
360 serde_json::Value::Object(obj) => {
361 let mut map = HashMap::new();
362 for (k, v) in obj {
363 map.insert(k, Self::from_json(v));
364 }
365 Self::object(map)
366 }
367 }
368 }
369}
370
371pub fn decode_value(raw: &serde_json::Value, type_name: &str) -> Result<Value> {
373 if raw.is_null() {
374 return Ok(Value::null());
375 }
376
377 let type_upper = type_name.to_uppercase();
378
379 match type_upper.as_str() {
380 "INT" => {
381 if let Some(n) = raw.as_i64() {
382 Ok(Value::int(n))
383 } else if let Some(s) = raw.as_str() {
384 if let Ok(n) = s.parse::<i64>() {
385 Ok(Value::int(n))
386 } else {
387 Ok(Value::string(s))
388 }
389 } else {
390 Ok(Value::string(raw.to_string()))
391 }
392 }
393 "DECIMAL" => {
394 let s = raw
395 .as_str()
396 .map(|v| v.to_string())
397 .unwrap_or_else(|| raw.to_string());
398 if let Ok(dec) = s.parse::<Decimal>() {
399 Ok(Value::decimal(dec))
400 } else {
401 Ok(Value::string(s))
402 }
403 }
404 "BOOL" => {
405 if let Some(b) = raw.as_bool() {
406 Ok(Value::bool(b))
407 } else if let Some(s) = raw.as_str() {
408 let lower = s.to_ascii_lowercase();
409 if lower == "true" {
410 Ok(Value::bool(true))
411 } else if lower == "false" {
412 Ok(Value::bool(false))
413 } else {
414 Ok(Value::string(s))
415 }
416 } else {
417 Ok(Value::string(raw.to_string()))
418 }
419 }
420 "STRING" => Ok(Value::string(raw.as_str().unwrap_or(""))),
421 "BYTEA" => {
422 let s = raw.as_str().unwrap_or("");
423 let bytes = if let Some(hex_str) = s.strip_prefix("\\x") {
424 hex::decode(hex_str).unwrap_or_default()
425 } else {
426 Vec::new()
427 };
428 Ok(Value {
429 kind: ValueKind::Bytea,
430 bytes_value: bytes,
431 string_value: s.to_string(),
432 ..Value::null()
433 })
434 }
435 "JSON" => Ok(Value {
436 kind: ValueKind::Json,
437 string_value: raw.to_string(),
438 ..Value::null()
439 }),
440 "JSONB" => Ok(Value {
441 kind: ValueKind::Jsonb,
442 string_value: raw.to_string(),
443 ..Value::null()
444 }),
445 "DATE" => {
446 let s = raw.as_str().unwrap_or("");
447 let date = NaiveDate::parse_from_str(s, "%Y-%m-%d").ok();
448 Ok(Value {
449 kind: ValueKind::Date,
450 string_value: s.to_string(),
451 date_value: date,
452 ..Value::null()
453 })
454 }
455 "TIMESTAMP" | "TIMESTAMPTZ" => {
456 let s = raw.as_str().unwrap_or("");
457 let timestamp = DateTime::parse_from_rfc3339(s)
458 .ok()
459 .map(|dt| dt.with_timezone(&Utc));
460 let kind = if type_upper == "TIMESTAMPTZ" {
461 ValueKind::TimestampTz
462 } else {
463 ValueKind::Timestamp
464 };
465 Ok(Value {
466 kind,
467 string_value: s.to_string(),
468 timestamp_value: timestamp,
469 ..Value::null()
470 })
471 }
472 _ if type_upper.contains("RANGE") => {
473 if let Some(obj) = raw.as_object() {
474 let range = Range {
475 lower: obj
476 .get("lower")
477 .and_then(|v| decode_value(v, "").ok().map(Box::new)),
478 upper: obj
479 .get("upper")
480 .and_then(|v| decode_value(v, "").ok().map(Box::new)),
481 bounds: obj
482 .get("bounds")
483 .and_then(|v| v.as_str())
484 .unwrap_or("")
485 .to_string(),
486 };
487 Ok(Value {
488 kind: ValueKind::Range,
489 range_value: Some(range),
490 ..Value::null()
491 })
492 } else {
493 Ok(Value::string(raw.to_string()))
494 }
495 }
496 _ => {
497 if let Some(arr) = raw.as_array() {
499 let values: Result<Vec<_>> = arr.iter().map(|v| decode_value(v, "")).collect();
500 Ok(Value::array(values?))
501 } else if let Some(obj) = raw.as_object() {
502 let mut map = HashMap::new();
503 for (k, v) in obj {
504 map.insert(k.clone(), decode_value(v, "")?);
505 }
506 Ok(Value::object(map))
507 } else if let Some(b) = raw.as_bool() {
508 Ok(Value::bool(b))
509 } else if let Some(n) = raw.as_i64() {
510 Ok(Value::int(n))
511 } else if let Some(f) = raw.as_f64() {
512 let s = f.to_string();
513 if let Ok(dec) = s.parse::<Decimal>() {
514 Ok(Value::decimal(dec))
515 } else {
516 Ok(Value::string(s))
517 }
518 } else if let Some(s) = raw.as_str() {
519 Ok(Value::string(s))
520 } else {
521 Ok(Value::string(raw.to_string()))
522 }
523 }
524 }
525}
526
527#[cfg(test)]
528mod tests {
529 use super::*;
530 use chrono::{Datelike, Timelike};
531 use rust_decimal_macros::dec;
532 use serde_json::json;
533
534 #[test]
537 fn test_value_kind_equality() {
538 assert_eq!(ValueKind::Null, ValueKind::Null);
539 assert_eq!(ValueKind::Int, ValueKind::Int);
540 assert_ne!(ValueKind::Int, ValueKind::String);
541 }
542
543 #[test]
544 fn test_value_kind_copy() {
545 let kind = ValueKind::Int;
546 let kind_copy = kind;
547 assert_eq!(kind, kind_copy);
548 }
549
550 #[test]
551 fn test_value_kind_debug() {
552 let debug_str = format!("{:?}", ValueKind::Timestamp);
553 assert_eq!(debug_str, "Timestamp");
554 }
555
556 #[test]
557 fn test_value_kind_all_variants() {
558 let variants = [
560 ValueKind::Null,
561 ValueKind::Int,
562 ValueKind::Bool,
563 ValueKind::String,
564 ValueKind::Decimal,
565 ValueKind::Array,
566 ValueKind::Object,
567 ValueKind::Bytea,
568 ValueKind::Date,
569 ValueKind::Time,
570 ValueKind::TimeTz,
571 ValueKind::Timestamp,
572 ValueKind::TimestampTz,
573 ValueKind::Interval,
574 ValueKind::Json,
575 ValueKind::Jsonb,
576 ValueKind::Xml,
577 ValueKind::Url,
578 ValueKind::Domain,
579 ValueKind::Uuid,
580 ValueKind::Enum,
581 ValueKind::BitString,
582 ValueKind::Range,
583 ];
584 assert_eq!(variants.len(), 23);
585 for i in 0..variants.len() {
587 for j in (i + 1)..variants.len() {
588 assert_ne!(variants[i], variants[j]);
589 }
590 }
591 }
592
593 #[test]
596 fn test_value_null() {
597 let v = Value::null();
598 assert_eq!(v.kind, ValueKind::Null);
599 assert!(v.is_null());
600 }
601
602 #[test]
603 fn test_value_int() {
604 let v = Value::int(42);
605 assert_eq!(v.kind, ValueKind::Int);
606 assert!(!v.is_null());
607 assert_eq!(v.as_int().unwrap(), 42);
608 }
609
610 #[test]
611 fn test_value_int_negative() {
612 let v = Value::int(-100);
613 assert_eq!(v.as_int().unwrap(), -100);
614 }
615
616 #[test]
617 fn test_value_int_zero() {
618 let v = Value::int(0);
619 assert_eq!(v.as_int().unwrap(), 0);
620 }
621
622 #[test]
623 fn test_value_int_max() {
624 let v = Value::int(i64::MAX);
625 assert_eq!(v.as_int().unwrap(), i64::MAX);
626 }
627
628 #[test]
629 fn test_value_int_min() {
630 let v = Value::int(i64::MIN);
631 assert_eq!(v.as_int().unwrap(), i64::MIN);
632 }
633
634 #[test]
635 fn test_value_bool_true() {
636 let v = Value::bool(true);
637 assert_eq!(v.kind, ValueKind::Bool);
638 assert!(v.as_bool().unwrap());
639 }
640
641 #[test]
642 fn test_value_bool_false() {
643 let v = Value::bool(false);
644 assert!(!v.as_bool().unwrap());
645 }
646
647 #[test]
648 fn test_value_string() {
649 let v = Value::string("hello");
650 assert_eq!(v.kind, ValueKind::String);
651 assert_eq!(v.as_string().unwrap(), "hello");
652 }
653
654 #[test]
655 fn test_value_string_empty() {
656 let v = Value::string("");
657 assert_eq!(v.as_string().unwrap(), "");
658 }
659
660 #[test]
661 fn test_value_string_unicode() {
662 let v = Value::string("こんにちは世界🌍");
663 assert_eq!(v.as_string().unwrap(), "こんにちは世界🌍");
664 }
665
666 #[test]
667 fn test_value_string_owned() {
668 let owned = String::from("owned string");
669 let v = Value::string(owned);
670 assert_eq!(v.as_string().unwrap(), "owned string");
671 }
672
673 #[test]
674 fn test_value_decimal() {
675 let v = Value::decimal(dec!(123.456));
676 assert_eq!(v.kind, ValueKind::Decimal);
677 assert_eq!(v.as_decimal().unwrap(), dec!(123.456));
678 }
679
680 #[test]
681 fn test_value_decimal_precision() {
682 let v = Value::decimal(dec!(0.000000001));
683 assert_eq!(v.as_decimal().unwrap(), dec!(0.000000001));
684 }
685
686 #[test]
687 fn test_value_decimal_large() {
688 let v = Value::decimal(dec!(99999999999999.99));
689 assert_eq!(v.as_decimal().unwrap(), dec!(99999999999999.99));
690 }
691
692 #[test]
693 fn test_value_array_empty() {
694 let v = Value::array(vec![]);
695 assert_eq!(v.kind, ValueKind::Array);
696 assert!(v.as_array().unwrap().is_empty());
697 }
698
699 #[test]
700 fn test_value_array() {
701 let v = Value::array(vec![Value::int(1), Value::int(2), Value::int(3)]);
702 let arr = v.as_array().unwrap();
703 assert_eq!(arr.len(), 3);
704 assert_eq!(arr[0].as_int().unwrap(), 1);
705 assert_eq!(arr[1].as_int().unwrap(), 2);
706 assert_eq!(arr[2].as_int().unwrap(), 3);
707 }
708
709 #[test]
710 fn test_value_array_mixed() {
711 let v = Value::array(vec![
712 Value::int(42),
713 Value::string("hello"),
714 Value::bool(true),
715 Value::null(),
716 ]);
717 let arr = v.as_array().unwrap();
718 assert_eq!(arr[0].as_int().unwrap(), 42);
719 assert_eq!(arr[1].as_string().unwrap(), "hello");
720 assert!(arr[2].as_bool().unwrap());
721 assert!(arr[3].is_null());
722 }
723
724 #[test]
725 fn test_value_array_nested() {
726 let inner = Value::array(vec![Value::int(1), Value::int(2)]);
727 let outer = Value::array(vec![inner]);
728 let arr = outer.as_array().unwrap();
729 let inner_arr = arr[0].as_array().unwrap();
730 assert_eq!(inner_arr.len(), 2);
731 }
732
733 #[test]
734 fn test_value_object_empty() {
735 let v = Value::object(HashMap::new());
736 assert_eq!(v.kind, ValueKind::Object);
737 assert!(v.as_object().unwrap().is_empty());
738 }
739
740 #[test]
741 fn test_value_object() {
742 let mut map = HashMap::new();
743 map.insert("name".to_string(), Value::string("Alice"));
744 map.insert("age".to_string(), Value::int(30));
745 let v = Value::object(map);
746
747 let obj = v.as_object().unwrap();
748 assert_eq!(obj.get("name").unwrap().as_string().unwrap(), "Alice");
749 assert_eq!(obj.get("age").unwrap().as_int().unwrap(), 30);
750 }
751
752 #[test]
753 fn test_value_object_nested() {
754 let mut inner = HashMap::new();
755 inner.insert("city".to_string(), Value::string("NYC"));
756
757 let mut outer = HashMap::new();
758 outer.insert("address".to_string(), Value::object(inner));
759
760 let v = Value::object(outer);
761 let obj = v.as_object().unwrap();
762 let addr = obj.get("address").unwrap().as_object().unwrap();
763 assert_eq!(addr.get("city").unwrap().as_string().unwrap(), "NYC");
764 }
765
766 #[test]
769 fn test_as_int_wrong_type() {
770 let v = Value::string("not an int");
771 let result = v.as_int();
772 assert!(result.is_err());
773 assert!(result.unwrap_err().to_string().contains("String"));
774 }
775
776 #[test]
777 fn test_as_bool_wrong_type() {
778 let v = Value::int(42);
779 let result = v.as_bool();
780 assert!(result.is_err());
781 }
782
783 #[test]
784 fn test_as_string_wrong_type() {
785 let v = Value::int(42);
786 let result = v.as_string();
787 assert!(result.is_err());
788 }
789
790 #[test]
791 fn test_as_decimal_wrong_type() {
792 let v = Value::int(42);
793 let result = v.as_decimal();
794 assert!(result.is_err());
795 }
796
797 #[test]
798 fn test_as_array_wrong_type() {
799 let v = Value::int(42);
800 let result = v.as_array();
801 assert!(result.is_err());
802 }
803
804 #[test]
805 fn test_as_object_wrong_type() {
806 let v = Value::int(42);
807 let result = v.as_object();
808 assert!(result.is_err());
809 }
810
811 #[test]
812 fn test_as_bytes_wrong_type() {
813 let v = Value::int(42);
814 let result = v.as_bytes();
815 assert!(result.is_err());
816 }
817
818 #[test]
819 fn test_as_date_wrong_type() {
820 let v = Value::int(42);
821 let result = v.as_date();
822 assert!(result.is_err());
823 }
824
825 #[test]
826 fn test_as_timestamp_wrong_type() {
827 let v = Value::int(42);
828 let result = v.as_timestamp();
829 assert!(result.is_err());
830 }
831
832 #[test]
833 fn test_as_range_wrong_type() {
834 let v = Value::int(42);
835 let result = v.as_range();
836 assert!(result.is_err());
837 }
838
839 #[test]
842 fn test_as_string_from_xml() {
843 let v = Value {
844 kind: ValueKind::Xml,
845 string_value: "<root/>".to_string(),
846 ..Value::null()
847 };
848 assert_eq!(v.as_string().unwrap(), "<root/>");
849 }
850
851 #[test]
852 fn test_as_string_from_json() {
853 let v = Value {
854 kind: ValueKind::Json,
855 string_value: r#"{"key":"value"}"#.to_string(),
856 ..Value::null()
857 };
858 assert_eq!(v.as_string().unwrap(), r#"{"key":"value"}"#);
859 }
860
861 #[test]
862 fn test_as_string_from_url() {
863 let v = Value {
864 kind: ValueKind::Url,
865 string_value: "https://example.com".to_string(),
866 ..Value::null()
867 };
868 assert_eq!(v.as_string().unwrap(), "https://example.com");
869 }
870
871 #[test]
872 fn test_as_string_from_uuid() {
873 let v = Value {
874 kind: ValueKind::Uuid,
875 string_value: "550e8400-e29b-41d4-a716-446655440000".to_string(),
876 ..Value::null()
877 };
878 assert_eq!(
879 v.as_string().unwrap(),
880 "550e8400-e29b-41d4-a716-446655440000"
881 );
882 }
883
884 #[test]
887 fn test_to_json_null() {
888 let v = Value::null();
889 assert_eq!(v.to_json(), json!(null));
890 }
891
892 #[test]
893 fn test_to_json_int() {
894 let v = Value::int(42);
895 assert_eq!(v.to_json(), json!(42));
896 }
897
898 #[test]
899 fn test_to_json_bool() {
900 let v = Value::bool(true);
901 assert_eq!(v.to_json(), json!(true));
902 }
903
904 #[test]
905 fn test_to_json_string() {
906 let v = Value::string("hello");
907 assert_eq!(v.to_json(), json!("hello"));
908 }
909
910 #[test]
911 fn test_to_json_decimal() {
912 let v = Value::decimal(dec!(123.45));
913 assert_eq!(v.to_json(), json!("123.45"));
914 }
915
916 #[test]
917 fn test_to_json_array() {
918 let v = Value::array(vec![Value::int(1), Value::int(2)]);
919 assert_eq!(v.to_json(), json!([1, 2]));
920 }
921
922 #[test]
923 fn test_to_json_object() {
924 let mut map = HashMap::new();
925 map.insert("key".to_string(), Value::string("value"));
926 let v = Value::object(map);
927 assert_eq!(v.to_json(), json!({"key": "value"}));
928 }
929
930 #[test]
931 fn test_to_json_bytea_empty() {
932 let v = Value {
933 kind: ValueKind::Bytea,
934 bytes_value: vec![],
935 string_value: "".to_string(),
936 ..Value::null()
937 };
938 assert_eq!(v.to_json(), json!(""));
939 }
940
941 #[test]
942 fn test_to_json_bytea_with_data() {
943 let v = Value {
944 kind: ValueKind::Bytea,
945 bytes_value: vec![0xDE, 0xAD, 0xBE, 0xEF],
946 ..Value::null()
947 };
948 assert_eq!(v.to_json(), json!("\\xdeadbeef"));
949 }
950
951 #[test]
952 fn test_to_json_range() {
953 let range = Range {
954 lower: Some(Box::new(Value::int(1))),
955 upper: Some(Box::new(Value::int(10))),
956 bounds: "[)".to_string(),
957 };
958 let v = Value {
959 kind: ValueKind::Range,
960 range_value: Some(range),
961 ..Value::null()
962 };
963 let j = v.to_json();
964 assert_eq!(j["lower"], json!(1));
965 assert_eq!(j["upper"], json!(10));
966 assert_eq!(j["bounds"], json!("[)"));
967 }
968
969 #[test]
970 fn test_to_json_range_none() {
971 let v = Value {
972 kind: ValueKind::Range,
973 range_value: None,
974 ..Value::null()
975 };
976 assert_eq!(v.to_json(), json!(null));
977 }
978
979 #[test]
982 fn test_from_json_null() {
983 let v = Value::from_json(json!(null));
984 assert!(v.is_null());
985 }
986
987 #[test]
988 fn test_from_json_bool() {
989 let v = Value::from_json(json!(true));
990 assert!(v.as_bool().unwrap());
991 }
992
993 #[test]
994 fn test_from_json_int() {
995 let v = Value::from_json(json!(42));
996 assert_eq!(v.as_int().unwrap(), 42);
997 }
998
999 #[test]
1000 fn test_from_json_float() {
1001 let v = Value::from_json(json!(1.5));
1002 assert_eq!(v.kind, ValueKind::String);
1004 }
1005
1006 #[test]
1007 fn test_from_json_string() {
1008 let v = Value::from_json(json!("hello"));
1009 assert_eq!(v.as_string().unwrap(), "hello");
1010 }
1011
1012 #[test]
1013 fn test_from_json_array() {
1014 let v = Value::from_json(json!([1, 2, 3]));
1015 let arr = v.as_array().unwrap();
1016 assert_eq!(arr.len(), 3);
1017 }
1018
1019 #[test]
1020 fn test_from_json_object() {
1021 let v = Value::from_json(json!({"name": "Alice"}));
1022 let obj = v.as_object().unwrap();
1023 assert_eq!(obj.get("name").unwrap().as_string().unwrap(), "Alice");
1024 }
1025
1026 #[test]
1027 fn test_from_json_nested() {
1028 let v = Value::from_json(json!({
1029 "users": [
1030 {"name": "Alice", "age": 30},
1031 {"name": "Bob", "age": 25}
1032 ]
1033 }));
1034 let obj = v.as_object().unwrap();
1035 let users = obj.get("users").unwrap().as_array().unwrap();
1036 assert_eq!(users.len(), 2);
1037 }
1038
1039 #[test]
1042 fn test_decode_value_null() {
1043 let v = decode_value(&json!(null), "INT").unwrap();
1044 assert!(v.is_null());
1045 }
1046
1047 #[test]
1048 fn test_decode_value_int_from_number() {
1049 let v = decode_value(&json!(42), "INT").unwrap();
1050 assert_eq!(v.as_int().unwrap(), 42);
1051 }
1052
1053 #[test]
1054 fn test_decode_value_int_from_string() {
1055 let v = decode_value(&json!("123"), "INT").unwrap();
1056 assert_eq!(v.as_int().unwrap(), 123);
1057 }
1058
1059 #[test]
1060 fn test_decode_value_int_invalid_string() {
1061 let v = decode_value(&json!("not_a_number"), "INT").unwrap();
1062 assert_eq!(v.kind, ValueKind::String);
1064 }
1065
1066 #[test]
1067 fn test_decode_value_decimal() {
1068 let v = decode_value(&json!("123.456"), "DECIMAL").unwrap();
1069 assert_eq!(v.as_decimal().unwrap(), dec!(123.456));
1070 }
1071
1072 #[test]
1073 fn test_decode_value_decimal_from_number() {
1074 let v = decode_value(&json!(123), "DECIMAL").unwrap();
1075 assert_eq!(v.as_decimal().unwrap(), dec!(123));
1076 }
1077
1078 #[test]
1079 fn test_decode_value_bool_true() {
1080 let v = decode_value(&json!(true), "BOOL").unwrap();
1081 assert!(v.as_bool().unwrap());
1082 }
1083
1084 #[test]
1085 fn test_decode_value_bool_false() {
1086 let v = decode_value(&json!(false), "BOOL").unwrap();
1087 assert!(!v.as_bool().unwrap());
1088 }
1089
1090 #[test]
1091 fn test_decode_value_bool_from_string_true() {
1092 let v = decode_value(&json!("true"), "BOOL").unwrap();
1093 assert!(v.as_bool().unwrap());
1094 }
1095
1096 #[test]
1097 fn test_decode_value_bool_from_string_false() {
1098 let v = decode_value(&json!("false"), "BOOL").unwrap();
1099 assert!(!v.as_bool().unwrap());
1100 }
1101
1102 #[test]
1103 fn test_decode_value_bool_from_string_case_insensitive() {
1104 let v = decode_value(&json!("TRUE"), "BOOL").unwrap();
1105 assert!(v.as_bool().unwrap());
1106 }
1107
1108 #[test]
1109 fn test_decode_value_string() {
1110 let v = decode_value(&json!("hello"), "STRING").unwrap();
1111 assert_eq!(v.as_string().unwrap(), "hello");
1112 }
1113
1114 #[test]
1115 fn test_decode_value_bytea() {
1116 let v = decode_value(&json!("\\xDEADBEEF"), "BYTEA").unwrap();
1117 assert_eq!(v.kind, ValueKind::Bytea);
1118 assert_eq!(v.as_bytes().unwrap(), &[0xDE, 0xAD, 0xBE, 0xEF]);
1119 }
1120
1121 #[test]
1122 fn test_decode_value_bytea_no_prefix() {
1123 let v = decode_value(&json!("plain"), "BYTEA").unwrap();
1124 assert_eq!(v.kind, ValueKind::Bytea);
1125 assert!(v.as_bytes().unwrap().is_empty());
1126 }
1127
1128 #[test]
1129 fn test_decode_value_json() {
1130 let v = decode_value(&json!({"key": "value"}), "JSON").unwrap();
1131 assert_eq!(v.kind, ValueKind::Json);
1132 }
1133
1134 #[test]
1135 fn test_decode_value_jsonb() {
1136 let v = decode_value(&json!({"key": "value"}), "JSONB").unwrap();
1137 assert_eq!(v.kind, ValueKind::Jsonb);
1138 }
1139
1140 #[test]
1141 fn test_decode_value_date() {
1142 let v = decode_value(&json!("2024-01-15"), "DATE").unwrap();
1143 assert_eq!(v.kind, ValueKind::Date);
1144 let date = v.as_date().unwrap();
1145 assert_eq!(date.to_string(), "2024-01-15");
1146 }
1147
1148 #[test]
1149 fn test_decode_value_date_invalid() {
1150 let v = decode_value(&json!("not-a-date"), "DATE").unwrap();
1151 assert_eq!(v.kind, ValueKind::Date);
1152 assert!(v.date_value.is_none());
1154 }
1155
1156 #[test]
1157 fn test_decode_value_timestamp() {
1158 let v = decode_value(&json!("2024-01-15T10:30:00Z"), "TIMESTAMP").unwrap();
1159 assert_eq!(v.kind, ValueKind::Timestamp);
1160 let ts = v.as_timestamp().unwrap();
1161 assert_eq!(ts.to_rfc3339(), "2024-01-15T10:30:00+00:00");
1162 }
1163
1164 #[test]
1165 fn test_decode_value_timestamptz() {
1166 let v = decode_value(&json!("2024-01-15T10:30:00+05:00"), "TIMESTAMPTZ").unwrap();
1167 assert_eq!(v.kind, ValueKind::TimestampTz);
1168 }
1169
1170 #[test]
1171 fn test_decode_value_range() {
1172 let v = decode_value(
1173 &json!({"lower": 1, "upper": 10, "bounds": "[)"}),
1174 "INT4RANGE",
1175 )
1176 .unwrap();
1177 assert_eq!(v.kind, ValueKind::Range);
1178 let range = v.as_range().unwrap();
1179 assert_eq!(range.bounds, "[)");
1180 }
1181
1182 #[test]
1183 fn test_decode_value_array_generic() {
1184 let v = decode_value(&json!([1, 2, 3]), "").unwrap();
1185 assert_eq!(v.kind, ValueKind::Array);
1186 assert_eq!(v.as_array().unwrap().len(), 3);
1187 }
1188
1189 #[test]
1190 fn test_decode_value_object_generic() {
1191 let v = decode_value(&json!({"key": "value"}), "").unwrap();
1192 assert_eq!(v.kind, ValueKind::Object);
1193 }
1194
1195 #[test]
1196 fn test_decode_value_generic_bool() {
1197 let v = decode_value(&json!(true), "UNKNOWN").unwrap();
1198 assert!(v.as_bool().unwrap());
1199 }
1200
1201 #[test]
1202 fn test_decode_value_generic_int() {
1203 let v = decode_value(&json!(42), "UNKNOWN").unwrap();
1204 assert_eq!(v.as_int().unwrap(), 42);
1205 }
1206
1207 #[test]
1208 fn test_decode_value_generic_float() {
1209 let v = decode_value(&json!(1.23), "UNKNOWN").unwrap();
1210 assert_eq!(v.kind, ValueKind::Decimal);
1212 }
1213
1214 #[test]
1215 fn test_decode_value_generic_string() {
1216 let v = decode_value(&json!("hello"), "UNKNOWN").unwrap();
1217 assert_eq!(v.as_string().unwrap(), "hello");
1218 }
1219
1220 #[test]
1221 fn test_decode_value_case_insensitive() {
1222 let v1 = decode_value(&json!(42), "int").unwrap();
1223 let v2 = decode_value(&json!(42), "INT").unwrap();
1224 let v3 = decode_value(&json!(42), "Int").unwrap();
1225 assert_eq!(v1.as_int().unwrap(), 42);
1226 assert_eq!(v2.as_int().unwrap(), 42);
1227 assert_eq!(v3.as_int().unwrap(), 42);
1228 }
1229
1230 #[test]
1233 fn test_range_construction() {
1234 let range = Range {
1235 lower: Some(Box::new(Value::int(0))),
1236 upper: Some(Box::new(Value::int(100))),
1237 bounds: "[)".to_string(),
1238 };
1239 assert_eq!(range.lower.as_ref().unwrap().as_int().unwrap(), 0);
1240 assert_eq!(range.upper.as_ref().unwrap().as_int().unwrap(), 100);
1241 assert_eq!(range.bounds, "[)");
1242 }
1243
1244 #[test]
1245 fn test_range_unbounded_lower() {
1246 let range = Range {
1247 lower: None,
1248 upper: Some(Box::new(Value::int(100))),
1249 bounds: "(]".to_string(),
1250 };
1251 assert!(range.lower.is_none());
1252 assert!(range.upper.is_some());
1253 }
1254
1255 #[test]
1256 fn test_range_unbounded_upper() {
1257 let range = Range {
1258 lower: Some(Box::new(Value::int(0))),
1259 upper: None,
1260 bounds: "[)".to_string(),
1261 };
1262 assert!(range.lower.is_some());
1263 assert!(range.upper.is_none());
1264 }
1265
1266 #[test]
1267 fn test_range_clone() {
1268 let range = Range {
1269 lower: Some(Box::new(Value::int(1))),
1270 upper: Some(Box::new(Value::int(10))),
1271 bounds: "[]".to_string(),
1272 };
1273 let cloned = range.clone();
1274 assert_eq!(cloned.bounds, "[]");
1275 }
1276
1277 #[test]
1280 fn test_value_clone() {
1281 let v = Value::string("test");
1282 let cloned = v.clone();
1283 assert_eq!(cloned.as_string().unwrap(), "test");
1284 }
1285
1286 #[test]
1287 fn test_value_clone_array() {
1288 let v = Value::array(vec![Value::int(1), Value::int(2)]);
1289 let cloned = v.clone();
1290 assert_eq!(cloned.as_array().unwrap().len(), 2);
1291 }
1292
1293 #[test]
1294 fn test_value_clone_object() {
1295 let mut map = HashMap::new();
1296 map.insert("key".to_string(), Value::string("value"));
1297 let v = Value::object(map);
1298 let cloned = v.clone();
1299 assert_eq!(
1300 cloned
1301 .as_object()
1302 .unwrap()
1303 .get("key")
1304 .unwrap()
1305 .as_string()
1306 .unwrap(),
1307 "value"
1308 );
1309 }
1310
1311 #[test]
1314 fn test_json_roundtrip_int() {
1315 let original = Value::int(42);
1316 let json = original.to_json();
1317 let restored = Value::from_json(json);
1318 assert_eq!(restored.as_int().unwrap(), 42);
1319 }
1320
1321 #[test]
1322 fn test_json_roundtrip_string() {
1323 let original = Value::string("hello world");
1324 let json = original.to_json();
1325 let restored = Value::from_json(json);
1326 assert_eq!(restored.as_string().unwrap(), "hello world");
1327 }
1328
1329 #[test]
1330 fn test_json_roundtrip_bool() {
1331 let original = Value::bool(true);
1332 let json = original.to_json();
1333 let restored = Value::from_json(json);
1334 assert!(restored.as_bool().unwrap());
1335 }
1336
1337 #[test]
1338 fn test_json_roundtrip_array() {
1339 let original = Value::array(vec![Value::int(1), Value::string("two")]);
1340 let json = original.to_json();
1341 let restored = Value::from_json(json);
1342 let arr = restored.as_array().unwrap();
1343 assert_eq!(arr[0].as_int().unwrap(), 1);
1344 assert_eq!(arr[1].as_string().unwrap(), "two");
1345 }
1346
1347 #[test]
1348 fn test_json_roundtrip_object() {
1349 let mut map = HashMap::new();
1350 map.insert("name".to_string(), Value::string("Alice"));
1351 map.insert("age".to_string(), Value::int(30));
1352 let original = Value::object(map);
1353 let json = original.to_json();
1354 let restored = Value::from_json(json);
1355 let obj = restored.as_object().unwrap();
1356 assert_eq!(obj.get("name").unwrap().as_string().unwrap(), "Alice");
1357 assert_eq!(obj.get("age").unwrap().as_int().unwrap(), 30);
1358 }
1359
1360 #[test]
1361 fn test_json_roundtrip_null() {
1362 let original = Value::null();
1363 let json = original.to_json();
1364 let restored = Value::from_json(json);
1365 assert!(restored.is_null());
1366 }
1367
1368 #[test]
1371 fn test_as_timestamp_from_timestamp() {
1372 let v = decode_value(&json!("2024-01-15T10:30:00Z"), "TIMESTAMP").unwrap();
1373 let ts = v.as_timestamp().unwrap();
1374 assert_eq!(ts.year(), 2024);
1375 assert_eq!(ts.month(), 1);
1376 assert_eq!(ts.day(), 15);
1377 }
1378
1379 #[test]
1380 fn test_as_timestamp_from_timestamptz() {
1381 let v = decode_value(&json!("2024-01-15T10:30:00Z"), "TIMESTAMPTZ").unwrap();
1382 let ts = v.as_timestamp().unwrap();
1383 assert!(ts.hour() == 10);
1384 }
1385}