1use crate::{IonExtractionError, IonParserError, IonValue, NullIonValue, SerdeJsonParseError};
2use bigdecimal::BigDecimal;
3use chrono::{DateTime, FixedOffset, Utc};
4use num_bigint::{BigInt, BigUint};
5use std::collections::HashMap;
6use std::convert::{TryFrom, TryInto};
7
8use serde_json::Value;
9use IonParserError::ValueExtractionFailure;
10
11impl TryFrom<IonValue> for std::collections::HashMap<String, IonValue> {
12 type Error = IonParserError;
13 fn try_from(value: IonValue) -> Result<Self, Self::Error> {
14 match value {
15 IonValue::Struct(value) => Ok(value),
16 _ => Err(ValueExtractionFailure(
17 IonExtractionError::TypeNotSupported(value),
18 )),
19 }
20 }
21}
22
23impl TryFrom<IonValue> for String {
24 type Error = IonParserError;
25
26 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
27 match value {
28 IonValue::String(value) | IonValue::Symbol(value) => Ok(value),
29 _ => Err(ValueExtractionFailure(
30 IonExtractionError::TypeNotSupported(value),
31 )),
32 }
33 }
34}
35
36impl TryFrom<IonValue> for u64 {
37 type Error = IonParserError;
38
39 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
40 match value {
41 IonValue::Integer(value) => value.try_into().map_err(|e| {
42 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
43 }),
44 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
45 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
46 }),
47 _ => Err(ValueExtractionFailure(
48 IonExtractionError::TypeNotSupported(value),
49 )),
50 }
51 }
52}
53
54impl TryFrom<IonValue> for i64 {
55 type Error = IonParserError;
56
57 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
58 match value {
59 IonValue::Integer(value) => Ok(value),
60 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
61 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
62 }),
63 _ => Err(ValueExtractionFailure(
64 IonExtractionError::TypeNotSupported(value),
65 )),
66 }
67 }
68}
69
70impl TryFrom<IonValue> for u32 {
71 type Error = IonParserError;
72
73 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
74 match value {
75 IonValue::Integer(value) => value.try_into().map_err(|e| {
76 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
77 }),
78 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
79 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
80 }),
81 _ => Err(ValueExtractionFailure(
82 IonExtractionError::TypeNotSupported(value),
83 )),
84 }
85 }
86}
87
88impl TryFrom<IonValue> for i32 {
89 type Error = IonParserError;
90
91 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
92 match value {
93 IonValue::Integer(value) => value.try_into().map_err(|e| {
94 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
95 }),
96 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
97 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
98 }),
99 _ => Err(ValueExtractionFailure(
100 IonExtractionError::TypeNotSupported(value),
101 )),
102 }
103 }
104}
105
106impl TryFrom<IonValue> for BigUint {
107 type Error = IonParserError;
108
109 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
110 match value {
111 IonValue::Integer(value) => value.try_into().map_err(|e| {
112 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
113 }),
114 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
115 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
116 }),
117 _ => Err(ValueExtractionFailure(
118 IonExtractionError::TypeNotSupported(value),
119 )),
120 }
121 }
122}
123
124impl TryFrom<IonValue> for BigInt {
125 type Error = IonParserError;
126
127 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
128 match value {
129 IonValue::Integer(value) => Ok(BigInt::from(value)),
130 IonValue::BigInteger(value) => Ok(value),
131 _ => Err(ValueExtractionFailure(
132 IonExtractionError::TypeNotSupported(value),
133 )),
134 }
135 }
136}
137
138impl TryFrom<IonValue> for BigDecimal {
139 type Error = IonParserError;
140
141 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
142 match value {
143 IonValue::Decimal(value) => Ok(value),
144 IonValue::Integer(value) => Ok(BigDecimal::from(value)),
145 IonValue::BigInteger(value) => {
146 let value = BigInt::from_signed_bytes_le(&value.to_signed_bytes_le());
147 Ok(BigDecimal::from(value))
148 }
149 _ => Err(ValueExtractionFailure(
150 IonExtractionError::TypeNotSupported(value),
151 )),
152 }
153 }
154}
155
156impl TryFrom<IonValue> for f64 {
157 type Error = IonParserError;
158
159 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
160 match value {
161 IonValue::Integer(value) => Ok(value as f64),
162 IonValue::BigInteger(value) => i64::try_from(value)
163 .map_err(|e| {
164 ValueExtractionFailure(IonExtractionError::NumericTransformationError(
165 Box::new(e),
166 ))
167 })
168 .map(|value| value as f64),
169 IonValue::Float(value) => Ok(value),
170 _ => Err(ValueExtractionFailure(
171 IonExtractionError::TypeNotSupported(value),
172 )),
173 }
174 }
175}
176
177impl TryFrom<IonValue> for f32 {
178 type Error = IonParserError;
179
180 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
181 match value {
182 IonValue::Integer(value) => Ok(value as f32),
183 IonValue::BigInteger(value) => i64::try_from(value)
184 .map_err(|e| {
185 ValueExtractionFailure(IonExtractionError::NumericTransformationError(
186 Box::new(e),
187 ))
188 })
189 .map(|value| value as f32),
190 IonValue::Float(value) => Ok(value as f32),
191 _ => Err(ValueExtractionFailure(
192 IonExtractionError::TypeNotSupported(value),
193 )),
194 }
195 }
196}
197
198impl TryFrom<IonValue> for DateTime<Utc> {
199 type Error = IonParserError;
200
201 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
202 match value {
203 IonValue::DateTime(value) => Ok(value.with_timezone(&Utc)),
204 _ => Err(ValueExtractionFailure(
205 IonExtractionError::TypeNotSupported(value),
206 )),
207 }
208 }
209}
210
211impl TryFrom<IonValue> for DateTime<FixedOffset> {
212 type Error = IonParserError;
213
214 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
215 match value {
216 IonValue::DateTime(value) => Ok(value),
217 _ => Err(ValueExtractionFailure(
218 IonExtractionError::TypeNotSupported(value),
219 )),
220 }
221 }
222}
223
224impl TryFrom<IonValue> for bool {
225 type Error = IonParserError;
226
227 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
228 match value {
229 IonValue::Bool(value) => Ok(value),
230 _ => Err(ValueExtractionFailure(
231 IonExtractionError::TypeNotSupported(value),
232 )),
233 }
234 }
235}
236
237impl TryFrom<IonValue> for Vec<u8> {
238 type Error = IonParserError;
239
240 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
241 match value {
242 IonValue::Clob(value) => Ok(value),
243 IonValue::Blob(value) => Ok(value),
244 _ => Err(ValueExtractionFailure(
245 IonExtractionError::TypeNotSupported(value),
246 )),
247 }
248 }
249}
250
251impl TryFrom<IonValue> for serde_json::Value {
252 type Error = IonParserError;
253
254 fn try_from(value: IonValue) -> Result<Self, IonParserError> {
255 match value {
256 IonValue::Null(_) => Ok(Value::Null),
257 IonValue::Bool(value) => Ok(Value::Bool(value)),
258 IonValue::Integer(value) => {
259 let json_number = serde_json::Number::from(value);
260 Ok(Value::from(json_number))
261 }
262 IonValue::BigInteger(value) => Ok(Value::Number(i64::try_from(value)?.into())),
263 ion_value @ IonValue::Decimal(_) => {
264 let number = f64::try_from(ion_value)?;
265
266 let json_number = serde_json::Number::from_f64(number)
267 .ok_or(IonParserError::DecimalNotANumericValue(number))?;
268
269 Ok(Value::Number(json_number))
270 }
271 IonValue::Float(value) => {
272 let json_number = serde_json::Number::from_f64(value)
273 .ok_or(IonParserError::DecimalNotANumericValue(value))?;
274
275 Ok(Value::from(json_number))
276 }
277 IonValue::String(value) => Ok(Value::String(value)),
278 IonValue::List(vector) => Ok(Value::Array(
279 vector
280 .into_iter()
281 .map(|element| element.try_into())
282 .collect::<Result<Vec<Value>, _>>()?,
283 )),
284 IonValue::Struct(values) => {
285 let mut result_map = serde_json::Map::with_capacity(values.len());
286
287 for (key, ion_value) in values {
288 result_map.insert(key.to_string(), Value::try_from(ion_value)?);
289 }
290 Ok(Value::Object(result_map))
291 }
292 _ => Err(IonParserError::TypeNotSupported(value)),
293 }
294 }
295}
296
297impl TryFrom<&IonValue> for Vec<IonValue> {
298 type Error = IonParserError;
299
300 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
301 match value {
302 IonValue::List(value) => Ok(value.to_vec()),
303 IonValue::SExpr(value) => Ok(value.to_vec()),
304 _ => Err(ValueExtractionFailure(
305 IonExtractionError::TypeNotSupported(value.clone()),
306 )),
307 }
308 }
309}
310
311impl TryFrom<&IonValue> for HashMap<String, IonValue> {
312 type Error = ();
313 fn try_from(value: &IonValue) -> Result<Self, Self::Error> {
314 if let IonValue::Struct(value) = value {
315 Ok(value.clone())
316 } else {
317 Err(())
318 }
319 }
320}
321
322impl TryFrom<&IonValue> for String {
323 type Error = IonParserError;
324
325 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
326 match value {
327 IonValue::String(value) | IonValue::Symbol(value) => Ok(value.clone()),
328 _ => Err(ValueExtractionFailure(
329 IonExtractionError::TypeNotSupported(value.clone()),
330 )),
331 }
332 }
333}
334
335impl TryFrom<&IonValue> for u64 {
336 type Error = IonParserError;
337
338 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
339 match value {
340 IonValue::Integer(value) => (*value).try_into().map_err(|e| {
341 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
342 }),
343 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
344 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
345 }),
346 _ => Err(ValueExtractionFailure(
347 IonExtractionError::TypeNotSupported(value.clone()),
348 )),
349 }
350 }
351}
352
353impl TryFrom<&IonValue> for i64 {
354 type Error = IonParserError;
355
356 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
357 match value {
358 IonValue::Integer(value) => Ok(*value),
359 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
360 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
361 }),
362 _ => Err(ValueExtractionFailure(
363 IonExtractionError::TypeNotSupported(value.clone()),
364 )),
365 }
366 }
367}
368
369impl TryFrom<&IonValue> for u32 {
370 type Error = IonParserError;
371
372 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
373 match value {
374 IonValue::Integer(value) => (*value).try_into().map_err(|e| {
375 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
376 }),
377 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
378 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
379 }),
380 _ => Err(ValueExtractionFailure(
381 IonExtractionError::TypeNotSupported(value.clone()),
382 )),
383 }
384 }
385}
386
387impl TryFrom<&IonValue> for i32 {
388 type Error = IonParserError;
389
390 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
391 match value {
392 IonValue::Integer(value) => (*value).try_into().map_err(|e| {
393 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
394 }),
395 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
396 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
397 }),
398 _ => Err(ValueExtractionFailure(
399 IonExtractionError::TypeNotSupported(value.clone()),
400 )),
401 }
402 }
403}
404
405impl TryFrom<&IonValue> for BigUint {
406 type Error = IonParserError;
407
408 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
409 match value {
410 IonValue::Integer(value) => (*value).try_into().map_err(|e| {
411 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
412 }),
413 IonValue::BigInteger(value) => value.try_into().map_err(|e| {
414 ValueExtractionFailure(IonExtractionError::NumericTransformationError(Box::new(e)))
415 }),
416 _ => Err(ValueExtractionFailure(
417 IonExtractionError::TypeNotSupported(value.clone()),
418 )),
419 }
420 }
421}
422
423impl TryFrom<&IonValue> for BigInt {
424 type Error = IonParserError;
425
426 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
427 match value {
428 IonValue::Integer(value) => Ok(BigInt::from(*value)),
429 IonValue::BigInteger(value) => Ok(value.clone()),
430 _ => Err(ValueExtractionFailure(
431 IonExtractionError::TypeNotSupported(value.clone()),
432 )),
433 }
434 }
435}
436
437impl TryFrom<&IonValue> for f64 {
438 type Error = IonParserError;
439
440 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
441 match value {
442 IonValue::Integer(value) => Ok(*value as f64),
443 IonValue::BigInteger(value) => i64::try_from(value)
444 .map_err(|e| {
445 ValueExtractionFailure(IonExtractionError::NumericTransformationError(
446 Box::new(e),
447 ))
448 })
449 .map(|value| value as f64),
450 IonValue::Float(value) => Ok(*value),
451 _ => Err(ValueExtractionFailure(
452 IonExtractionError::TypeNotSupported(value.clone()),
453 )),
454 }
455 }
456}
457
458impl TryFrom<&IonValue> for f32 {
459 type Error = IonParserError;
460
461 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
462 match value {
463 IonValue::Integer(value) => Ok(*value as f32),
464 IonValue::BigInteger(value) => i64::try_from(value)
465 .map_err(|e| {
466 ValueExtractionFailure(IonExtractionError::NumericTransformationError(
467 Box::new(e),
468 ))
469 })
470 .map(|value| value as f32),
471 IonValue::Float(value) => Ok(*value as f32),
472 _ => Err(ValueExtractionFailure(
473 IonExtractionError::TypeNotSupported(value.clone()),
474 )),
475 }
476 }
477}
478
479impl TryFrom<&IonValue> for DateTime<Utc> {
480 type Error = IonParserError;
481
482 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
483 match value {
484 IonValue::DateTime(value) => Ok(value.with_timezone(&Utc)),
485 _ => Err(ValueExtractionFailure(
486 IonExtractionError::TypeNotSupported(value.clone()),
487 )),
488 }
489 }
490}
491
492impl TryFrom<&IonValue> for DateTime<FixedOffset> {
493 type Error = IonParserError;
494
495 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
496 match value {
497 IonValue::DateTime(value) => Ok(*value),
498 _ => Err(ValueExtractionFailure(
499 IonExtractionError::TypeNotSupported(value.clone()),
500 )),
501 }
502 }
503}
504
505impl TryFrom<&IonValue> for bool {
506 type Error = IonParserError;
507
508 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
509 match value {
510 IonValue::Bool(value) => Ok(*value),
511 _ => Err(ValueExtractionFailure(
512 IonExtractionError::TypeNotSupported(value.clone()),
513 )),
514 }
515 }
516}
517
518impl TryFrom<&IonValue> for Vec<u8> {
519 type Error = IonParserError;
520
521 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
522 match value {
523 IonValue::Clob(value) => Ok(value.to_vec()),
524 IonValue::Blob(value) => Ok(value.to_vec()),
525 _ => Err(ValueExtractionFailure(
526 IonExtractionError::TypeNotSupported(value.clone()),
527 )),
528 }
529 }
530}
531
532impl TryFrom<&IonValue> for serde_json::Value {
533 type Error = IonParserError;
534
535 fn try_from(value: &IonValue) -> Result<Self, IonParserError> {
536 value.clone().try_into()
537 }
538}
539
540impl From<String> for IonValue {
541 fn from(value: String) -> IonValue {
542 IonValue::String(value)
543 }
544}
545
546impl From<&str> for IonValue {
547 fn from(value: &str) -> IonValue {
548 IonValue::String(value.to_string())
549 }
550}
551
552impl From<u16> for IonValue {
553 fn from(value: u16) -> IonValue {
554 IonValue::Integer(value.into())
555 }
556}
557
558impl From<i16> for IonValue {
559 fn from(value: i16) -> IonValue {
560 IonValue::Integer(value.into())
561 }
562}
563
564impl From<u32> for IonValue {
565 fn from(value: u32) -> IonValue {
566 IonValue::Integer(value.into())
567 }
568}
569
570impl From<i32> for IonValue {
571 fn from(value: i32) -> IonValue {
572 IonValue::Integer(value.into())
573 }
574}
575
576impl From<u64> for IonValue {
577 fn from(value: u64) -> IonValue {
578 match i64::try_from(value) {
579 Ok(value) => IonValue::Integer(value),
580 Err(_) => IonValue::BigInteger(BigInt::from(value)),
581 }
582 }
583}
584
585impl From<i64> for IonValue {
586 fn from(value: i64) -> IonValue {
587 IonValue::Integer(value)
588 }
589}
590
591impl From<u128> for IonValue {
592 fn from(value: u128) -> IonValue {
593 IonValue::BigInteger(BigInt::from(value))
594 }
595}
596
597impl From<i128> for IonValue {
598 fn from(value: i128) -> IonValue {
599 IonValue::BigInteger(BigInt::from(value))
600 }
601}
602
603impl From<BigInt> for IonValue {
604 fn from(value: BigInt) -> IonValue {
605 IonValue::BigInteger(value)
606 }
607}
608
609impl From<BigUint> for IonValue {
610 fn from(value: BigUint) -> IonValue {
611 IonValue::BigInteger(BigInt::from(value))
612 }
613}
614
615impl From<DateTime<FixedOffset>> for IonValue {
616 fn from(value: DateTime<FixedOffset>) -> IonValue {
617 IonValue::DateTime(value)
618 }
619}
620
621impl From<DateTime<Utc>> for IonValue {
622 fn from(value: DateTime<Utc>) -> IonValue {
623 IonValue::DateTime(value.into())
624 }
625}
626
627impl From<bool> for IonValue {
628 fn from(value: bool) -> IonValue {
629 IonValue::Bool(value)
630 }
631}
632
633impl From<Vec<u8>> for IonValue {
634 fn from(value: Vec<u8>) -> IonValue {
635 IonValue::Blob(value)
636 }
637}
638
639impl From<&[u8]> for IonValue {
640 fn from(value: &[u8]) -> IonValue {
641 IonValue::Blob(value.to_vec())
642 }
643}
644
645impl From<f32> for IonValue {
646 fn from(value: f32) -> IonValue {
647 IonValue::Float(value.into())
648 }
649}
650
651impl From<f64> for IonValue {
652 fn from(value: f64) -> IonValue {
653 IonValue::Float(value)
654 }
655}
656
657impl From<BigDecimal> for IonValue {
658 fn from(value: BigDecimal) -> IonValue {
659 IonValue::Decimal(value)
660 }
661}
662
663impl<I: Into<IonValue>> From<Vec<I>> for IonValue {
664 fn from(values: Vec<I>) -> Self {
665 let mut vec: Vec<IonValue> = vec![];
666
667 for value in values {
668 vec.push(value.into())
669 }
670
671 IonValue::List(vec)
672 }
673}
674
675impl<I: Into<IonValue> + Clone> From<&[I]> for IonValue {
676 fn from(values: &[I]) -> Self {
677 let mut vec: Vec<IonValue> = vec![];
678
679 for value in values.iter().cloned() {
680 vec.push(value.into())
681 }
682
683 IonValue::List(vec)
684 }
685}
686
687impl<I: Into<IonValue>, K: Into<String>> From<HashMap<K, I>> for IonValue {
688 fn from(values: HashMap<K, I>) -> Self {
689 let mut vec: HashMap<String, IonValue> = HashMap::new();
690
691 for (key, value) in values.into_iter() {
692 vec.insert(key.into(), value.into());
693 }
694
695 IonValue::Struct(vec)
696 }
697}
698
699impl<I: Into<IonValue> + Clone> From<&I> for IonValue {
700 fn from(value: &I) -> IonValue {
701 value.clone().into()
702 }
703}
704
705impl TryFrom<serde_json::Value> for IonValue {
706 type Error = SerdeJsonParseError;
707
708 fn try_from(value: serde_json::Value) -> Result<IonValue, SerdeJsonParseError> {
709 match value {
710 serde_json::Value::Null => Ok(IonValue::Null(NullIonValue::Null)),
711 serde_json::Value::Bool(bool) => Ok(bool.into()),
712 serde_json::Value::Number(number) => {
713 if number.is_f64() {
714 number
715 .as_f64()
716 .ok_or(SerdeJsonParseError::WrongNumberType)
717 .map(Into::into)
718 } else if number.is_i64() {
719 number
720 .as_i64()
721 .ok_or(SerdeJsonParseError::WrongNumberType)
722 .map(Into::into)
723 } else if number.is_u64() {
724 number
725 .as_u64()
726 .ok_or(SerdeJsonParseError::WrongNumberType)
727 .map(Into::into)
728 } else {
729 Err(SerdeJsonParseError::NonExistentNumberType)
730 }
731 }
732 serde_json::Value::String(string) => Ok(string.into()),
733 serde_json::Value::Array(array) => {
734 let list: Result<Vec<IonValue>, SerdeJsonParseError> = array
735 .into_iter()
736 .map(|element| element.try_into())
737 .collect();
738 match list {
739 Ok(list) => Ok(list.into()),
740 Err(error) => Err(error),
741 }
742 }
743 serde_json::Value::Object(map) => {
744 let mut hash_map = HashMap::<String, IonValue>::new();
745 for (key, value) in map.into_iter() {
746 let ion_value = value.try_into()?;
747 hash_map.insert(key.to_string(), ion_value);
748 }
749 Ok(hash_map.into())
750 }
751 }
752 }
753}