1pub use crate::types::{Type, TypeCode};
16use crate::value::Kind;
17use crate::value::Value;
18use base64::Engine;
19use base64::prelude::BASE64_STANDARD;
20use rust_decimal::Decimal;
21use serde_json::Value as JsonValue;
22use std::time::SystemTime;
23use time::{Date, OffsetDateTime};
24
25#[derive(thiserror::Error, Debug)]
27#[non_exhaustive]
28pub enum ConvertError {
29 #[error("expected {want:?}, got {got:?}")]
31 KindMismatch {
32 want: Kind,
34 got: Kind,
36 },
37
38 #[error("expected non-null value, got null")]
40 NotNull,
41
42 #[error("cannot convert value, source={0}")]
44 Convert(#[source] BoxedError),
45}
46
47type BoxedError = Box<dyn std::error::Error + Send + Sync>;
48
49pub trait FromValue: Sized {
54 fn from_value(value: &Value, type_: &Type) -> Result<Self, ConvertError>;
63}
64
65impl<T> FromValue for Option<T>
66where
67 T: FromValue,
68{
69 fn from_value(value: &Value, type_: &Type) -> Result<Self, ConvertError> {
70 match &value.0.kind {
71 Some(prost_types::value::Kind::NullValue(_)) => Ok(None),
72 _ => T::from_value(value, type_).map(Some),
73 }
74 }
75}
76
77impl FromValue for Value {
78 fn from_value(value: &Value, _type: &Type) -> Result<Self, ConvertError> {
79 Ok(value.clone())
80 }
81}
82
83impl FromValue for JsonValue {
117 fn from_value(value: &Value, type_: &Type) -> Result<Self, ConvertError> {
118 from_value_recursive(value, Some(type_), 0)
119 }
120}
121
122fn from_value_recursive(
123 value: &Value,
124 type_: Option<&Type>,
125 depth: usize,
126) -> Result<JsonValue, ConvertError> {
127 const MAX_RECURSION_DEPTH: usize = 64;
128 if depth > MAX_RECURSION_DEPTH {
129 return Err(ConvertError::Convert(
130 "maximum nesting depth exceeded".into(),
131 ));
132 }
133
134 match &value.0.kind {
135 Some(prost_types::value::Kind::NullValue(_)) => Ok(JsonValue::Null),
136
137 Some(prost_types::value::Kind::NumberValue(n)) => Ok(serde_json::Number::from_f64(*n)
138 .map(JsonValue::Number)
139 .unwrap_or(JsonValue::Null)),
140
141 Some(prost_types::value::Kind::StringValue(s)) => {
142 let Some(t) = type_ else {
143 return Ok(JsonValue::String(s.clone()));
144 };
145 match t.code() {
146 TypeCode::Json => {
147 serde_json::from_str(s).map_err(|e| ConvertError::Convert(Box::new(e)))
148 }
149 TypeCode::Float64 | TypeCode::Float32 => {
150 if s == "NaN" || s == "Infinity" || s == "-Infinity" {
151 return Ok(JsonValue::Null);
152 }
153 let f = s
154 .parse::<f64>()
155 .map_err(|e| ConvertError::Convert(Box::new(e)))?;
156 Ok(serde_json::Number::from_f64(f)
157 .map(JsonValue::Number)
158 .unwrap_or(JsonValue::Null))
159 }
160 _ => Ok(JsonValue::String(s.clone())),
161 }
162 }
163
164 Some(prost_types::value::Kind::BoolValue(b)) => Ok(JsonValue::Bool(*b)),
165
166 Some(prost_types::value::Kind::StructValue(s)) => struct_value_to_json(s, type_, depth + 1),
167
168 Some(prost_types::value::Kind::ListValue(list)) => {
169 list_value_to_json(list, type_, depth + 1)
170 }
171
172 None => Ok(JsonValue::Null),
173 }
174}
175
176fn struct_value_to_json(
177 s: &prost_types::Struct,
178 type_: Option<&Type>,
179 depth: usize,
180) -> Result<JsonValue, ConvertError> {
181 let s = crate::value::Struct::from_ref(s);
182 let mut map = serde_json::Map::new();
183
184 let Some(struct_type) = type_.and_then(|t| t.struct_type()) else {
185 for (k, v) in s.fields() {
186 map.insert(k.clone(), from_value_recursive(v, None, depth)?);
187 }
188 return Ok(JsonValue::Object(map));
189 };
190
191 for field in &struct_type.fields {
192 let field_type = field.r#type.as_deref().map(Type::from_ref);
193 let value = if let Some(v) = s.get(&field.name) {
194 from_value_recursive(v, field_type, depth)?
195 } else {
196 JsonValue::Null
197 };
198 map.insert(field.name.clone(), value);
199 }
200
201 Ok(JsonValue::Object(map))
202}
203
204fn list_value_to_json(
205 list: &prost_types::ListValue,
206 type_: Option<&Type>,
207 depth: usize,
208) -> Result<JsonValue, ConvertError> {
209 let code = type_.map_or(TypeCode::Unspecified, |t| t.code());
210 match code {
211 TypeCode::Struct => {
212 let Some(struct_type) = type_.and_then(|t| t.struct_type()) else {
213 let mut arr = Vec::with_capacity(list.values.len());
214 for v in &list.values {
215 let val = Value::from_ref(v);
216 arr.push(from_value_recursive(val, None, depth)?);
217 }
218 return Ok(JsonValue::Array(arr));
219 };
220
221 let mut map = serde_json::Map::new();
222 for (i, field) in struct_type.fields.iter().enumerate() {
223 let field_type = field.r#type.as_deref().map(Type::from_ref);
224 let value = if let Some(v) = list.values.get(i) {
225 let val = Value::from_ref(v);
226 from_value_recursive(val, field_type, depth)?
227 } else {
228 JsonValue::Null
229 };
230 map.insert(field.name.clone(), value);
231 }
232 Ok(JsonValue::Object(map))
233 }
234
235 TypeCode::Array => {
236 let element_type = type_.and_then(|t| t.array_element_type());
237 let mut arr = Vec::with_capacity(list.values.len());
238 for v in &list.values {
239 let val = Value::from_ref(v);
240 arr.push(from_value_recursive(val, element_type.as_ref(), depth)?);
241 }
242 Ok(JsonValue::Array(arr))
243 }
244
245 _ => {
246 let mut arr = Vec::with_capacity(list.values.len());
247 for v in &list.values {
248 let val = Value::from_ref(v);
249 arr.push(from_value_recursive(val, None, depth)?);
250 }
251 Ok(JsonValue::Array(arr))
252 }
253 }
254}
255
256impl FromValue for String {
257 fn from_value(value: &Value, _type: &Type) -> Result<Self, ConvertError> {
258 match &value.0.kind {
259 Some(prost_types::value::Kind::StringValue(s)) => Ok(s.clone()),
260 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
261 _ => Err(ConvertError::KindMismatch {
262 want: crate::value::Kind::String,
263 got: value.kind(),
264 }),
265 }
266 }
267}
268
269impl FromValue for i64 {
270 fn from_value(value: &Value, _type: &Type) -> Result<Self, ConvertError> {
271 match &value.0.kind {
272 Some(prost_types::value::Kind::StringValue(s)) => {
273 s.parse().map_err(|e| ConvertError::Convert(Box::new(e)))
274 }
275 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
276 _ => Err(ConvertError::KindMismatch {
277 want: crate::value::Kind::String,
278 got: value.kind(),
279 }),
280 }
281 }
282}
283
284impl FromValue for i32 {
285 fn from_value(value: &Value, _type: &Type) -> Result<Self, ConvertError> {
286 match &value.0.kind {
287 Some(prost_types::value::Kind::StringValue(s)) => {
288 s.parse().map_err(|e| ConvertError::Convert(Box::new(e)))
289 }
290 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
291 _ => Err(ConvertError::KindMismatch {
292 want: crate::value::Kind::String,
293 got: value.kind(),
294 }),
295 }
296 }
297}
298
299impl FromValue for Decimal {
300 fn from_value(value: &Value, type_: &Type) -> Result<Self, ConvertError> {
301 if type_.code() != TypeCode::Numeric {
302 return Err(ConvertError::KindMismatch {
303 want: crate::value::Kind::String,
304 got: value.kind(),
305 });
306 }
307 match &value.0.kind {
308 Some(prost_types::value::Kind::StringValue(s)) => {
309 Decimal::from_str_exact(s).map_err(|e| ConvertError::Convert(Box::new(e)))
310 }
311 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
312 _ => Err(ConvertError::KindMismatch {
313 want: crate::value::Kind::String,
314 got: value.kind(),
315 }),
316 }
317 }
318}
319
320impl FromValue for SystemTime {
321 fn from_value(value: &Value, type_: &Type) -> Result<Self, ConvertError> {
322 if type_.code() != TypeCode::Timestamp {
323 return Err(ConvertError::KindMismatch {
324 want: crate::value::Kind::String,
325 got: value.kind(),
326 });
327 }
328 match &value.0.kind {
329 Some(prost_types::value::Kind::StringValue(s)) => {
330 let dt = OffsetDateTime::parse(s, &time::format_description::well_known::Rfc3339)
331 .map_err(|e| ConvertError::Convert(Box::new(e)))?;
332 Ok(dt.into())
333 }
334 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
335 _ => Err(ConvertError::KindMismatch {
336 want: crate::value::Kind::String,
337 got: value.kind(),
338 }),
339 }
340 }
341}
342
343impl FromValue for OffsetDateTime {
344 fn from_value(value: &Value, type_: &Type) -> Result<Self, ConvertError> {
345 if type_.code() != TypeCode::Timestamp {
346 return Err(ConvertError::KindMismatch {
347 want: crate::value::Kind::String,
348 got: value.kind(),
349 });
350 }
351 match &value.0.kind {
352 Some(prost_types::value::Kind::StringValue(s)) => {
353 let dt = OffsetDateTime::parse(s, &time::format_description::well_known::Rfc3339)
354 .map_err(|e| ConvertError::Convert(Box::new(e)))?;
355 Ok(dt)
356 }
357 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
358 _ => Err(ConvertError::KindMismatch {
359 want: crate::value::Kind::String,
360 got: value.kind(),
361 }),
362 }
363 }
364}
365
366impl FromValue for wkt::Timestamp {
367 fn from_value(value: &Value, type_: &Type) -> Result<Self, ConvertError> {
368 let dt = OffsetDateTime::from_value(value, type_)?;
369 wkt::Timestamp::try_from(dt).map_err(|e| ConvertError::Convert(Box::new(e)))
370 }
371}
372
373impl FromValue for Date {
374 fn from_value(value: &Value, type_: &Type) -> Result<Self, ConvertError> {
375 if type_.code() != TypeCode::Date {
376 return Err(ConvertError::KindMismatch {
377 want: crate::value::Kind::String,
378 got: value.kind(),
379 });
380 }
381 match &value.0.kind {
382 Some(prost_types::value::Kind::StringValue(s)) => {
383 let date = Date::parse(s, crate::value::SPANNER_DATE_FORMAT)
384 .map_err(|e| ConvertError::Convert(Box::new(e)))?;
385 Ok(date)
386 }
387 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
388 _ => Err(ConvertError::KindMismatch {
389 want: crate::value::Kind::String,
390 got: value.kind(),
391 }),
392 }
393 }
394}
395
396impl FromValue for bool {
397 fn from_value(value: &Value, _type: &Type) -> Result<Self, ConvertError> {
398 match &value.0.kind {
399 Some(prost_types::value::Kind::BoolValue(b)) => Ok(*b),
400 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
401 _ => Err(ConvertError::KindMismatch {
402 want: crate::value::Kind::Bool,
403 got: value.kind(),
404 }),
405 }
406 }
407}
408
409impl FromValue for f64 {
410 fn from_value(value: &Value, _type: &Type) -> Result<Self, ConvertError> {
411 match &value.0.kind {
412 Some(prost_types::value::Kind::NumberValue(n)) => Ok(*n),
413 Some(prost_types::value::Kind::StringValue(s)) => {
414 s.parse().map_err(|e| ConvertError::Convert(Box::new(e)))
415 }
416 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
417 _ => Err(ConvertError::KindMismatch {
418 want: crate::value::Kind::Number,
419 got: value.kind(),
420 }),
421 }
422 }
423}
424
425impl FromValue for f32 {
426 fn from_value(value: &Value, _type: &Type) -> Result<Self, ConvertError> {
427 match &value.0.kind {
428 Some(prost_types::value::Kind::NumberValue(n)) => Ok(*n as f32),
429 Some(prost_types::value::Kind::StringValue(s)) => {
430 s.parse().map_err(|e| ConvertError::Convert(Box::new(e)))
431 }
432 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
433 _ => Err(ConvertError::KindMismatch {
434 want: crate::value::Kind::Number,
435 got: value.kind(),
436 }),
437 }
438 }
439}
440
441impl FromValue for Vec<u8> {
442 fn from_value(value: &Value, type_: &Type) -> Result<Self, ConvertError> {
443 if type_.code() != TypeCode::Bytes && type_.code() != TypeCode::Proto {
444 return Err(ConvertError::KindMismatch {
445 want: crate::value::Kind::String,
446 got: value.kind(),
447 });
448 }
449 match &value.0.kind {
450 Some(prost_types::value::Kind::StringValue(s)) => BASE64_STANDARD
451 .decode(s)
452 .map_err(|e| ConvertError::Convert(Box::new(e))),
453 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
454 _ => Err(ConvertError::KindMismatch {
455 want: crate::value::Kind::String,
456 got: value.kind(),
457 }),
458 }
459 }
460}
461
462impl<T> FromValue for Vec<T>
463where
464 T: FromValue,
465{
466 fn from_value(value: &Value, r#type: &Type) -> Result<Self, ConvertError> {
467 if r#type.code() != TypeCode::Array {
468 return Err(ConvertError::KindMismatch {
469 want: crate::value::Kind::List,
470 got: value.kind(),
471 });
472 }
473 let element_type = r#type
474 .array_element_type()
475 .ok_or_else(|| ConvertError::Convert("Array type missing element type".into()))?;
476
477 match &value.0.kind {
478 Some(prost_types::value::Kind::ListValue(list)) => {
479 let mut vec = Vec::with_capacity(list.values.len());
480 for v in &list.values {
481 let val = crate::value::Value::from_ref(v);
484 vec.push(T::from_value(val, &element_type)?);
485 }
486 Ok(vec)
487 }
488 Some(prost_types::value::Kind::NullValue(_)) => Err(ConvertError::NotNull),
489 _ => Err(ConvertError::KindMismatch {
490 want: crate::value::Kind::List,
491 got: value.kind(),
492 }),
493 }
494 }
495}
496
497#[cfg(test)]
498mod tests {
499 use super::*;
500 use crate::generated::gapic_dataplane::model as mdl;
501 use crate::to_value::ToValue;
502 use crate::types;
503 use serde_json::Value as JsonValue;
504
505 #[test]
506 fn test_from_value_string() {
507 let v = "hello".to_value();
508 let s = String::from_value(&v, &types::string()).unwrap();
509 assert_eq!(s, "hello");
510 }
511
512 #[test]
513 fn test_from_value_int() {
514 let v = 42i64.to_value();
515 let i = i64::from_value(&v, &types::int64()).unwrap();
516 assert_eq!(i, 42);
517
518 let v = 42i32.to_value();
519 let i = i32::from_value(&v, &types::int64()).unwrap();
520 assert_eq!(i, 42);
521
522 let v = "not an int".to_value();
524 let err = i64::from_value(&v, &types::int64()).unwrap_err();
525 assert!(format!("{}", err).contains("cannot convert value"));
526
527 let v = "not an int".to_value();
528 let err = i32::from_value(&v, &types::int64()).unwrap_err();
529 assert!(format!("{}", err).contains("cannot convert value"));
530 }
531
532 #[test]
533 fn test_from_value_float() {
534 let v = 42.5f64.to_value();
535 let f = f64::from_value(&v, &types::float64()).unwrap();
536 assert_eq!(f, 42.5);
537
538 let v = "Infinity".to_string().to_value();
539 let f = f64::from_value(&v, &types::float64()).unwrap();
540 assert_eq!(f, f64::INFINITY);
541
542 let v = "invalid float".to_string().to_value();
543 let err = f64::from_value(&v, &types::float64()).unwrap_err();
544 assert!(format!("{}", err).contains("invalid float literal"));
545 }
546
547 #[test]
548 fn test_from_value_bool() {
549 let v = true.to_value();
550 let b = bool::from_value(&v, &types::bool()).unwrap();
551 assert!(b);
552 }
553
554 #[test]
555 fn test_from_value_array() {
556 let str_array = vec!["one".to_string(), "two".to_string()];
558 let v = str_array.to_value();
559 let res = Vec::<String>::from_value(&v, &types::array(types::string()))
560 .expect("parsed string array");
561 assert_eq!(res, str_array);
562
563 let int_array = vec![42i64, 100i64];
565 let v = int_array.to_value();
566 let res =
567 Vec::<i64>::from_value(&v, &types::array(types::int64())).expect("parsed int array");
568 assert_eq!(res, int_array);
569
570 let bool_array = vec![true, false];
572 let v = bool_array.to_value();
573 let res =
574 Vec::<bool>::from_value(&v, &types::array(types::bool())).expect("parsed bool array");
575 assert_eq!(res, bool_array);
576
577 let float_array = vec![9.9f64, -2.5f64];
579 let v = float_array.to_value();
580 let res = Vec::<f64>::from_value(&v, &types::array(types::float64()))
581 .expect("parsed float array");
582 assert_eq!(res, float_array);
583
584 let empty_array: Vec<f64> = vec![];
586 let v = empty_array.to_value();
587 let res = Vec::<f64>::from_value(&v, &types::array(types::float64()))
588 .expect("parsed empty array");
589 assert_eq!(res, empty_array);
590
591 let opt_array: Vec<Option<i64>> = vec![Some(42), None, Some(100)];
593 let v = opt_array.to_value();
594 let res = Vec::<Option<i64>>::from_value(&v, &types::array(types::int64()))
595 .expect("parsed optional array");
596 assert_eq!(res, opt_array);
597
598 let null_array: Option<Vec<i64>> = None;
600 let v = null_array.to_value();
601 let res = Option::<Vec<i64>>::from_value(&v, &types::array(types::int64()))
602 .expect("parsed null array");
603 assert_eq!(res, null_array);
604
605 let err = Vec::<i64>::from_value(&int_array.to_value(), &types::int64()).unwrap_err();
607 assert!(format!("{}", err).contains("expected List"));
608
609 let err = Vec::<i64>::from_value(&str_array.to_value(), &types::array(types::int64()))
611 .unwrap_err();
612 assert!(format!("{}", err).contains("cannot convert value, source="));
613 }
614
615 #[test]
616 fn test_from_value_bytes() {
617 let bytes: Vec<u8> = vec![1, 2, 3];
618 let v = bytes.to_value();
619 let b = Vec::<u8>::from_value(&v, &types::bytes()).unwrap();
620 assert_eq!(b, bytes);
621
622 let v = "invalid base64".to_string().to_value();
623 let err = Vec::<u8>::from_value(&v, &types::bytes()).unwrap_err();
624 assert!(format!("{}", err).contains("cannot convert value"));
625 }
626
627 #[test]
628 fn test_from_value_decimal() {
629 let d = Decimal::from_str_exact("123.456").unwrap();
630 let v = d.to_value();
631 let res = Decimal::from_value(&v, &types::numeric()).unwrap();
632 assert_eq!(res, d);
633
634 let v = "invalid decimal".to_string().to_value();
635 let err = Decimal::from_value(&v, &types::numeric()).unwrap_err();
636 assert!(format!("{}", err).contains("cannot convert value"));
637 }
638
639 #[test]
640 fn test_from_value_date() {
641 let d = Date::from_calendar_date(2023, time::Month::October, 27).unwrap();
642 let v = d.to_value();
643 let res = Date::from_value(&v, &types::date()).unwrap();
644 assert_eq!(res, d);
645
646 let v = "invalid date".to_string().to_value();
647 let err = Date::from_value(&v, &types::date()).unwrap_err();
648 assert!(format!("{}", err).contains("cannot convert value"));
649 }
650
651 #[test]
652 fn test_from_value_timestamp() {
653 let dt = OffsetDateTime::parse(
654 "2023-10-27T10:00:00Z",
655 &time::format_description::well_known::Rfc3339,
656 )
657 .unwrap();
658 let v = dt.to_value();
659 let res = OffsetDateTime::from_value(&v, &types::timestamp()).unwrap();
660 assert_eq!(res, dt);
661
662 let v = "invalid timestamp".to_string().to_value();
663 let err = OffsetDateTime::from_value(&v, &types::timestamp()).unwrap_err();
664 assert!(format!("{}", err).contains("cannot convert value"));
665 }
666
667 #[test]
668 fn test_from_value_null() {
669 let v = Option::<i32>::None.to_value();
670 let res = Option::<i32>::from_value(&v, &types::int64()).unwrap();
671 assert_eq!(res, None);
672
673 let v = Option::<i32>::None.to_value();
674 let err = i32::from_value(&v, &types::int64()).unwrap_err();
675 assert!(format!("{}", err).contains("expected non-null value, got null"));
676 }
677 #[test]
678 fn test_from_value_system_time() {
679 let dt = OffsetDateTime::parse(
680 "2023-10-27T10:00:00Z",
681 &time::format_description::well_known::Rfc3339,
682 )
683 .unwrap();
684 let system_time: SystemTime = dt.into();
685 let v = system_time.to_value();
686 let res = SystemTime::from_value(&v, &types::timestamp()).unwrap();
687 let res_dt: OffsetDateTime = res.into();
688 assert_eq!(res_dt, dt);
689
690 let v = "invalid timestamp".to_string().to_value();
691 let err = SystemTime::from_value(&v, &types::timestamp()).unwrap_err();
692 assert!(format!("{}", err).contains("cannot convert value"));
693 }
694
695 #[test]
696 fn test_from_value_wkt_timestamp() {
697 let dt = OffsetDateTime::parse(
698 "2023-10-27T10:00:00Z",
699 &time::format_description::well_known::Rfc3339,
700 )
701 .expect("valid date time parsing");
702 let wkt_ts = wkt::Timestamp::try_from(dt).expect("valid wkt timestamp conversion");
703 let v = dt.to_value();
704 let res = wkt::Timestamp::from_value(&v, &types::timestamp())
705 .expect("valid wkt timestamp decoding");
706 assert_eq!(res, wkt_ts);
707
708 let v = "invalid timestamp".to_string().to_value();
709 let err = wkt::Timestamp::from_value(&v, &types::timestamp()).unwrap_err();
710 assert!(format!("{}", err).contains("cannot convert value"));
711 }
712
713 #[test]
714 fn test_from_value_type_mismatch() {
715 let v = Decimal::from(42).to_value();
716 let err = Decimal::from_value(&v, &types::int64()).unwrap_err();
717 assert!(format!("{}", err).contains("expected String, got String"));
718
719 let v = SystemTime::now().to_value();
720 let err = SystemTime::from_value(&v, &types::string()).unwrap_err();
721 assert!(format!("{}", err).contains("expected String, got String")); let v = OffsetDateTime::now_utc().to_value();
724 let err = OffsetDateTime::from_value(&v, &types::string()).unwrap_err();
725 assert!(format!("{}", err).contains("expected String, got String"));
726
727 let v = Date::from_calendar_date(2023, time::Month::October, 27)
728 .unwrap()
729 .to_value();
730 let err = Date::from_value(&v, &types::string()).unwrap_err();
731 assert!(format!("{}", err).contains("expected String, got String"));
732
733 let v = vec![1u8].to_value();
734 let err = Vec::<u8>::from_value(&v, &types::string()).unwrap_err();
735 assert!(format!("{}", err).contains("expected String, got String"));
736 }
737
738 #[test]
739 fn test_from_value_wrong_kind() {
740 let v_bool = true.to_value();
741 let err = String::from_value(&v_bool, &types::string()).unwrap_err();
742 assert!(format!("{}", err).contains("expected String, got Bool"));
743
744 let v_string = "hello".to_value();
745 let err = i64::from_value(&v_string, &types::int64()).unwrap_err();
746 assert!(format!("{}", err).contains("cannot convert value"));
747
748 let v_struct = crate::value::Value(prost_types::Value {
749 kind: Some(prost_types::value::Kind::StructValue(
750 prost_types::Struct::default(),
751 )),
752 });
753 let err = i64::from_value(&v_struct, &types::int64()).unwrap_err();
754 assert!(format!("{}", err).contains("expected String, got Struct"));
755
756 let err = f64::from_value(&v_bool, &types::float64()).unwrap_err();
757 assert!(format!("{}", err).contains("expected Number, got Bool"));
758
759 let err = bool::from_value(&v_string, &types::bool()).unwrap_err();
760 assert!(format!("{}", err).contains("expected Bool, got String"));
761 }
762
763 #[test]
764 fn test_from_value_null_errors() {
765 let v_null = Option::<i32>::None.to_value();
766
767 let err = String::from_value(&v_null, &types::string()).unwrap_err();
768 assert!(format!("{}", err).contains("expected non-null value, got null"));
769
770 let err = i64::from_value(&v_null, &types::int64()).unwrap_err();
771 assert!(format!("{}", err).contains("expected non-null value, got null"));
772
773 let err = f64::from_value(&v_null, &types::float64()).unwrap_err();
774 assert!(format!("{}", err).contains("expected non-null value, got null"));
775
776 let err = f32::from_value(&v_null, &types::float32()).unwrap_err();
777 assert!(format!("{}", err).contains("expected non-null value, got null"));
778
779 let err = bool::from_value(&v_null, &types::bool()).unwrap_err();
780 assert!(format!("{}", err).contains("expected non-null value, got null"));
781
782 let err = Decimal::from_value(&v_null, &types::numeric()).unwrap_err();
783 assert!(format!("{}", err).contains("expected non-null value, got null"));
784
785 let err = SystemTime::from_value(&v_null, &types::timestamp()).unwrap_err();
786 assert!(format!("{}", err).contains("expected non-null value, got null"));
787
788 let err = OffsetDateTime::from_value(&v_null, &types::timestamp()).unwrap_err();
789 assert!(format!("{}", err).contains("expected non-null value, got null"));
790
791 let err = Date::from_value(&v_null, &types::date()).unwrap_err();
792 assert!(format!("{}", err).contains("expected non-null value, got null"));
793
794 let err = Vec::<u8>::from_value(&v_null, &types::bytes()).unwrap_err();
795 assert!(format!("{}", err).contains("expected non-null value, got null"));
796 }
797
798 #[test]
799 fn test_from_value_option_missing_kind() {
800 let v = crate::value::Value(prost_types::Value { kind: None });
801 let err = Option::<i32>::from_value(&v, &types::int64()).unwrap_err();
802 assert!(format!("{}", err).contains("expected String, got Null"));
803 }
804
805 #[test]
808 fn test_from_value_json_primitives() {
809 let v = "hello".to_value();
811 let j = JsonValue::from_value(&v, &types::string()).unwrap();
812 assert_eq!(j, JsonValue::String("hello".to_string()));
813
814 let v = 42i64.to_value();
817 let j = JsonValue::from_value(&v, &types::int64()).unwrap();
818 assert_eq!(j, JsonValue::String("42".to_string()));
819
820 let v = true.to_value();
822 let j = JsonValue::from_value(&v, &types::bool()).unwrap();
823 assert_eq!(j, JsonValue::Bool(true));
824
825 let v = 1.5f64.to_value();
827 let j = JsonValue::from_value(&v, &types::float64()).unwrap();
828 assert_eq!(j, serde_json::json!(1.5));
829
830 let v: Option<i64> = None;
832 let j = JsonValue::from_value(&v.to_value(), &types::int64()).unwrap();
833 assert_eq!(j, JsonValue::Null);
834
835 let v = crate::value::Value(prost_types::Value { kind: None });
837 let j = JsonValue::from_value(&v, &types::string()).unwrap();
838 assert_eq!(j, JsonValue::Null);
839 }
840
841 #[test]
842 fn test_from_value_json_string_array() {
843 let str_array = vec!["a".to_string(), "b".to_string()];
844 let v = str_array.to_value();
845 let j = JsonValue::from_value(&v, &types::array(types::string())).unwrap();
846 assert_eq!(j, serde_json::json!(["a", "b"]));
847 }
848
849 #[test]
850 fn test_from_value_json_int_array() {
851 let int_array = vec![10i64, 20i64];
853 let v = int_array.to_value();
854 let j = JsonValue::from_value(&v, &types::array(types::int64())).unwrap();
855 assert_eq!(j, serde_json::json!(["10", "20"]));
856 }
857
858 #[test]
859 fn test_from_value_json_positional_struct() {
860 let struct_type = types::create_type(TypeCode::Struct);
862 let mut inner: mdl::Type = struct_type.0;
863 inner.struct_type = Some(Box::new(mdl::StructType {
864 fields: vec![
865 mdl::struct_type::Field::new()
866 .set_name("name")
867 .set_type(mdl::Type {
868 code: mdl::TypeCode::String,
869 ..Default::default()
870 }),
871 mdl::struct_type::Field::new()
872 .set_name("age")
873 .set_type(mdl::Type {
874 code: mdl::TypeCode::Int64,
875 ..Default::default()
876 }),
877 ],
878 _unknown_fields: Default::default(),
879 }));
880 let spanner_type = Type(inner);
881
882 let v = crate::value::Value(prost_types::Value {
884 kind: Some(prost_types::value::Kind::ListValue(
885 prost_types::ListValue {
886 values: vec![
887 prost_types::Value {
888 kind: Some(prost_types::value::Kind::StringValue("Alice".to_string())),
889 },
890 prost_types::Value {
891 kind: Some(prost_types::value::Kind::StringValue("30".to_string())),
892 },
893 ],
894 },
895 )),
896 });
897
898 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
899 assert_eq!(j, serde_json::json!({"name": "Alice", "age": "30"}));
900 }
901
902 #[test]
903 fn test_from_value_json_array_of_structs() {
904 let elem_struct = mdl::Type {
906 code: mdl::TypeCode::Struct,
907 struct_type: Some(Box::new(mdl::StructType {
908 fields: vec![
909 mdl::struct_type::Field::new()
910 .set_name("a")
911 .set_type(mdl::Type {
912 code: mdl::TypeCode::String,
913 ..Default::default()
914 }),
915 mdl::struct_type::Field::new()
916 .set_name("b")
917 .set_type(mdl::Type {
918 code: mdl::TypeCode::Int64,
919 ..Default::default()
920 }),
921 ],
922 _unknown_fields: Default::default(),
923 })),
924 ..Default::default()
925 };
926 let array_type = mdl::Type {
927 code: mdl::TypeCode::Array,
928 array_element_type: Some(Box::new(elem_struct)),
929 ..Default::default()
930 };
931 let spanner_type = Type(array_type);
932
933 let v = crate::value::Value(prost_types::Value {
935 kind: Some(prost_types::value::Kind::ListValue(
936 prost_types::ListValue {
937 values: vec![
938 prost_types::Value {
939 kind: Some(prost_types::value::Kind::ListValue(
940 prost_types::ListValue {
941 values: vec![
942 prost_types::Value {
943 kind: Some(prost_types::value::Kind::StringValue(
944 "x".to_string(),
945 )),
946 },
947 prost_types::Value {
948 kind: Some(prost_types::value::Kind::StringValue(
949 "1".to_string(),
950 )),
951 },
952 ],
953 },
954 )),
955 },
956 prost_types::Value {
957 kind: Some(prost_types::value::Kind::ListValue(
958 prost_types::ListValue {
959 values: vec![
960 prost_types::Value {
961 kind: Some(prost_types::value::Kind::StringValue(
962 "y".to_string(),
963 )),
964 },
965 prost_types::Value {
966 kind: Some(prost_types::value::Kind::StringValue(
967 "2".to_string(),
968 )),
969 },
970 ],
971 },
972 )),
973 },
974 ],
975 },
976 )),
977 });
978
979 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
980 assert_eq!(
981 j,
982 serde_json::json!([
983 {"a": "x", "b": "1"},
984 {"a": "y", "b": "2"},
985 ])
986 );
987 }
988
989 #[test]
990 fn test_from_value_json_named_struct() {
991 let struct_type_mdl =
993 mdl::Type {
994 code: mdl::TypeCode::Struct,
995 struct_type: Some(Box::new(mdl::StructType {
996 fields: vec![mdl::struct_type::Field::new().set_name("name").set_type(
997 mdl::Type {
998 code: mdl::TypeCode::String,
999 ..Default::default()
1000 },
1001 )],
1002 _unknown_fields: Default::default(),
1003 })),
1004 ..Default::default()
1005 };
1006 let spanner_type = Type(struct_type_mdl);
1007
1008 let mut s = prost_types::Struct::default();
1010 s.fields.insert(
1011 "name".to_string(),
1012 prost_types::Value {
1013 kind: Some(prost_types::value::Kind::StringValue("Alice".to_string())),
1014 },
1015 );
1016 let v = crate::value::Value(prost_types::Value {
1017 kind: Some(prost_types::value::Kind::StructValue(s)),
1018 });
1019
1020 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1021 assert_eq!(j, serde_json::json!({"name": "Alice"}));
1022 }
1023
1024 #[test]
1025 fn test_from_value_json_named_struct_missing_fields_become_null() {
1026 let struct_type_mdl = mdl::Type {
1028 code: mdl::TypeCode::Struct,
1029 struct_type: Some(Box::new(mdl::StructType {
1030 fields: vec![
1031 mdl::struct_type::Field::new()
1032 .set_name("present")
1033 .set_type(mdl::Type {
1034 code: mdl::TypeCode::String,
1035 ..Default::default()
1036 }),
1037 mdl::struct_type::Field::new()
1038 .set_name("absent")
1039 .set_type(mdl::Type {
1040 code: mdl::TypeCode::Int64,
1041 ..Default::default()
1042 }),
1043 ],
1044 _unknown_fields: Default::default(),
1045 })),
1046 ..Default::default()
1047 };
1048 let spanner_type = Type(struct_type_mdl);
1049
1050 let mut s = prost_types::Struct::default();
1052 s.fields.insert(
1053 "present".to_string(),
1054 prost_types::Value {
1055 kind: Some(prost_types::value::Kind::StringValue("here".to_string())),
1056 },
1057 );
1058 let v = crate::value::Value(prost_types::Value {
1059 kind: Some(prost_types::value::Kind::StructValue(s)),
1060 });
1061
1062 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1063 assert_eq!(j, serde_json::json!({"present": "here", "absent": null}));
1064 }
1065
1066 #[test]
1067 fn test_from_value_json_spanner_json_column() {
1068 let json_str = r#"{"key": "value", "nested": [1, 2, 3]}"#;
1070 let v = crate::value::Value(prost_types::Value {
1071 kind: Some(prost_types::value::Kind::StringValue(json_str.to_string())),
1072 });
1073
1074 let j = JsonValue::from_value(&v, &types::json()).unwrap();
1075 assert_eq!(j, serde_json::json!({"key": "value", "nested": [1, 2, 3]}));
1076 }
1077
1078 #[test]
1079 fn test_from_value_json_nested_struct_in_struct() {
1080 let inner_struct_type = mdl::Type {
1082 code: mdl::TypeCode::Struct,
1083 struct_type: Some(Box::new(mdl::StructType {
1084 fields: vec![
1085 mdl::struct_type::Field::new()
1086 .set_name("x")
1087 .set_type(mdl::Type {
1088 code: mdl::TypeCode::Int64,
1089 ..Default::default()
1090 }),
1091 mdl::struct_type::Field::new()
1092 .set_name("y")
1093 .set_type(mdl::Type {
1094 code: mdl::TypeCode::Bool,
1095 ..Default::default()
1096 }),
1097 ],
1098 _unknown_fields: Default::default(),
1099 })),
1100 ..Default::default()
1101 };
1102
1103 let outer_type = mdl::Type {
1104 code: mdl::TypeCode::Struct,
1105 struct_type: Some(Box::new(mdl::StructType {
1106 fields: vec![
1107 mdl::struct_type::Field::new()
1108 .set_name("outer_field")
1109 .set_type(mdl::Type {
1110 code: mdl::TypeCode::String,
1111 ..Default::default()
1112 }),
1113 mdl::struct_type::Field::new()
1114 .set_name("inner")
1115 .set_type(inner_struct_type),
1116 ],
1117 _unknown_fields: Default::default(),
1118 })),
1119 ..Default::default()
1120 };
1121 let spanner_type = Type(outer_type);
1122
1123 let v = crate::value::Value(prost_types::Value {
1125 kind: Some(prost_types::value::Kind::ListValue(
1126 prost_types::ListValue {
1127 values: vec![
1128 prost_types::Value {
1129 kind: Some(prost_types::value::Kind::StringValue("hello".to_string())),
1130 },
1131 prost_types::Value {
1132 kind: Some(prost_types::value::Kind::ListValue(
1133 prost_types::ListValue {
1134 values: vec![
1135 prost_types::Value {
1136 kind: Some(prost_types::value::Kind::StringValue(
1137 "42".to_string(),
1138 )),
1139 },
1140 prost_types::Value {
1141 kind: Some(prost_types::value::Kind::BoolValue(true)),
1142 },
1143 ],
1144 },
1145 )),
1146 },
1147 ],
1148 },
1149 )),
1150 });
1151
1152 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1153 assert_eq!(
1154 j,
1155 serde_json::json!({"outer_field": "hello", "inner": {"x": "42", "y": true}})
1156 );
1157 }
1158
1159 #[test]
1160 fn test_from_value_json_null_in_struct() {
1161 let struct_type_mdl = mdl::Type {
1163 code: mdl::TypeCode::Struct,
1164 struct_type: Some(Box::new(mdl::StructType {
1165 fields: vec![
1166 mdl::struct_type::Field::new()
1167 .set_name("name")
1168 .set_type(mdl::Type {
1169 code: mdl::TypeCode::String,
1170 ..Default::default()
1171 }),
1172 mdl::struct_type::Field::new()
1173 .set_name("value")
1174 .set_type(mdl::Type {
1175 code: mdl::TypeCode::Int64,
1176 ..Default::default()
1177 }),
1178 ],
1179 _unknown_fields: Default::default(),
1180 })),
1181 ..Default::default()
1182 };
1183 let spanner_type = Type(struct_type_mdl);
1184
1185 let v = crate::value::Value(prost_types::Value {
1187 kind: Some(prost_types::value::Kind::ListValue(
1188 prost_types::ListValue {
1189 values: vec![
1190 prost_types::Value {
1191 kind: Some(prost_types::value::Kind::StringValue("test".to_string())),
1192 },
1193 prost_types::Value {
1194 kind: Some(prost_types::value::Kind::NullValue(0)),
1195 },
1196 ],
1197 },
1198 )),
1199 });
1200
1201 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1202 assert_eq!(j, serde_json::json!({"name": "test", "value": null}));
1203 }
1204
1205 #[test]
1206 fn test_from_value_json_nan_becomes_null() {
1207 let v = crate::value::Value(prost_types::Value {
1209 kind: Some(prost_types::value::Kind::NumberValue(f64::NAN)),
1210 });
1211 let j = JsonValue::from_value(&v, &types::float64()).unwrap();
1212 assert_eq!(j, JsonValue::Null);
1213
1214 let v = crate::value::Value(prost_types::Value {
1215 kind: Some(prost_types::value::Kind::NumberValue(f64::INFINITY)),
1216 });
1217 let j = JsonValue::from_value(&v, &types::float64()).unwrap();
1218 assert_eq!(j, JsonValue::Null);
1219
1220 let v = crate::value::Value(prost_types::Value {
1221 kind: Some(prost_types::value::Kind::NumberValue(f64::NEG_INFINITY)),
1222 });
1223 let j = JsonValue::from_value(&v, &types::float64()).unwrap();
1224 assert_eq!(j, JsonValue::Null);
1225
1226 let v = crate::value::Value(prost_types::Value {
1228 kind: Some(prost_types::value::Kind::StringValue("NaN".to_string())),
1229 });
1230 let j = JsonValue::from_value(&v, &types::float64()).unwrap();
1231 assert_eq!(j, JsonValue::Null);
1232
1233 let v = crate::value::Value(prost_types::Value {
1234 kind: Some(prost_types::value::Kind::StringValue(
1235 "Infinity".to_string(),
1236 )),
1237 });
1238 let j = JsonValue::from_value(&v, &types::float64()).unwrap();
1239 assert_eq!(j, JsonValue::Null);
1240
1241 let v = crate::value::Value(prost_types::Value {
1242 kind: Some(prost_types::value::Kind::StringValue(
1243 "-Infinity".to_string(),
1244 )),
1245 });
1246 let j = JsonValue::from_value(&v, &types::float64()).unwrap();
1247 assert_eq!(j, JsonValue::Null);
1248 }
1249
1250 #[test]
1251 fn test_from_value_json_option_wrapping() {
1252 let v = "hello".to_value();
1254 let j = Option::<JsonValue>::from_value(&v, &types::string()).unwrap();
1255 assert_eq!(j, Some(JsonValue::String("hello".to_string())));
1256
1257 let v: Option<String> = None;
1259 let j = Option::<JsonValue>::from_value(&v.to_value(), &types::string()).unwrap();
1260 assert_eq!(j, None);
1261 }
1262
1263 #[test]
1264 fn test_from_value_json_empty_struct() {
1265 let struct_type_mdl = mdl::Type {
1267 code: mdl::TypeCode::Struct,
1268 struct_type: Some(Box::new(mdl::StructType {
1269 fields: vec![],
1270 _unknown_fields: Default::default(),
1271 })),
1272 ..Default::default()
1273 };
1274 let spanner_type = Type(struct_type_mdl);
1275
1276 let v = crate::value::Value(prost_types::Value {
1278 kind: Some(prost_types::value::Kind::ListValue(
1279 prost_types::ListValue { values: vec![] },
1280 )),
1281 });
1282
1283 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1284 assert_eq!(j, serde_json::json!({}));
1285 }
1286
1287 #[test]
1288 fn test_from_value_json_unnamed_fields() {
1289 let struct_type_mdl = mdl::Type {
1292 code: mdl::TypeCode::Struct,
1293 struct_type: Some(Box::new(mdl::StructType {
1294 fields: vec![
1295 mdl::struct_type::Field::new()
1296 .set_name("")
1297 .set_type(mdl::Type {
1298 code: mdl::TypeCode::String,
1299 ..Default::default()
1300 }),
1301 mdl::struct_type::Field::new()
1302 .set_name("")
1303 .set_type(mdl::Type {
1304 code: mdl::TypeCode::Int64,
1305 ..Default::default()
1306 }),
1307 ],
1308 _unknown_fields: Default::default(),
1309 })),
1310 ..Default::default()
1311 };
1312 let spanner_type = Type(struct_type_mdl);
1313
1314 let v = crate::value::Value(prost_types::Value {
1316 kind: Some(prost_types::value::Kind::ListValue(
1317 prost_types::ListValue {
1318 values: vec![
1319 prost_types::Value {
1320 kind: Some(prost_types::value::Kind::StringValue("val".to_string())),
1321 },
1322 prost_types::Value {
1323 kind: Some(prost_types::value::Kind::StringValue("99".to_string())),
1324 },
1325 ],
1326 },
1327 )),
1328 });
1329
1330 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1332 assert!(j.is_object());
1333 assert_eq!(
1335 j.as_object().unwrap().get("").unwrap(),
1336 &serde_json::json!("99")
1337 );
1338 }
1339
1340 #[test]
1341 fn test_from_value_json_vec_composition() {
1342 let str_array = vec!["one".to_string(), "two".to_string()];
1344 let v = str_array.to_value();
1345 let res = Vec::<JsonValue>::from_value(&v, &types::array(types::string())).unwrap();
1346 assert_eq!(res.len(), 2);
1347 assert_eq!(res[0], JsonValue::String("one".to_string()));
1348 assert_eq!(res[1], JsonValue::String("two".to_string()));
1349 }
1350
1351 #[test]
1352 fn test_from_value_json_struct_without_metadata() {
1353 let mut s = prost_types::Struct::default();
1355 s.fields.insert(
1356 "raw_field".to_string(),
1357 prost_types::Value {
1358 kind: Some(prost_types::value::Kind::BoolValue(true)),
1359 },
1360 );
1361 let v = crate::value::Value(prost_types::Value {
1362 kind: Some(prost_types::value::Kind::StructValue(s)),
1363 });
1364
1365 let j = JsonValue::from_value(&v, &Type::default()).unwrap();
1367 assert_eq!(j, serde_json::json!({"raw_field": true}));
1368 }
1369
1370 #[test]
1371 fn test_from_value_json_list_without_type_info() {
1372 let v = crate::value::Value(prost_types::Value {
1374 kind: Some(prost_types::value::Kind::ListValue(
1375 prost_types::ListValue {
1376 values: vec![
1377 prost_types::Value {
1378 kind: Some(prost_types::value::Kind::StringValue("a".to_string())),
1379 },
1380 prost_types::Value {
1381 kind: Some(prost_types::value::Kind::BoolValue(false)),
1382 },
1383 ],
1384 },
1385 )),
1386 });
1387
1388 let j = JsonValue::from_value(&v, &Type::default()).unwrap();
1389 assert_eq!(j, serde_json::json!(["a", false]));
1390 }
1391
1392 #[test]
1393 fn test_from_value_json_invalid_json_column() {
1394 let v = crate::value::Value(prost_types::Value {
1396 kind: Some(prost_types::value::Kind::StringValue(
1397 "not valid json{".to_string(),
1398 )),
1399 });
1400
1401 let err = JsonValue::from_value(&v, &types::json()).unwrap_err();
1402 assert!(format!("{}", err).contains("cannot convert value"));
1403 }
1404
1405 #[test]
1406 fn test_from_value_json_missing_positional_fields_become_null() {
1407 let struct_type_mdl = mdl::Type {
1409 code: mdl::TypeCode::Struct,
1410 struct_type: Some(Box::new(mdl::StructType {
1411 fields: vec![
1412 mdl::struct_type::Field::new()
1413 .set_name("a")
1414 .set_type(mdl::Type {
1415 code: mdl::TypeCode::String,
1416 ..Default::default()
1417 }),
1418 mdl::struct_type::Field::new()
1419 .set_name("b")
1420 .set_type(mdl::Type {
1421 code: mdl::TypeCode::Int64,
1422 ..Default::default()
1423 }),
1424 mdl::struct_type::Field::new()
1425 .set_name("c")
1426 .set_type(mdl::Type {
1427 code: mdl::TypeCode::Bool,
1428 ..Default::default()
1429 }),
1430 ],
1431 _unknown_fields: Default::default(),
1432 })),
1433 ..Default::default()
1434 };
1435 let spanner_type = Type(struct_type_mdl);
1436
1437 let v = crate::value::Value(prost_types::Value {
1439 kind: Some(prost_types::value::Kind::ListValue(
1440 prost_types::ListValue {
1441 values: vec![prost_types::Value {
1442 kind: Some(prost_types::value::Kind::StringValue("only_a".to_string())),
1443 }],
1444 },
1445 )),
1446 });
1447
1448 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1449 assert_eq!(j, serde_json::json!({"a": "only_a", "b": null, "c": null}));
1450 }
1451
1452 #[test]
1453 fn test_from_value_json_array_of_json_columns() {
1454 let json_type = mdl::Type {
1456 code: mdl::TypeCode::Json,
1457 ..Default::default()
1458 };
1459 let array_type = mdl::Type {
1460 code: mdl::TypeCode::Array,
1461 array_element_type: Some(Box::new(json_type)),
1462 ..Default::default()
1463 };
1464 let spanner_type = Type(array_type);
1465
1466 let v = crate::value::Value(prost_types::Value {
1468 kind: Some(prost_types::value::Kind::ListValue(
1469 prost_types::ListValue {
1470 values: vec![
1471 prost_types::Value {
1472 kind: Some(prost_types::value::Kind::StringValue(
1473 r#"{"x":1}"#.to_string(),
1474 )),
1475 },
1476 prost_types::Value {
1477 kind: Some(prost_types::value::Kind::StringValue(
1478 r#"{"y":2}"#.to_string(),
1479 )),
1480 },
1481 ],
1482 },
1483 )),
1484 });
1485
1486 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1487 assert_eq!(j, serde_json::json!([{"x": 1}, {"y": 2}]));
1488 }
1489
1490 #[test]
1491 fn test_from_value_json_nested_array_in_struct() {
1492 let struct_type_mdl = mdl::Type {
1494 code: mdl::TypeCode::Struct,
1495 struct_type: Some(Box::new(mdl::StructType {
1496 fields: vec![
1497 mdl::struct_type::Field::new()
1498 .set_name("tags")
1499 .set_type(mdl::Type {
1500 code: mdl::TypeCode::Array,
1501 array_element_type: Some(Box::new(mdl::Type {
1502 code: mdl::TypeCode::String,
1503 ..Default::default()
1504 })),
1505 ..Default::default()
1506 }),
1507 mdl::struct_type::Field::new()
1508 .set_name("id")
1509 .set_type(mdl::Type {
1510 code: mdl::TypeCode::Int64,
1511 ..Default::default()
1512 }),
1513 ],
1514 _unknown_fields: Default::default(),
1515 })),
1516 ..Default::default()
1517 };
1518 let spanner_type = Type(struct_type_mdl);
1519
1520 let v = crate::value::Value(prost_types::Value {
1522 kind: Some(prost_types::value::Kind::ListValue(
1523 prost_types::ListValue {
1524 values: vec![
1525 prost_types::Value {
1526 kind: Some(prost_types::value::Kind::ListValue(
1527 prost_types::ListValue {
1528 values: vec![
1529 prost_types::Value {
1530 kind: Some(prost_types::value::Kind::StringValue(
1531 "foo".to_string(),
1532 )),
1533 },
1534 prost_types::Value {
1535 kind: Some(prost_types::value::Kind::StringValue(
1536 "bar".to_string(),
1537 )),
1538 },
1539 ],
1540 },
1541 )),
1542 },
1543 prost_types::Value {
1544 kind: Some(prost_types::value::Kind::StringValue("42".to_string())),
1545 },
1546 ],
1547 },
1548 )),
1549 });
1550
1551 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1552 assert_eq!(j, serde_json::json!({"tags": ["foo", "bar"], "id": "42"}));
1553 }
1554
1555 #[test]
1556 fn test_from_value_json_recursion_depth_limit() {
1557 let mut inner = prost_types::Value {
1559 kind: Some(prost_types::value::Kind::BoolValue(true)),
1560 };
1561 for _ in 0..65 {
1562 inner = prost_types::Value {
1563 kind: Some(prost_types::value::Kind::ListValue(
1564 prost_types::ListValue {
1565 values: vec![inner],
1566 },
1567 )),
1568 };
1569 }
1570 let v = crate::value::Value(inner);
1571
1572 let err = JsonValue::from_value(&v, &Type::default()).unwrap_err();
1573 assert!(format!("{}", err).contains("nesting depth exceeded"));
1574 }
1575
1576 #[test]
1577 fn test_from_value_json_array_without_element_type() {
1578 let array_type = mdl::Type {
1580 code: mdl::TypeCode::Array,
1581 array_element_type: None,
1582 ..Default::default()
1583 };
1584 let spanner_type = Type(array_type);
1585
1586 let v = crate::value::Value(prost_types::Value {
1588 kind: Some(prost_types::value::Kind::ListValue(
1589 prost_types::ListValue {
1590 values: vec![prost_types::Value {
1591 kind: Some(prost_types::value::Kind::StringValue("hello".to_string())),
1592 }],
1593 },
1594 )),
1595 });
1596
1597 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1598 assert_eq!(j, serde_json::json!(["hello"]));
1599 }
1600
1601 #[test]
1602 fn test_from_value_json_struct_with_missing_field_type() {
1603 let struct_type_mdl = mdl::Type {
1605 code: mdl::TypeCode::Struct,
1606 struct_type: Some(Box::new(mdl::StructType {
1607 fields: vec![
1608 mdl::struct_type::Field::new().set_name("a"), ],
1610 _unknown_fields: Default::default(),
1611 })),
1612 ..Default::default()
1613 };
1614 let spanner_type = Type(struct_type_mdl);
1615
1616 let v = crate::value::Value(prost_types::Value {
1618 kind: Some(prost_types::value::Kind::ListValue(
1619 prost_types::ListValue {
1620 values: vec![prost_types::Value {
1621 kind: Some(prost_types::value::Kind::StringValue("hello".to_string())),
1622 }],
1623 },
1624 )),
1625 });
1626
1627 let j = JsonValue::from_value(&v, &spanner_type).unwrap();
1628 assert_eq!(j, serde_json::json!({"a": "hello"}));
1629 }
1630}