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