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 to_proto_string(&self) -> String {
342 match self.kind {
343 ValueKind::Null => String::new(),
344 ValueKind::Int => self.int_value.to_string(),
345 ValueKind::Bool => self.bool_value.to_string(),
346 ValueKind::String
347 | ValueKind::Xml
348 | ValueKind::Json
349 | ValueKind::Jsonb
350 | ValueKind::Url
351 | ValueKind::Domain
352 | ValueKind::Uuid
353 | ValueKind::Enum
354 | ValueKind::BitString => self.string_value.clone(),
355 ValueKind::Decimal => self
356 .decimal_value
357 .map(|d| d.to_string())
358 .unwrap_or_default(),
359 ValueKind::Array => serde_json::to_string(&self.to_json()).unwrap_or_default(),
360 ValueKind::Object => serde_json::to_string(&self.to_json()).unwrap_or_default(),
361 ValueKind::Bytea => {
362 if self.bytes_value.is_empty() {
363 self.string_value.clone()
364 } else {
365 format!("\\x{}", hex::encode(&self.bytes_value))
366 }
367 }
368 ValueKind::Date
369 | ValueKind::Time
370 | ValueKind::TimeTz
371 | ValueKind::Timestamp
372 | ValueKind::TimestampTz
373 | ValueKind::Interval => self.string_value.clone(),
374 ValueKind::Range => serde_json::to_string(&self.to_json()).unwrap_or_default(),
375 }
376 }
377
378 pub fn from_json(json: serde_json::Value) -> Self {
380 match json {
381 serde_json::Value::Null => Self::null(),
382 serde_json::Value::Bool(b) => Self::bool(b),
383 serde_json::Value::Number(n) => {
384 if let Some(i) = n.as_i64() {
385 Self::int(i)
386 } else if let Some(f) = n.as_f64() {
387 Self::string(f.to_string())
389 } else {
390 Self::null()
391 }
392 }
393 serde_json::Value::String(s) => Self::string(s),
394 serde_json::Value::Array(arr) => {
395 let values: Vec<Value> = arr.into_iter().map(Self::from_json).collect();
396 Self::array(values)
397 }
398 serde_json::Value::Object(obj) => {
399 let mut map = HashMap::new();
400 for (k, v) in obj {
401 map.insert(k, Self::from_json(v));
402 }
403 Self::object(map)
404 }
405 }
406 }
407}
408
409pub fn decode_value(raw: &serde_json::Value, type_name: &str) -> Result<Value> {
411 if raw.is_null() {
412 return Ok(Value::null());
413 }
414
415 let type_upper = type_name.to_uppercase();
416
417 match type_upper.as_str() {
418 "INT" => {
419 if let Some(n) = raw.as_i64() {
420 Ok(Value::int(n))
421 } else if let Some(s) = raw.as_str() {
422 if let Ok(n) = s.parse::<i64>() {
423 Ok(Value::int(n))
424 } else {
425 Ok(Value::string(s))
426 }
427 } else {
428 Ok(Value::string(raw.to_string()))
429 }
430 }
431 "DECIMAL" => {
432 let s = raw
433 .as_str()
434 .map(|v| v.to_string())
435 .unwrap_or_else(|| raw.to_string());
436 if let Ok(dec) = s.parse::<Decimal>() {
437 Ok(Value::decimal(dec))
438 } else {
439 Ok(Value::string(s))
440 }
441 }
442 "BOOL" => {
443 if let Some(b) = raw.as_bool() {
444 Ok(Value::bool(b))
445 } else if let Some(s) = raw.as_str() {
446 let lower = s.to_ascii_lowercase();
447 if lower == "true" {
448 Ok(Value::bool(true))
449 } else if lower == "false" {
450 Ok(Value::bool(false))
451 } else {
452 Ok(Value::string(s))
453 }
454 } else {
455 Ok(Value::string(raw.to_string()))
456 }
457 }
458 "STRING" => Ok(Value::string(raw.as_str().unwrap_or(""))),
459 "BYTEA" => {
460 let s = raw.as_str().unwrap_or("");
461 let bytes = if let Some(hex_str) = s.strip_prefix("\\x") {
462 hex::decode(hex_str).unwrap_or_default()
463 } else {
464 Vec::new()
465 };
466 Ok(Value {
467 kind: ValueKind::Bytea,
468 bytes_value: bytes,
469 string_value: s.to_string(),
470 ..Value::null()
471 })
472 }
473 "JSON" => Ok(Value {
474 kind: ValueKind::Json,
475 string_value: raw.to_string(),
476 ..Value::null()
477 }),
478 "JSONB" => Ok(Value {
479 kind: ValueKind::Jsonb,
480 string_value: raw.to_string(),
481 ..Value::null()
482 }),
483 "DATE" => {
484 let s = raw.as_str().unwrap_or("");
485 let date = NaiveDate::parse_from_str(s, "%Y-%m-%d").ok();
486 Ok(Value {
487 kind: ValueKind::Date,
488 string_value: s.to_string(),
489 date_value: date,
490 ..Value::null()
491 })
492 }
493 "TIMESTAMP" | "TIMESTAMPTZ" => {
494 let s = raw.as_str().unwrap_or("");
495 let timestamp = DateTime::parse_from_rfc3339(s)
496 .ok()
497 .map(|dt| dt.with_timezone(&Utc));
498 let kind = if type_upper == "TIMESTAMPTZ" {
499 ValueKind::TimestampTz
500 } else {
501 ValueKind::Timestamp
502 };
503 Ok(Value {
504 kind,
505 string_value: s.to_string(),
506 timestamp_value: timestamp,
507 ..Value::null()
508 })
509 }
510 _ if type_upper.contains("RANGE") => {
511 if let Some(obj) = raw.as_object() {
512 let range = Range {
513 lower: obj
514 .get("lower")
515 .and_then(|v| decode_value(v, "").ok().map(Box::new)),
516 upper: obj
517 .get("upper")
518 .and_then(|v| decode_value(v, "").ok().map(Box::new)),
519 bounds: obj
520 .get("bounds")
521 .and_then(|v| v.as_str())
522 .unwrap_or("")
523 .to_string(),
524 };
525 Ok(Value {
526 kind: ValueKind::Range,
527 range_value: Some(range),
528 ..Value::null()
529 })
530 } else {
531 Ok(Value::string(raw.to_string()))
532 }
533 }
534 _ => {
535 if let Some(arr) = raw.as_array() {
537 let values: Result<Vec<_>> = arr.iter().map(|v| decode_value(v, "")).collect();
538 Ok(Value::array(values?))
539 } else if let Some(obj) = raw.as_object() {
540 let mut map = HashMap::new();
541 for (k, v) in obj {
542 map.insert(k.clone(), decode_value(v, "")?);
543 }
544 Ok(Value::object(map))
545 } else if let Some(b) = raw.as_bool() {
546 Ok(Value::bool(b))
547 } else if let Some(n) = raw.as_i64() {
548 Ok(Value::int(n))
549 } else if let Some(f) = raw.as_f64() {
550 let s = f.to_string();
551 if let Ok(dec) = s.parse::<Decimal>() {
552 Ok(Value::decimal(dec))
553 } else {
554 Ok(Value::string(s))
555 }
556 } else if let Some(s) = raw.as_str() {
557 Ok(Value::string(s))
558 } else {
559 Ok(Value::string(raw.to_string()))
560 }
561 }
562 }
563}
564
565#[cfg(test)]
566mod tests {
567 use super::*;
568 use chrono::{Datelike, Timelike};
569 use rust_decimal_macros::dec;
570 use serde_json::json;
571
572 #[test]
575 fn test_value_kind_equality() {
576 assert_eq!(ValueKind::Null, ValueKind::Null);
577 assert_eq!(ValueKind::Int, ValueKind::Int);
578 assert_ne!(ValueKind::Int, ValueKind::String);
579 }
580
581 #[test]
582 fn test_value_kind_copy() {
583 let kind = ValueKind::Int;
584 let kind_copy = kind;
585 assert_eq!(kind, kind_copy);
586 }
587
588 #[test]
589 fn test_value_kind_debug() {
590 let debug_str = format!("{:?}", ValueKind::Timestamp);
591 assert_eq!(debug_str, "Timestamp");
592 }
593
594 #[test]
595 fn test_value_kind_all_variants() {
596 let variants = [
598 ValueKind::Null,
599 ValueKind::Int,
600 ValueKind::Bool,
601 ValueKind::String,
602 ValueKind::Decimal,
603 ValueKind::Array,
604 ValueKind::Object,
605 ValueKind::Bytea,
606 ValueKind::Date,
607 ValueKind::Time,
608 ValueKind::TimeTz,
609 ValueKind::Timestamp,
610 ValueKind::TimestampTz,
611 ValueKind::Interval,
612 ValueKind::Json,
613 ValueKind::Jsonb,
614 ValueKind::Xml,
615 ValueKind::Url,
616 ValueKind::Domain,
617 ValueKind::Uuid,
618 ValueKind::Enum,
619 ValueKind::BitString,
620 ValueKind::Range,
621 ];
622 assert_eq!(variants.len(), 23);
623 for i in 0..variants.len() {
625 for j in (i + 1)..variants.len() {
626 assert_ne!(variants[i], variants[j]);
627 }
628 }
629 }
630
631 #[test]
634 fn test_value_null() {
635 let v = Value::null();
636 assert_eq!(v.kind, ValueKind::Null);
637 assert!(v.is_null());
638 }
639
640 #[test]
641 fn test_value_int() {
642 let v = Value::int(42);
643 assert_eq!(v.kind, ValueKind::Int);
644 assert!(!v.is_null());
645 assert_eq!(v.as_int().unwrap(), 42);
646 }
647
648 #[test]
649 fn test_value_int_negative() {
650 let v = Value::int(-100);
651 assert_eq!(v.as_int().unwrap(), -100);
652 }
653
654 #[test]
655 fn test_value_int_zero() {
656 let v = Value::int(0);
657 assert_eq!(v.as_int().unwrap(), 0);
658 }
659
660 #[test]
661 fn test_value_int_max() {
662 let v = Value::int(i64::MAX);
663 assert_eq!(v.as_int().unwrap(), i64::MAX);
664 }
665
666 #[test]
667 fn test_value_int_min() {
668 let v = Value::int(i64::MIN);
669 assert_eq!(v.as_int().unwrap(), i64::MIN);
670 }
671
672 #[test]
673 fn test_value_bool_true() {
674 let v = Value::bool(true);
675 assert_eq!(v.kind, ValueKind::Bool);
676 assert!(v.as_bool().unwrap());
677 }
678
679 #[test]
680 fn test_value_bool_false() {
681 let v = Value::bool(false);
682 assert!(!v.as_bool().unwrap());
683 }
684
685 #[test]
686 fn test_value_string() {
687 let v = Value::string("hello");
688 assert_eq!(v.kind, ValueKind::String);
689 assert_eq!(v.as_string().unwrap(), "hello");
690 }
691
692 #[test]
693 fn test_value_string_empty() {
694 let v = Value::string("");
695 assert_eq!(v.as_string().unwrap(), "");
696 }
697
698 #[test]
699 fn test_value_string_unicode() {
700 let v = Value::string("こんにちは世界🌍");
701 assert_eq!(v.as_string().unwrap(), "こんにちは世界🌍");
702 }
703
704 #[test]
705 fn test_value_string_owned() {
706 let owned = String::from("owned string");
707 let v = Value::string(owned);
708 assert_eq!(v.as_string().unwrap(), "owned string");
709 }
710
711 #[test]
712 fn test_value_decimal() {
713 let v = Value::decimal(dec!(123.456));
714 assert_eq!(v.kind, ValueKind::Decimal);
715 assert_eq!(v.as_decimal().unwrap(), dec!(123.456));
716 }
717
718 #[test]
719 fn test_value_decimal_precision() {
720 let v = Value::decimal(dec!(0.000000001));
721 assert_eq!(v.as_decimal().unwrap(), dec!(0.000000001));
722 }
723
724 #[test]
725 fn test_value_decimal_large() {
726 let v = Value::decimal(dec!(99999999999999.99));
727 assert_eq!(v.as_decimal().unwrap(), dec!(99999999999999.99));
728 }
729
730 #[test]
731 fn test_value_array_empty() {
732 let v = Value::array(vec![]);
733 assert_eq!(v.kind, ValueKind::Array);
734 assert!(v.as_array().unwrap().is_empty());
735 }
736
737 #[test]
738 fn test_value_array() {
739 let v = Value::array(vec![Value::int(1), Value::int(2), Value::int(3)]);
740 let arr = v.as_array().unwrap();
741 assert_eq!(arr.len(), 3);
742 assert_eq!(arr[0].as_int().unwrap(), 1);
743 assert_eq!(arr[1].as_int().unwrap(), 2);
744 assert_eq!(arr[2].as_int().unwrap(), 3);
745 }
746
747 #[test]
748 fn test_value_array_mixed() {
749 let v = Value::array(vec![
750 Value::int(42),
751 Value::string("hello"),
752 Value::bool(true),
753 Value::null(),
754 ]);
755 let arr = v.as_array().unwrap();
756 assert_eq!(arr[0].as_int().unwrap(), 42);
757 assert_eq!(arr[1].as_string().unwrap(), "hello");
758 assert!(arr[2].as_bool().unwrap());
759 assert!(arr[3].is_null());
760 }
761
762 #[test]
763 fn test_value_array_nested() {
764 let inner = Value::array(vec![Value::int(1), Value::int(2)]);
765 let outer = Value::array(vec![inner]);
766 let arr = outer.as_array().unwrap();
767 let inner_arr = arr[0].as_array().unwrap();
768 assert_eq!(inner_arr.len(), 2);
769 }
770
771 #[test]
772 fn test_value_object_empty() {
773 let v = Value::object(HashMap::new());
774 assert_eq!(v.kind, ValueKind::Object);
775 assert!(v.as_object().unwrap().is_empty());
776 }
777
778 #[test]
779 fn test_value_object() {
780 let mut map = HashMap::new();
781 map.insert("name".to_string(), Value::string("Alice"));
782 map.insert("age".to_string(), Value::int(30));
783 let v = Value::object(map);
784
785 let obj = v.as_object().unwrap();
786 assert_eq!(obj.get("name").unwrap().as_string().unwrap(), "Alice");
787 assert_eq!(obj.get("age").unwrap().as_int().unwrap(), 30);
788 }
789
790 #[test]
791 fn test_value_object_nested() {
792 let mut inner = HashMap::new();
793 inner.insert("city".to_string(), Value::string("NYC"));
794
795 let mut outer = HashMap::new();
796 outer.insert("address".to_string(), Value::object(inner));
797
798 let v = Value::object(outer);
799 let obj = v.as_object().unwrap();
800 let addr = obj.get("address").unwrap().as_object().unwrap();
801 assert_eq!(addr.get("city").unwrap().as_string().unwrap(), "NYC");
802 }
803
804 #[test]
807 fn test_as_int_wrong_type() {
808 let v = Value::string("not an int");
809 let result = v.as_int();
810 assert!(result.is_err());
811 assert!(result.unwrap_err().to_string().contains("String"));
812 }
813
814 #[test]
815 fn test_as_bool_wrong_type() {
816 let v = Value::int(42);
817 let result = v.as_bool();
818 assert!(result.is_err());
819 }
820
821 #[test]
822 fn test_as_string_wrong_type() {
823 let v = Value::int(42);
824 let result = v.as_string();
825 assert!(result.is_err());
826 }
827
828 #[test]
829 fn test_as_decimal_wrong_type() {
830 let v = Value::int(42);
831 let result = v.as_decimal();
832 assert!(result.is_err());
833 }
834
835 #[test]
836 fn test_as_array_wrong_type() {
837 let v = Value::int(42);
838 let result = v.as_array();
839 assert!(result.is_err());
840 }
841
842 #[test]
843 fn test_as_object_wrong_type() {
844 let v = Value::int(42);
845 let result = v.as_object();
846 assert!(result.is_err());
847 }
848
849 #[test]
850 fn test_as_bytes_wrong_type() {
851 let v = Value::int(42);
852 let result = v.as_bytes();
853 assert!(result.is_err());
854 }
855
856 #[test]
857 fn test_as_date_wrong_type() {
858 let v = Value::int(42);
859 let result = v.as_date();
860 assert!(result.is_err());
861 }
862
863 #[test]
864 fn test_as_timestamp_wrong_type() {
865 let v = Value::int(42);
866 let result = v.as_timestamp();
867 assert!(result.is_err());
868 }
869
870 #[test]
871 fn test_as_range_wrong_type() {
872 let v = Value::int(42);
873 let result = v.as_range();
874 assert!(result.is_err());
875 }
876
877 #[test]
880 fn test_as_string_from_xml() {
881 let v = Value {
882 kind: ValueKind::Xml,
883 string_value: "<root/>".to_string(),
884 ..Value::null()
885 };
886 assert_eq!(v.as_string().unwrap(), "<root/>");
887 }
888
889 #[test]
890 fn test_as_string_from_json() {
891 let v = Value {
892 kind: ValueKind::Json,
893 string_value: r#"{"key":"value"}"#.to_string(),
894 ..Value::null()
895 };
896 assert_eq!(v.as_string().unwrap(), r#"{"key":"value"}"#);
897 }
898
899 #[test]
900 fn test_as_string_from_url() {
901 let v = Value {
902 kind: ValueKind::Url,
903 string_value: "https://example.com".to_string(),
904 ..Value::null()
905 };
906 assert_eq!(v.as_string().unwrap(), "https://example.com");
907 }
908
909 #[test]
910 fn test_as_string_from_uuid() {
911 let v = Value {
912 kind: ValueKind::Uuid,
913 string_value: "550e8400-e29b-41d4-a716-446655440000".to_string(),
914 ..Value::null()
915 };
916 assert_eq!(
917 v.as_string().unwrap(),
918 "550e8400-e29b-41d4-a716-446655440000"
919 );
920 }
921
922 #[test]
925 fn test_to_json_null() {
926 let v = Value::null();
927 assert_eq!(v.to_json(), json!(null));
928 }
929
930 #[test]
931 fn test_to_json_int() {
932 let v = Value::int(42);
933 assert_eq!(v.to_json(), json!(42));
934 }
935
936 #[test]
937 fn test_to_json_bool() {
938 let v = Value::bool(true);
939 assert_eq!(v.to_json(), json!(true));
940 }
941
942 #[test]
943 fn test_to_json_string() {
944 let v = Value::string("hello");
945 assert_eq!(v.to_json(), json!("hello"));
946 }
947
948 #[test]
949 fn test_to_json_decimal() {
950 let v = Value::decimal(dec!(123.45));
951 assert_eq!(v.to_json(), json!("123.45"));
952 }
953
954 #[test]
955 fn test_to_json_array() {
956 let v = Value::array(vec![Value::int(1), Value::int(2)]);
957 assert_eq!(v.to_json(), json!([1, 2]));
958 }
959
960 #[test]
961 fn test_to_json_object() {
962 let mut map = HashMap::new();
963 map.insert("key".to_string(), Value::string("value"));
964 let v = Value::object(map);
965 assert_eq!(v.to_json(), json!({"key": "value"}));
966 }
967
968 #[test]
969 fn test_to_json_bytea_empty() {
970 let v = Value {
971 kind: ValueKind::Bytea,
972 bytes_value: vec![],
973 string_value: "".to_string(),
974 ..Value::null()
975 };
976 assert_eq!(v.to_json(), json!(""));
977 }
978
979 #[test]
980 fn test_to_json_bytea_with_data() {
981 let v = Value {
982 kind: ValueKind::Bytea,
983 bytes_value: vec![0xDE, 0xAD, 0xBE, 0xEF],
984 ..Value::null()
985 };
986 assert_eq!(v.to_json(), json!("\\xdeadbeef"));
987 }
988
989 #[test]
990 fn test_to_json_range() {
991 let range = Range {
992 lower: Some(Box::new(Value::int(1))),
993 upper: Some(Box::new(Value::int(10))),
994 bounds: "[)".to_string(),
995 };
996 let v = Value {
997 kind: ValueKind::Range,
998 range_value: Some(range),
999 ..Value::null()
1000 };
1001 let j = v.to_json();
1002 assert_eq!(j["lower"], json!(1));
1003 assert_eq!(j["upper"], json!(10));
1004 assert_eq!(j["bounds"], json!("[)"));
1005 }
1006
1007 #[test]
1008 fn test_to_json_range_none() {
1009 let v = Value {
1010 kind: ValueKind::Range,
1011 range_value: None,
1012 ..Value::null()
1013 };
1014 assert_eq!(v.to_json(), json!(null));
1015 }
1016
1017 #[test]
1020 fn test_from_json_null() {
1021 let v = Value::from_json(json!(null));
1022 assert!(v.is_null());
1023 }
1024
1025 #[test]
1026 fn test_from_json_bool() {
1027 let v = Value::from_json(json!(true));
1028 assert!(v.as_bool().unwrap());
1029 }
1030
1031 #[test]
1032 fn test_from_json_int() {
1033 let v = Value::from_json(json!(42));
1034 assert_eq!(v.as_int().unwrap(), 42);
1035 }
1036
1037 #[test]
1038 fn test_from_json_float() {
1039 let v = Value::from_json(json!(1.5));
1040 assert_eq!(v.kind, ValueKind::String);
1042 }
1043
1044 #[test]
1045 fn test_from_json_string() {
1046 let v = Value::from_json(json!("hello"));
1047 assert_eq!(v.as_string().unwrap(), "hello");
1048 }
1049
1050 #[test]
1051 fn test_from_json_array() {
1052 let v = Value::from_json(json!([1, 2, 3]));
1053 let arr = v.as_array().unwrap();
1054 assert_eq!(arr.len(), 3);
1055 }
1056
1057 #[test]
1058 fn test_from_json_object() {
1059 let v = Value::from_json(json!({"name": "Alice"}));
1060 let obj = v.as_object().unwrap();
1061 assert_eq!(obj.get("name").unwrap().as_string().unwrap(), "Alice");
1062 }
1063
1064 #[test]
1065 fn test_from_json_nested() {
1066 let v = Value::from_json(json!({
1067 "users": [
1068 {"name": "Alice", "age": 30},
1069 {"name": "Bob", "age": 25}
1070 ]
1071 }));
1072 let obj = v.as_object().unwrap();
1073 let users = obj.get("users").unwrap().as_array().unwrap();
1074 assert_eq!(users.len(), 2);
1075 }
1076
1077 #[test]
1080 fn test_decode_value_null() {
1081 let v = decode_value(&json!(null), "INT").unwrap();
1082 assert!(v.is_null());
1083 }
1084
1085 #[test]
1086 fn test_decode_value_int_from_number() {
1087 let v = decode_value(&json!(42), "INT").unwrap();
1088 assert_eq!(v.as_int().unwrap(), 42);
1089 }
1090
1091 #[test]
1092 fn test_decode_value_int_from_string() {
1093 let v = decode_value(&json!("123"), "INT").unwrap();
1094 assert_eq!(v.as_int().unwrap(), 123);
1095 }
1096
1097 #[test]
1098 fn test_decode_value_int_invalid_string() {
1099 let v = decode_value(&json!("not_a_number"), "INT").unwrap();
1100 assert_eq!(v.kind, ValueKind::String);
1102 }
1103
1104 #[test]
1105 fn test_decode_value_decimal() {
1106 let v = decode_value(&json!("123.456"), "DECIMAL").unwrap();
1107 assert_eq!(v.as_decimal().unwrap(), dec!(123.456));
1108 }
1109
1110 #[test]
1111 fn test_decode_value_decimal_from_number() {
1112 let v = decode_value(&json!(123), "DECIMAL").unwrap();
1113 assert_eq!(v.as_decimal().unwrap(), dec!(123));
1114 }
1115
1116 #[test]
1117 fn test_decode_value_bool_true() {
1118 let v = decode_value(&json!(true), "BOOL").unwrap();
1119 assert!(v.as_bool().unwrap());
1120 }
1121
1122 #[test]
1123 fn test_decode_value_bool_false() {
1124 let v = decode_value(&json!(false), "BOOL").unwrap();
1125 assert!(!v.as_bool().unwrap());
1126 }
1127
1128 #[test]
1129 fn test_decode_value_bool_from_string_true() {
1130 let v = decode_value(&json!("true"), "BOOL").unwrap();
1131 assert!(v.as_bool().unwrap());
1132 }
1133
1134 #[test]
1135 fn test_decode_value_bool_from_string_false() {
1136 let v = decode_value(&json!("false"), "BOOL").unwrap();
1137 assert!(!v.as_bool().unwrap());
1138 }
1139
1140 #[test]
1141 fn test_decode_value_bool_from_string_case_insensitive() {
1142 let v = decode_value(&json!("TRUE"), "BOOL").unwrap();
1143 assert!(v.as_bool().unwrap());
1144 }
1145
1146 #[test]
1147 fn test_decode_value_string() {
1148 let v = decode_value(&json!("hello"), "STRING").unwrap();
1149 assert_eq!(v.as_string().unwrap(), "hello");
1150 }
1151
1152 #[test]
1153 fn test_decode_value_bytea() {
1154 let v = decode_value(&json!("\\xDEADBEEF"), "BYTEA").unwrap();
1155 assert_eq!(v.kind, ValueKind::Bytea);
1156 assert_eq!(v.as_bytes().unwrap(), &[0xDE, 0xAD, 0xBE, 0xEF]);
1157 }
1158
1159 #[test]
1160 fn test_decode_value_bytea_no_prefix() {
1161 let v = decode_value(&json!("plain"), "BYTEA").unwrap();
1162 assert_eq!(v.kind, ValueKind::Bytea);
1163 assert!(v.as_bytes().unwrap().is_empty());
1164 }
1165
1166 #[test]
1167 fn test_decode_value_json() {
1168 let v = decode_value(&json!({"key": "value"}), "JSON").unwrap();
1169 assert_eq!(v.kind, ValueKind::Json);
1170 }
1171
1172 #[test]
1173 fn test_decode_value_jsonb() {
1174 let v = decode_value(&json!({"key": "value"}), "JSONB").unwrap();
1175 assert_eq!(v.kind, ValueKind::Jsonb);
1176 }
1177
1178 #[test]
1179 fn test_decode_value_date() {
1180 let v = decode_value(&json!("2024-01-15"), "DATE").unwrap();
1181 assert_eq!(v.kind, ValueKind::Date);
1182 let date = v.as_date().unwrap();
1183 assert_eq!(date.to_string(), "2024-01-15");
1184 }
1185
1186 #[test]
1187 fn test_decode_value_date_invalid() {
1188 let v = decode_value(&json!("not-a-date"), "DATE").unwrap();
1189 assert_eq!(v.kind, ValueKind::Date);
1190 assert!(v.date_value.is_none());
1192 }
1193
1194 #[test]
1195 fn test_decode_value_timestamp() {
1196 let v = decode_value(&json!("2024-01-15T10:30:00Z"), "TIMESTAMP").unwrap();
1197 assert_eq!(v.kind, ValueKind::Timestamp);
1198 let ts = v.as_timestamp().unwrap();
1199 assert_eq!(ts.to_rfc3339(), "2024-01-15T10:30:00+00:00");
1200 }
1201
1202 #[test]
1203 fn test_decode_value_timestamptz() {
1204 let v = decode_value(&json!("2024-01-15T10:30:00+05:00"), "TIMESTAMPTZ").unwrap();
1205 assert_eq!(v.kind, ValueKind::TimestampTz);
1206 }
1207
1208 #[test]
1209 fn test_decode_value_range() {
1210 let v = decode_value(
1211 &json!({"lower": 1, "upper": 10, "bounds": "[)"}),
1212 "INT4RANGE",
1213 )
1214 .unwrap();
1215 assert_eq!(v.kind, ValueKind::Range);
1216 let range = v.as_range().unwrap();
1217 assert_eq!(range.bounds, "[)");
1218 }
1219
1220 #[test]
1221 fn test_decode_value_array_generic() {
1222 let v = decode_value(&json!([1, 2, 3]), "").unwrap();
1223 assert_eq!(v.kind, ValueKind::Array);
1224 assert_eq!(v.as_array().unwrap().len(), 3);
1225 }
1226
1227 #[test]
1228 fn test_decode_value_object_generic() {
1229 let v = decode_value(&json!({"key": "value"}), "").unwrap();
1230 assert_eq!(v.kind, ValueKind::Object);
1231 }
1232
1233 #[test]
1234 fn test_decode_value_generic_bool() {
1235 let v = decode_value(&json!(true), "UNKNOWN").unwrap();
1236 assert!(v.as_bool().unwrap());
1237 }
1238
1239 #[test]
1240 fn test_decode_value_generic_int() {
1241 let v = decode_value(&json!(42), "UNKNOWN").unwrap();
1242 assert_eq!(v.as_int().unwrap(), 42);
1243 }
1244
1245 #[test]
1246 fn test_decode_value_generic_float() {
1247 let v = decode_value(&json!(1.23), "UNKNOWN").unwrap();
1248 assert_eq!(v.kind, ValueKind::Decimal);
1250 }
1251
1252 #[test]
1253 fn test_decode_value_generic_string() {
1254 let v = decode_value(&json!("hello"), "UNKNOWN").unwrap();
1255 assert_eq!(v.as_string().unwrap(), "hello");
1256 }
1257
1258 #[test]
1259 fn test_decode_value_case_insensitive() {
1260 let v1 = decode_value(&json!(42), "int").unwrap();
1261 let v2 = decode_value(&json!(42), "INT").unwrap();
1262 let v3 = decode_value(&json!(42), "Int").unwrap();
1263 assert_eq!(v1.as_int().unwrap(), 42);
1264 assert_eq!(v2.as_int().unwrap(), 42);
1265 assert_eq!(v3.as_int().unwrap(), 42);
1266 }
1267
1268 #[test]
1271 fn test_range_construction() {
1272 let range = Range {
1273 lower: Some(Box::new(Value::int(0))),
1274 upper: Some(Box::new(Value::int(100))),
1275 bounds: "[)".to_string(),
1276 };
1277 assert_eq!(range.lower.as_ref().unwrap().as_int().unwrap(), 0);
1278 assert_eq!(range.upper.as_ref().unwrap().as_int().unwrap(), 100);
1279 assert_eq!(range.bounds, "[)");
1280 }
1281
1282 #[test]
1283 fn test_range_unbounded_lower() {
1284 let range = Range {
1285 lower: None,
1286 upper: Some(Box::new(Value::int(100))),
1287 bounds: "(]".to_string(),
1288 };
1289 assert!(range.lower.is_none());
1290 assert!(range.upper.is_some());
1291 }
1292
1293 #[test]
1294 fn test_range_unbounded_upper() {
1295 let range = Range {
1296 lower: Some(Box::new(Value::int(0))),
1297 upper: None,
1298 bounds: "[)".to_string(),
1299 };
1300 assert!(range.lower.is_some());
1301 assert!(range.upper.is_none());
1302 }
1303
1304 #[test]
1305 fn test_range_clone() {
1306 let range = Range {
1307 lower: Some(Box::new(Value::int(1))),
1308 upper: Some(Box::new(Value::int(10))),
1309 bounds: "[]".to_string(),
1310 };
1311 let cloned = range.clone();
1312 assert_eq!(cloned.bounds, "[]");
1313 }
1314
1315 #[test]
1318 fn test_value_clone() {
1319 let v = Value::string("test");
1320 let cloned = v.clone();
1321 assert_eq!(cloned.as_string().unwrap(), "test");
1322 }
1323
1324 #[test]
1325 fn test_value_clone_array() {
1326 let v = Value::array(vec![Value::int(1), Value::int(2)]);
1327 let cloned = v.clone();
1328 assert_eq!(cloned.as_array().unwrap().len(), 2);
1329 }
1330
1331 #[test]
1332 fn test_value_clone_object() {
1333 let mut map = HashMap::new();
1334 map.insert("key".to_string(), Value::string("value"));
1335 let v = Value::object(map);
1336 let cloned = v.clone();
1337 assert_eq!(
1338 cloned
1339 .as_object()
1340 .unwrap()
1341 .get("key")
1342 .unwrap()
1343 .as_string()
1344 .unwrap(),
1345 "value"
1346 );
1347 }
1348
1349 #[test]
1352 fn test_json_roundtrip_int() {
1353 let original = Value::int(42);
1354 let json = original.to_json();
1355 let restored = Value::from_json(json);
1356 assert_eq!(restored.as_int().unwrap(), 42);
1357 }
1358
1359 #[test]
1360 fn test_json_roundtrip_string() {
1361 let original = Value::string("hello world");
1362 let json = original.to_json();
1363 let restored = Value::from_json(json);
1364 assert_eq!(restored.as_string().unwrap(), "hello world");
1365 }
1366
1367 #[test]
1368 fn test_json_roundtrip_bool() {
1369 let original = Value::bool(true);
1370 let json = original.to_json();
1371 let restored = Value::from_json(json);
1372 assert!(restored.as_bool().unwrap());
1373 }
1374
1375 #[test]
1376 fn test_json_roundtrip_array() {
1377 let original = Value::array(vec![Value::int(1), Value::string("two")]);
1378 let json = original.to_json();
1379 let restored = Value::from_json(json);
1380 let arr = restored.as_array().unwrap();
1381 assert_eq!(arr[0].as_int().unwrap(), 1);
1382 assert_eq!(arr[1].as_string().unwrap(), "two");
1383 }
1384
1385 #[test]
1386 fn test_json_roundtrip_object() {
1387 let mut map = HashMap::new();
1388 map.insert("name".to_string(), Value::string("Alice"));
1389 map.insert("age".to_string(), Value::int(30));
1390 let original = Value::object(map);
1391 let json = original.to_json();
1392 let restored = Value::from_json(json);
1393 let obj = restored.as_object().unwrap();
1394 assert_eq!(obj.get("name").unwrap().as_string().unwrap(), "Alice");
1395 assert_eq!(obj.get("age").unwrap().as_int().unwrap(), 30);
1396 }
1397
1398 #[test]
1399 fn test_json_roundtrip_null() {
1400 let original = Value::null();
1401 let json = original.to_json();
1402 let restored = Value::from_json(json);
1403 assert!(restored.is_null());
1404 }
1405
1406 #[test]
1409 fn test_as_timestamp_from_timestamp() {
1410 let v = decode_value(&json!("2024-01-15T10:30:00Z"), "TIMESTAMP").unwrap();
1411 let ts = v.as_timestamp().unwrap();
1412 assert_eq!(ts.year(), 2024);
1413 assert_eq!(ts.month(), 1);
1414 assert_eq!(ts.day(), 15);
1415 }
1416
1417 #[test]
1418 fn test_as_timestamp_from_timestamptz() {
1419 let v = decode_value(&json!("2024-01-15T10:30:00Z"), "TIMESTAMPTZ").unwrap();
1420 let ts = v.as_timestamp().unwrap();
1421 assert!(ts.hour() == 10);
1422 }
1423}