1#![cfg(feature = "serde")]
2
3mod r#enum;
4mod identifier;
5mod map;
6mod number;
7mod seq;
8mod tests;
9
10use crate::Data;
11use crate::DataType;
12use crate::Error;
13use crate::Expected;
14use crate::Number;
15use crate::Value;
16use alloc::borrow::Cow;
17use alloc::borrow::ToOwned;
18use alloc::boxed::Box;
19use alloc::string::String;
20use alloc::vec::Vec;
21use core::fmt;
22use identifier::Identifier;
23use map::Map;
24use seq::Seq;
25use serde::de;
26use serde::Deserialize;
27mod error;
28use map::Key;
29use serde::de::MapAccess;
30use serde::de::SeqAccess;
31use serde::de::Visitor;
32
33pub use error::Unexpected;
34
35#[derive(Debug, Clone, PartialEq, PartialOrd)]
37pub struct Deserializer<'de> {
38 value: Value<'de>,
39 human_readable: bool,
40 coerce_numbers: bool,
41}
42
43impl<'de> Deserializer<'de> {
44 pub const fn new(value: Value<'de>) -> Self {
49 Self {
50 value,
51 human_readable: false,
52 coerce_numbers: false,
53 }
54 }
55
56 pub const fn human_readable(mut self) -> Self {
58 self.human_readable = true;
59 self
60 }
61
62 pub const fn coerce_numbers(mut self) -> Self {
64 self.coerce_numbers = true;
65 self
66 }
67
68 pub fn deserialize<T>(self) -> Result<T, Error>
70 where
71 T: de::Deserialize<'de>,
72 {
73 T::deserialize(self)
74 }
75}
76
77#[cfg(feature = "std")]
78impl<'de> serde::de::IntoDeserializer<'de, Error> for Deserializer<'de> {
79 type Deserializer = Deserializer<'de>;
80
81 fn into_deserializer(self) -> Self::Deserializer {
82 self
83 }
84}
85
86#[cfg(feature = "std")]
87impl<'de> serde::de::IntoDeserializer<'de, Error> for Value<'de> {
88 type Deserializer = Deserializer<'de>;
89
90 fn into_deserializer(self) -> Self::Deserializer {
91 Deserializer::new(self)
92 }
93}
94
95impl<'de> de::Deserializer<'de> for Deserializer<'de> {
96 type Error = Error;
97
98 fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
99 where
100 V: Visitor<'de>,
101 {
102 match self.value {
103 Value::Unit => visitor.visit_unit(),
104 Value::Bool(v) => visitor.visit_bool(v),
105 Value::Number(n) => match n {
106 Number::I8(v) => visitor.visit_i8(v),
107 Number::U8(v) => visitor.visit_u8(v),
108 Number::I16(v) => visitor.visit_i16(v),
109 Number::U16(v) => visitor.visit_u16(v),
110 Number::I32(v) => visitor.visit_i32(v),
111 Number::U32(v) => visitor.visit_u32(v),
112 Number::F32(v) => visitor.visit_f32(v),
113 Number::I64(v) => visitor.visit_i64(v),
114 Number::U64(v) => visitor.visit_u64(v),
115 Number::F64(v) => visitor.visit_f64(v),
116 Number::I128(v) => visitor.visit_i128(v),
117 Number::U128(v) => visitor.visit_u128(v),
118 },
119 Value::Char(v) => visitor.visit_char(v),
120 Value::String(v) => match v {
121 Cow::Borrowed(v) => visitor.visit_borrowed_str(v),
122 Cow::Owned(v) => visitor.visit_string(v),
123 },
124 Value::Bytes(v) => match v {
125 Cow::Borrowed(v) => visitor.visit_borrowed_bytes(v),
126 Cow::Owned(v) => visitor.visit_byte_buf(v),
127 },
128 Value::Seq(v) => {
129 visitor.visit_seq(Seq::new(v, self.human_readable, self.coerce_numbers))
130 }
131 Value::Map(v) => {
132 visitor.visit_map(Map::from((v, self.human_readable, self.coerce_numbers)))
133 }
134 Value::Option(v) => match v {
135 Some(v) => {
136 self.value = *v;
137 visitor.visit_some(self)
138 }
139 None => visitor.visit_none(),
140 },
141 Value::Struct(v) => match v.data {
142 Data::Unit => visitor.visit_unit(),
143 Data::NewType { value } => {
144 self.value = value;
145 visitor.visit_newtype_struct(self)
146 }
147 Data::Tuple { values } => {
148 let tuple = Seq::new(values, self.human_readable, self.coerce_numbers);
149 visitor.visit_seq(tuple)
150 }
151 Data::Struct { fields } => {
152 let len = fields.len();
153 let mut vec = Vec::with_capacity(len);
154 for (index, (key, value)) in fields.into_iter().enumerate() {
155 let key = Key::Identifier(Identifier::new(key, index as u64));
156 vec.push((key, value));
157 }
158 let data = Map::new(vec, self.human_readable, self.coerce_numbers);
159 visitor.visit_map(data)
160 }
161 },
162 Value::Enum(v) => r#enum::visit_enum(
163 v.name.clone(),
164 v,
165 self.human_readable,
166 self.coerce_numbers,
167 visitor,
168 ),
169 Value::Tuple(v) => {
170 visitor.visit_seq(Seq::new(v, self.human_readable, self.coerce_numbers))
171 }
172 }
173 }
174
175 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
176 where
177 V: Visitor<'de>,
178 {
179 match self.value {
180 Value::Bool(v) => visitor.visit_bool(v),
181 _ => Err(self.value.unexpected(Expected::Bool)),
182 }
183 }
184
185 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
186 where
187 V: Visitor<'de>,
188 {
189 match self.value {
190 Value::Number(n) => number::visit(n, Expected::I8, self.coerce_numbers, visitor),
191 _ => Err(self.value.unexpected(Expected::I8)),
192 }
193 }
194
195 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
196 where
197 V: Visitor<'de>,
198 {
199 match self.value {
200 Value::Number(n) => number::visit(n, Expected::I16, self.coerce_numbers, visitor),
201 _ => Err(self.value.unexpected(Expected::I16)),
202 }
203 }
204
205 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
206 where
207 V: Visitor<'de>,
208 {
209 match self.value {
210 Value::Number(n) => number::visit(n, Expected::I32, self.coerce_numbers, visitor),
211 _ => Err(self.value.unexpected(Expected::I32)),
212 }
213 }
214
215 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
216 where
217 V: Visitor<'de>,
218 {
219 match self.value {
220 Value::Number(n) => number::visit(n, Expected::I64, self.coerce_numbers, visitor),
221 _ => Err(self.value.unexpected(Expected::I64)),
222 }
223 }
224
225 fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
226 where
227 V: Visitor<'de>,
228 {
229 match self.value {
230 Value::Number(n) => number::visit(n, Expected::I128, self.coerce_numbers, visitor),
231 _ => Err(self.value.unexpected(Expected::I128)),
232 }
233 }
234
235 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
236 where
237 V: Visitor<'de>,
238 {
239 match self.value {
240 Value::Number(n) => number::visit(n, Expected::U8, self.coerce_numbers, visitor),
241 _ => Err(self.value.unexpected(Expected::U8)),
242 }
243 }
244
245 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
246 where
247 V: Visitor<'de>,
248 {
249 match self.value {
250 Value::Number(n) => number::visit(n, Expected::U16, self.coerce_numbers, visitor),
251 _ => Err(self.value.unexpected(Expected::U16)),
252 }
253 }
254
255 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
256 where
257 V: Visitor<'de>,
258 {
259 match self.value {
260 Value::Number(n) => number::visit(n, Expected::U32, self.coerce_numbers, visitor),
261 _ => Err(self.value.unexpected(Expected::U32)),
262 }
263 }
264
265 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
266 where
267 V: Visitor<'de>,
268 {
269 match self.value {
270 Value::Number(n) => number::visit(n, Expected::U64, self.coerce_numbers, visitor),
271 _ => Err(self.value.unexpected(Expected::U64)),
272 }
273 }
274
275 fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
276 where
277 V: Visitor<'de>,
278 {
279 match self.value {
280 Value::Number(n) => number::visit(n, Expected::U128, self.coerce_numbers, visitor),
281 _ => Err(self.value.unexpected(Expected::U128)),
282 }
283 }
284
285 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
286 where
287 V: Visitor<'de>,
288 {
289 match self.value {
290 Value::Number(n) => number::visit(n, Expected::F32, self.coerce_numbers, visitor),
291 _ => Err(self.value.unexpected(Expected::F32)),
292 }
293 }
294
295 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
296 where
297 V: Visitor<'de>,
298 {
299 match self.value {
300 Value::Number(n) => number::visit(n, Expected::F64, self.coerce_numbers, visitor),
301 _ => Err(self.value.unexpected(Expected::F64)),
302 }
303 }
304
305 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
306 where
307 V: Visitor<'de>,
308 {
309 match self.value {
310 Value::Char(v) => visitor.visit_char(v),
311 _ => Err(self.value.unexpected(Expected::Char)),
312 }
313 }
314
315 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
316 where
317 V: Visitor<'de>,
318 {
319 match self.value {
320 Value::String(v) => match v {
321 Cow::Borrowed(v) => visitor.visit_borrowed_str(v),
322 Cow::Owned(v) => visitor.visit_string(v),
323 },
324 _ => Err(self.value.unexpected(Expected::String)),
325 }
326 }
327
328 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
329 where
330 V: Visitor<'de>,
331 {
332 self.deserialize_str(visitor)
333 }
334
335 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
336 where
337 V: Visitor<'de>,
338 {
339 match self.value {
340 Value::Bytes(v) => match v {
341 Cow::Borrowed(v) => visitor.visit_borrowed_bytes(v),
342 Cow::Owned(v) => visitor.visit_byte_buf(v),
343 },
344 _ => Err(self.value.unexpected(Expected::Bytes)),
345 }
346 }
347
348 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
349 where
350 V: Visitor<'de>,
351 {
352 self.deserialize_bytes(visitor)
353 }
354
355 fn deserialize_option<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
356 where
357 V: Visitor<'de>,
358 {
359 match self.value {
360 Value::Option(v) => match v {
361 Some(v) => {
362 self.value = *v;
363 visitor.visit_some(self)
364 }
365 None => visitor.visit_none(),
366 },
367 _ => visitor.visit_some(self),
368 }
369 }
370
371 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
372 where
373 V: Visitor<'de>,
374 {
375 match self.value {
376 Value::Unit => visitor.visit_unit(),
377 _ => Err(self.value.unexpected(Expected::Unit)),
378 }
379 }
380
381 fn deserialize_unit_struct<V>(
382 self,
383 name: &'static str,
384 visitor: V,
385 ) -> Result<V::Value, Self::Error>
386 where
387 V: Visitor<'de>,
388 {
389 match self.value {
390 Value::Struct(v) => match v.data {
391 Data::Unit => visitor.visit_unit(),
392 _ => Err(v.unexpected(Expected::Struct {
393 name: Some(name.to_owned()),
394 typ: Some(DataType::Unit),
395 })),
396 },
397 Value::Unit => self.deserialize_unit(visitor),
398 _ => Err(self.value.unexpected(Expected::Struct {
399 name: Some(name.to_owned()),
400 typ: Some(DataType::Unit),
401 })),
402 }
403 }
404
405 fn deserialize_newtype_struct<V>(
406 mut self,
407 _name: &'static str,
408 visitor: V,
409 ) -> Result<V::Value, Self::Error>
410 where
411 V: Visitor<'de>,
412 {
413 match self.value {
414 Value::Struct(v) => match v.data {
415 Data::NewType { value } => {
416 self.value = value;
417 visitor.visit_newtype_struct(self)
418 }
419 _ => {
420 self.value = Value::Struct(v);
421 visitor.visit_newtype_struct(self)
422 }
423 },
424 _ => visitor.visit_newtype_struct(self),
425 }
426 }
427
428 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
429 where
430 V: Visitor<'de>,
431 {
432 match self.value {
433 Value::Seq(v) => {
434 visitor.visit_seq(Seq::new(v, self.human_readable, self.coerce_numbers))
435 }
436 _ => Err(self.value.unexpected(Expected::Seq)),
437 }
438 }
439
440 fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
441 where
442 V: Visitor<'de>,
443 {
444 match self.value {
445 Value::Tuple(v) => {
446 visitor.visit_seq(Seq::new(v, self.human_readable, self.coerce_numbers))
447 }
448 Value::Seq(_) => self.deserialize_seq(visitor),
449 _ => Err(self.value.unexpected(Expected::Tuple(len))),
450 }
451 }
452
453 fn deserialize_tuple_struct<V>(
454 self,
455 name: &'static str,
456 _len: usize,
457 visitor: V,
458 ) -> Result<V::Value, Self::Error>
459 where
460 V: Visitor<'de>,
461 {
462 match self.value {
463 Value::Struct(v) => match v.data {
464 Data::Tuple { values } => {
465 visitor.visit_seq(Seq::new(values, self.human_readable, self.coerce_numbers))
466 }
467 _ => Err(v.unexpected(Expected::Struct {
468 name: Some(name.to_owned()),
469 typ: Some(DataType::Tuple),
470 })),
471 },
472 Value::Seq(_) => self.deserialize_seq(visitor),
473 _ => Err(self.value.unexpected(Expected::Struct {
474 name: Some(name.to_owned()),
475 typ: Some(DataType::Tuple),
476 })),
477 }
478 }
479
480 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
481 where
482 V: Visitor<'de>,
483 {
484 match self.value {
485 Value::Map(v) => {
486 visitor.visit_map(Map::from((v, self.human_readable, self.coerce_numbers)))
487 }
488 _ => Err(self.value.unexpected(Expected::Map)),
489 }
490 }
491
492 fn deserialize_struct<V>(
493 self,
494 name: &'static str,
495 _fields: &'static [&'static str],
496 visitor: V,
497 ) -> Result<V::Value, Self::Error>
498 where
499 V: Visitor<'de>,
500 {
501 match self.value {
502 Value::Struct(v) => match v.data {
503 Data::Struct { fields } => visitor.visit_map(Map::from((
504 fields,
505 self.human_readable,
506 self.coerce_numbers,
507 ))),
508 _ => Err(v.unexpected(Expected::Struct {
509 name: Some(name.to_owned()),
510 typ: Some(DataType::Struct),
511 })),
512 },
513 Value::Map(_) => self.deserialize_map(visitor),
514 _ => Err(self.value.unexpected(Expected::Struct {
515 name: Some(name.to_owned()),
516 typ: Some(DataType::Struct),
517 })),
518 }
519 }
520
521 fn deserialize_enum<V>(
522 self,
523 name: &'static str,
524 _variants: &'static [&'static str],
525 visitor: V,
526 ) -> Result<V::Value, Self::Error>
527 where
528 V: Visitor<'de>,
529 {
530 match self.value {
531 Value::Enum(v) => r#enum::visit_enum(
532 Cow::Borrowed(name),
533 v,
534 self.human_readable,
535 self.coerce_numbers,
536 visitor,
537 ),
538 Value::String(string) => visitor.visit_enum(r#enum::Access {
539 expected: name,
540 name: Value::String(string),
541 data: None,
542 human_readable: self.human_readable,
543 coerce_numbers: self.coerce_numbers,
544 }),
545 Value::Map(mut map) if map.len() == 1 => {
546 let (variant, data) = map.pop().unwrap();
547 visitor.visit_enum(r#enum::Access {
548 expected: name,
549 name: variant,
550 data: Some(data),
551 human_readable: self.human_readable,
552 coerce_numbers: self.coerce_numbers,
553 })
554 }
555 _ => Err(self.value.unexpected(Expected::Enum {
556 name: Some(name.to_owned()),
557 typ: None,
558 })),
559 }
560 }
561
562 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
563 where
564 V: Visitor<'de>,
565 {
566 match self.value {
567 Value::String(v) => match v {
568 Cow::Borrowed(v) => visitor.visit_borrowed_str(v),
569 Cow::Owned(v) => visitor.visit_string(v),
570 },
571 Value::Enum(v) => match v.variant {
572 Cow::Borrowed(v) => visitor.visit_borrowed_str(v),
573 Cow::Owned(v) => visitor.visit_string(v),
574 },
575 _ => Err(self.value.unexpected(Expected::Identifier)),
576 }
577 }
578
579 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
580 where
581 V: Visitor<'de>,
582 {
583 visitor.visit_unit()
584 }
585
586 fn is_human_readable(&self) -> bool {
587 self.human_readable
588 }
589}
590
591impl<'de> de::Deserialize<'de> for Value<'static> {
592 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
593 where
594 D: de::Deserializer<'de>,
595 {
596 let value: Value = deserializer.deserialize_any(ValueVisitor)?;
597 Ok(value.into_owned())
598 }
599}
600
601pub struct ValueVisitor;
614
615impl<'de> Visitor<'de> for ValueVisitor {
616 type Value = Value<'de>;
617
618 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
619 formatter.write_str("any value")
620 }
621
622 fn visit_bool<F>(self, value: bool) -> Result<Self::Value, F>
623 where
624 F: de::Error,
625 {
626 Ok(Value::Bool(value))
627 }
628
629 fn visit_i8<F>(self, value: i8) -> Result<Self::Value, F>
630 where
631 F: de::Error,
632 {
633 Ok(Value::Number(Number::I8(value)))
634 }
635
636 fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F>
637 where
638 F: de::Error,
639 {
640 Ok(Value::Number(Number::I16(value)))
641 }
642
643 fn visit_i32<F>(self, value: i32) -> Result<Self::Value, F>
644 where
645 F: de::Error,
646 {
647 Ok(Value::Number(Number::I32(value)))
648 }
649
650 fn visit_i64<F>(self, value: i64) -> Result<Self::Value, F>
651 where
652 F: de::Error,
653 {
654 Ok(Value::Number(Number::I64(value)))
655 }
656
657 fn visit_u8<F>(self, value: u8) -> Result<Self::Value, F>
658 where
659 F: de::Error,
660 {
661 Ok(Value::Number(Number::U8(value)))
662 }
663
664 fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F>
665 where
666 F: de::Error,
667 {
668 Ok(Value::Number(Number::U16(value)))
669 }
670
671 fn visit_u32<F>(self, value: u32) -> Result<Self::Value, F>
672 where
673 F: de::Error,
674 {
675 Ok(Value::Number(Number::U32(value)))
676 }
677
678 fn visit_u64<F>(self, value: u64) -> Result<Self::Value, F>
679 where
680 F: de::Error,
681 {
682 Ok(Value::Number(Number::U64(value)))
683 }
684
685 fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F>
686 where
687 F: de::Error,
688 {
689 Ok(Value::Number(Number::F32(value)))
690 }
691
692 fn visit_f64<F>(self, value: f64) -> Result<Self::Value, F>
693 where
694 F: de::Error,
695 {
696 Ok(Value::Number(Number::F64(value)))
697 }
698
699 fn visit_char<F>(self, value: char) -> Result<Self::Value, F>
700 where
701 F: de::Error,
702 {
703 Ok(Value::Char(value))
704 }
705
706 fn visit_str<F>(self, value: &str) -> Result<Self::Value, F>
707 where
708 F: de::Error,
709 {
710 Ok(Value::String(Cow::Owned(value.to_owned())))
711 }
712
713 fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F>
714 where
715 F: de::Error,
716 {
717 Ok(Value::String(Cow::Borrowed(value)))
718 }
719
720 fn visit_string<F>(self, value: String) -> Result<Self::Value, F>
721 where
722 F: de::Error,
723 {
724 Ok(Value::String(Cow::Owned(value)))
725 }
726
727 fn visit_bytes<F>(self, value: &[u8]) -> Result<Self::Value, F>
728 where
729 F: de::Error,
730 {
731 Ok(Value::Bytes(Cow::Owned(value.to_owned())))
732 }
733
734 fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F>
735 where
736 F: de::Error,
737 {
738 Ok(Value::Bytes(Cow::Borrowed(value)))
739 }
740
741 fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F>
742 where
743 F: de::Error,
744 {
745 Ok(Value::Bytes(Cow::Owned(value)))
746 }
747
748 fn visit_unit<F>(self) -> Result<Self::Value, F>
749 where
750 F: de::Error,
751 {
752 Ok(Value::Unit)
753 }
754
755 fn visit_none<F>(self) -> Result<Self::Value, F>
756 where
757 F: de::Error,
758 {
759 Ok(Value::Option(None))
760 }
761
762 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
763 where
764 D: de::Deserializer<'de>,
765 {
766 de::Deserialize::deserialize(deserializer).map(|v| Value::Option(Some(Box::new(v))))
767 }
768
769 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
770 where
771 D: de::Deserializer<'de>,
772 {
773 Deserialize::deserialize(deserializer)
774 }
775
776 fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
777 where
778 V: SeqAccess<'de>,
779 {
780 let len = visitor.size_hint().unwrap_or_default();
781 let mut vec = Vec::with_capacity(len);
782 while let Some(e) = visitor.next_element()? {
783 vec.push(e);
784 }
785 Ok(Value::Seq(vec))
786 }
787
788 fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
789 where
790 V: MapAccess<'de>,
791 {
792 let len = visitor.size_hint().unwrap_or_default();
793 let mut vec = Vec::with_capacity(len);
794 while let Some(kv) = visitor.next_entry()? {
795 vec.push(kv);
796 }
797 Ok(Value::Map(vec))
798 }
799
800 fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
801 where
802 E: de::Error,
803 {
804 Ok(Value::Number(Number::I128(v)))
805 }
806
807 fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
808 where
809 E: de::Error,
810 {
811 Ok(Value::Number(Number::U128(v)))
812 }
813}