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