1#![no_std]
186#![doc(html_root_url = "https://docs.rs/serde-untagged/0.1.9")]
187#![deny(unsafe_op_in_unsafe_fn)]
188#![allow(
189 clippy::doc_markdown,
190 clippy::elidable_lifetime_names,
191 clippy::enum_glob_use,
192 clippy::manual_assert,
193 clippy::manual_map,
194 clippy::missing_errors_doc,
195 clippy::missing_panics_doc,
196 clippy::must_use_candidate,
197 clippy::needless_lifetimes,
198 clippy::needless_pass_by_value,
199 clippy::new_without_default,
200 clippy::type_complexity
201)]
202#![allow(unknown_lints, mismatched_lifetime_syntaxes)]
203
204extern crate alloc;
205extern crate serde_core as serde;
206
207mod any;
208mod error;
209mod int;
210mod map;
211mod seed;
212mod seq;
213
214use crate::error::Error;
215use crate::map::Map;
216use crate::seq::Seq;
217use alloc::boxed::Box;
218use alloc::vec::Vec;
219use core::fmt::{self, Display};
220use core::marker::PhantomData;
221use serde::de::{Deserializer, Expected, MapAccess, SeqAccess, Unexpected, Visitor};
222
223pub mod de {
224 pub use crate::error::Error;
225 pub use crate::map::Map;
226 pub use crate::seq::Seq;
227}
228
229pub struct UntaggedEnumVisitor<'closure, 'de, Value> {
230 expecting: Option<Box<dyn Display + 'closure>>,
231 visit_bool: Option<Box<dyn FnOnce(bool) -> Result<Value, Error> + 'closure>>,
232 visit_i8: Option<Box<dyn FnOnce(i8) -> Result<Value, Error> + 'closure>>,
233 visit_i16: Option<Box<dyn FnOnce(i16) -> Result<Value, Error> + 'closure>>,
234 visit_i32: Option<Box<dyn FnOnce(i32) -> Result<Value, Error> + 'closure>>,
235 visit_i64: Option<Box<dyn FnOnce(i64) -> Result<Value, Error> + 'closure>>,
236 visit_i128: Option<Box<dyn FnOnce(i128) -> Result<Value, Error> + 'closure>>,
237 visit_u8: Option<Box<dyn FnOnce(u8) -> Result<Value, Error> + 'closure>>,
238 visit_u16: Option<Box<dyn FnOnce(u16) -> Result<Value, Error> + 'closure>>,
239 visit_u32: Option<Box<dyn FnOnce(u32) -> Result<Value, Error> + 'closure>>,
240 visit_u64: Option<Box<dyn FnOnce(u64) -> Result<Value, Error> + 'closure>>,
241 visit_u128: Option<Box<dyn FnOnce(u128) -> Result<Value, Error> + 'closure>>,
242 visit_f32: Option<Box<dyn FnOnce(f32) -> Result<Value, Error> + 'closure>>,
243 visit_f64: Option<Box<dyn FnOnce(f64) -> Result<Value, Error> + 'closure>>,
244 visit_char: Option<Box<dyn FnOnce(char) -> Result<Value, Error> + 'closure>>,
245 visit_str: Option<Box<dyn FnOnce(&str) -> Result<Value, Error> + 'closure>>,
246 visit_borrowed_str: Option<Box<dyn FnOnce(&'de str) -> Result<Value, Error> + 'closure>>,
247 visit_bytes: Option<Box<dyn FnOnce(&[u8]) -> Result<Value, Error> + 'closure>>,
248 visit_borrowed_bytes: Option<Box<dyn FnOnce(&'de [u8]) -> Result<Value, Error> + 'closure>>,
249 visit_byte_buf: Option<Box<dyn FnOnce(Vec<u8>) -> Result<Value, Error> + 'closure>>,
250 visit_none: Option<Box<dyn FnOnce() -> Result<Value, Error> + 'closure>>,
251 visit_unit: Option<Box<dyn FnOnce() -> Result<Value, Error> + 'closure>>,
252 visit_seq:
253 Option<Box<dyn for<'access> FnOnce(Seq<'access, 'de>) -> Result<Value, Error> + 'closure>>,
254 visit_map:
255 Option<Box<dyn for<'access> FnOnce(Map<'access, 'de>) -> Result<Value, Error> + 'closure>>,
256}
257
258impl<'closure, 'de, Value> UntaggedEnumVisitor<'closure, 'de, Value> {
259 pub fn new() -> Self {
260 UntaggedEnumVisitor {
261 expecting: None,
262 visit_bool: None,
263 visit_i8: None,
264 visit_i16: None,
265 visit_i32: None,
266 visit_i64: None,
267 visit_i128: None,
268 visit_u8: None,
269 visit_u16: None,
270 visit_u32: None,
271 visit_u64: None,
272 visit_u128: None,
273 visit_f32: None,
274 visit_f64: None,
275 visit_char: None,
276 visit_str: None,
277 visit_borrowed_str: None,
278 visit_bytes: None,
279 visit_borrowed_bytes: None,
280 visit_byte_buf: None,
281 visit_none: None,
282 visit_unit: None,
283 visit_seq: None,
284 visit_map: None,
285 }
286 }
287
288 #[must_use]
344 pub fn expecting(mut self, expecting: impl Display + 'closure) -> Self {
345 if self.expecting.is_some() {
346 panic!("UntaggedEnumVisitor::expecting already set");
347 }
348 self.expecting = Some(Box::new(expecting));
349 self
350 }
351
352 #[must_use]
353 pub fn bool(mut self, visit: impl FnOnce(bool) -> Result<Value, Error> + 'closure) -> Self {
354 if self.visit_bool.is_some() {
355 panic!("UntaggedEnumVisitor::bool already set");
356 }
357 self.visit_bool = Some(Box::new(visit));
358 self
359 }
360
361 #[must_use]
362 pub fn i8(mut self, visit: impl FnOnce(i8) -> Result<Value, Error> + 'closure) -> Self {
363 if self.visit_i8.is_some() {
364 panic!("UntaggedEnumVisitor::i8 already set");
365 }
366 self.visit_i8 = Some(Box::new(visit));
367 self
368 }
369
370 #[must_use]
371 pub fn i16(mut self, visit: impl FnOnce(i16) -> Result<Value, Error> + 'closure) -> Self {
372 if self.visit_i16.is_some() {
373 panic!("UntaggedEnumVisitor::i16 already set");
374 }
375 self.visit_i16 = Some(Box::new(visit));
376 self
377 }
378
379 #[must_use]
380 pub fn i32(mut self, visit: impl FnOnce(i32) -> Result<Value, Error> + 'closure) -> Self {
381 if self.visit_i32.is_some() {
382 panic!("UntaggedEnumVisitor::i32 already set");
383 }
384 self.visit_i32 = Some(Box::new(visit));
385 self
386 }
387
388 #[must_use]
389 pub fn i64(mut self, visit: impl FnOnce(i64) -> Result<Value, Error> + 'closure) -> Self {
390 if self.visit_i64.is_some() {
391 panic!("UntaggedEnumVisitor::i64 already set");
392 }
393 self.visit_i64 = Some(Box::new(visit));
394 self
395 }
396
397 #[must_use]
398 pub fn i128(mut self, visit: impl FnOnce(i128) -> Result<Value, Error> + 'closure) -> Self {
399 if self.visit_i128.is_some() {
400 panic!("UntaggedEnumVisitor::i128 already set");
401 }
402 self.visit_i128 = Some(Box::new(visit));
403 self
404 }
405
406 #[must_use]
407 pub fn u8(mut self, visit: impl FnOnce(u8) -> Result<Value, Error> + 'closure) -> Self {
408 if self.visit_u8.is_some() {
409 panic!("UntaggedEnumVisitor::u8 already set");
410 }
411 self.visit_u8 = Some(Box::new(visit));
412 self
413 }
414
415 #[must_use]
416 pub fn u16(mut self, visit: impl FnOnce(u16) -> Result<Value, Error> + 'closure) -> Self {
417 if self.visit_u16.is_some() {
418 panic!("UntaggedEnumVisitor::u16 already set");
419 }
420 self.visit_u16 = Some(Box::new(visit));
421 self
422 }
423
424 #[must_use]
425 pub fn u32(mut self, visit: impl FnOnce(u32) -> Result<Value, Error> + 'closure) -> Self {
426 if self.visit_u32.is_some() {
427 panic!("UntaggedEnumVisitor::u32 already set");
428 }
429 self.visit_u32 = Some(Box::new(visit));
430 self
431 }
432
433 #[must_use]
434 pub fn u64(mut self, visit: impl FnOnce(u64) -> Result<Value, Error> + 'closure) -> Self {
435 if self.visit_u64.is_some() {
436 panic!("UntaggedEnumVisitor::u64 already set");
437 }
438 self.visit_u64 = Some(Box::new(visit));
439 self
440 }
441
442 #[must_use]
443 pub fn u128(mut self, visit: impl FnOnce(u128) -> Result<Value, Error> + 'closure) -> Self {
444 if self.visit_u128.is_some() {
445 panic!("UntaggedEnumVisitor::u128 already set");
446 }
447 self.visit_u128 = Some(Box::new(visit));
448 self
449 }
450
451 #[must_use]
452 pub fn f32(mut self, visit: impl FnOnce(f32) -> Result<Value, Error> + 'closure) -> Self {
453 if self.visit_f32.is_some() {
454 panic!("UntaggedEnumVisitor::f32 already set");
455 }
456 self.visit_f32 = Some(Box::new(visit));
457 self
458 }
459
460 #[must_use]
461 pub fn f64(mut self, visit: impl FnOnce(f64) -> Result<Value, Error> + 'closure) -> Self {
462 if self.visit_f64.is_some() {
463 panic!("UntaggedEnumVisitor::f64 already set");
464 }
465 self.visit_f64 = Some(Box::new(visit));
466 self
467 }
468
469 #[must_use]
470 pub fn char(mut self, visit: impl FnOnce(char) -> Result<Value, Error> + 'closure) -> Self {
471 if self.visit_char.is_some() {
472 panic!("UntaggedEnumVisitor::char already set");
473 }
474 self.visit_char = Some(Box::new(visit));
475 self
476 }
477
478 #[must_use]
479 pub fn string(mut self, visit: impl FnOnce(&str) -> Result<Value, Error> + 'closure) -> Self {
480 if self.visit_str.is_some() {
481 panic!("UntaggedEnumVisitor::string already set");
482 }
483 self.visit_str = Some(Box::new(visit));
484 self
485 }
486
487 #[must_use]
488 pub fn borrowed_str(
489 mut self,
490 visit: impl FnOnce(&'de str) -> Result<Value, Error> + 'closure,
491 ) -> Self {
492 if self.visit_borrowed_str.is_some() {
493 panic!("UntaggedEnumVisitor::borrowed_str already set");
494 }
495 self.visit_borrowed_str = Some(Box::new(visit));
496 self
497 }
498
499 #[must_use]
500 pub fn bytes(mut self, visit: impl FnOnce(&[u8]) -> Result<Value, Error> + 'closure) -> Self {
501 if self.visit_bytes.is_some() {
502 panic!("UntaggedEnumVisitor::bytes already set");
503 }
504 self.visit_bytes = Some(Box::new(visit));
505 self
506 }
507
508 #[must_use]
509 pub fn borrowed_bytes(
510 mut self,
511 visit: impl FnOnce(&'de [u8]) -> Result<Value, Error> + 'closure,
512 ) -> Self {
513 if self.visit_borrowed_bytes.is_some() {
514 panic!("UntaggedEnumVisitor::borrowed_bytes already set");
515 }
516 self.visit_borrowed_bytes = Some(Box::new(visit));
517 self
518 }
519
520 #[must_use]
521 pub fn byte_buf(
522 mut self,
523 visit: impl FnOnce(Vec<u8>) -> Result<Value, Error> + 'closure,
524 ) -> Self {
525 if self.visit_byte_buf.is_some() {
526 panic!("UntaggedEnumVisitor::byte_buf already set");
527 }
528 self.visit_byte_buf = Some(Box::new(visit));
529 self
530 }
531
532 #[must_use]
533 pub fn none(mut self, visit: impl FnOnce() -> Result<Value, Error> + 'closure) -> Self {
534 if self.visit_none.is_some() {
535 panic!("UntaggedEnumVisitor::none already set");
536 }
537 self.visit_none = Some(Box::new(visit));
538 self
539 }
540
541 #[must_use]
542 pub fn unit(mut self, visit: impl FnOnce() -> Result<Value, Error> + 'closure) -> Self {
543 if self.visit_unit.is_some() {
544 panic!("UntaggedEnumVisitor::unit already set");
545 }
546 self.visit_unit = Some(Box::new(visit));
547 self
548 }
549
550 #[must_use]
553 pub fn seq(
554 mut self,
555 visit: impl for<'access> FnOnce(Seq<'access, 'de>) -> Result<Value, Error> + 'closure,
556 ) -> Self {
557 if self.visit_seq.is_some() {
558 panic!("UntaggedEnumVisitor::seq already set");
559 }
560 self.visit_seq = Some(Box::new(visit));
561 self
562 }
563
564 #[must_use]
624 pub fn map(
625 mut self,
626 visit: impl for<'access> FnOnce(Map<'access, 'de>) -> Result<Value, Error> + 'closure,
627 ) -> Self {
628 if self.visit_map.is_some() {
629 panic!("UntaggedEnumVisitor::map already set");
630 }
631 self.visit_map = Some(Box::new(visit));
632 self
633 }
634
635 pub fn deserialize<D>(self, deserializer: D) -> Result<Value, D::Error>
636 where
637 D: Deserializer<'de>,
638 {
639 deserializer.deserialize_any(self)
640 }
641}
642
643impl<'closure, 'de, Value> Visitor<'de> for UntaggedEnumVisitor<'closure, 'de, Value> {
644 type Value = Value;
645
646 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
647 if let Some(expecting) = &self.expecting {
648 return expecting.fmt(formatter);
649 }
650
651 let mut message = Expecting::new(formatter);
654 if self.visit_bool.is_some() {
655 message.push("a", "boolean")?;
656 }
657 if self.visit_i8.is_some()
658 || self.visit_i16.is_some()
659 || self.visit_i32.is_some()
660 || self.visit_i64.is_some()
661 || self.visit_i128.is_some()
662 || self.visit_u8.is_some()
663 || self.visit_u16.is_some()
664 || self.visit_u32.is_some()
665 || self.visit_u64.is_some()
666 || self.visit_u128.is_some()
667 {
668 message.push("an", "integer")?;
669 }
670 if self.visit_f32.is_some() || self.visit_f64.is_some() {
671 message.push("a", "float")?;
672 }
673 if self.visit_char.is_some() {
674 message.push("a", "character")?;
675 }
676 if self.visit_str.is_some() {
677 message.push("a", "string")?;
678 }
679 if self.visit_borrowed_str.is_some() && self.visit_str.is_none() {
680 message.push("a", "borrowed string")?;
681 }
682 if self.visit_bytes.is_some()
683 || self.visit_borrowed_bytes.is_some()
684 || self.visit_byte_buf.is_some()
685 {
686 message.push("a", "byte array")?;
687 }
688 if self.visit_unit.is_some() || self.visit_none.is_some() {
689 message.push("", "null")?;
690 }
691 if self.visit_seq.is_some() {
692 message.push("an", "array")?;
693 }
694 if self.visit_map.is_some() {
695 message.push("a", "map")?;
696 }
697 message.flush()
698 }
699
700 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
701 where
702 E: serde::de::Error,
703 {
704 if let Some(visit_bool) = self.visit_bool {
705 visit_bool(v).map_err(error::unerase)
706 } else {
707 DefaultVisitor::new(&self).visit_bool(v)
708 }
709 }
710
711 fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
712 where
713 E: serde::de::Error,
714 {
715 use crate::int::IntKind::*;
716 self.dispatch_integer(v, [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128])
717 }
718
719 fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
720 where
721 E: serde::de::Error,
722 {
723 use crate::int::IntKind::*;
724 self.dispatch_integer(v, [I16, I32, I64, I128, I8, U8, U16, U32, U64, U128])
725 }
726
727 fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
728 where
729 E: serde::de::Error,
730 {
731 use crate::int::IntKind::*;
732 self.dispatch_integer(v, [I32, I64, I128, I8, I16, U8, U16, U32, U64, U128])
733 }
734
735 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
736 where
737 E: serde::de::Error,
738 {
739 use crate::int::IntKind::*;
740 self.dispatch_integer(v, [I64, I128, I8, I16, I32, U8, U16, U32, U64, U128])
741 }
742
743 fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
744 where
745 E: serde::de::Error,
746 {
747 use crate::int::IntKind::*;
748 self.dispatch_integer(v, [I128, I8, I16, I32, I64, U8, U16, U32, U64, U128])
749 }
750
751 fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
752 where
753 E: serde::de::Error,
754 {
755 use crate::int::IntKind::*;
756 self.dispatch_integer(v, [U8, U16, U32, U64, U128, I8, I16, I32, I64, I128])
757 }
758
759 fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
760 where
761 E: serde::de::Error,
762 {
763 use crate::int::IntKind::*;
764 self.dispatch_integer(v, [U16, U32, U64, U128, U8, I8, I16, I32, I64, I128])
765 }
766
767 fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
768 where
769 E: serde::de::Error,
770 {
771 use crate::int::IntKind::*;
772 self.dispatch_integer(v, [U32, U64, U128, U8, U16, I8, I16, I32, I64, I128])
773 }
774
775 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
776 where
777 E: serde::de::Error,
778 {
779 use crate::int::IntKind::*;
780 self.dispatch_integer(v, [U64, U128, U8, U16, U32, I8, I16, I32, I64, I128])
781 }
782
783 fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
784 where
785 E: serde::de::Error,
786 {
787 use crate::int::IntKind::*;
788 self.dispatch_integer(v, [U128, U8, U16, U32, U64, I8, I16, I32, I64, I128])
789 }
790
791 fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
792 where
793 E: serde::de::Error,
794 {
795 if let Some(visit_f32) = self.visit_f32 {
796 visit_f32(v).map_err(error::unerase)
797 } else {
798 self.visit_f64(f64::from(v))
799 }
800 }
801
802 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
803 where
804 E: serde::de::Error,
805 {
806 if let Some(visit_f64) = self.visit_f64 {
807 visit_f64(v).map_err(error::unerase)
808 } else {
809 DefaultVisitor::new(&self).visit_f64(v)
810 }
811 }
812
813 fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
814 where
815 E: serde::de::Error,
816 {
817 if let Some(visit_char) = self.visit_char {
818 visit_char(v).map_err(error::unerase)
819 } else if self.visit_str.is_some() {
820 self.visit_str(v.encode_utf8(&mut [0u8; 4]))
821 } else {
822 Err(E::invalid_type(Unexpected::Char(v), &self))
823 }
824 }
825
826 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
827 where
828 E: serde::de::Error,
829 {
830 if let Some(visit_str) = self.visit_str {
831 visit_str(v).map_err(error::unerase)
832 } else {
833 DefaultVisitor::new(&self).visit_str(v)
834 }
835 }
836
837 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
838 where
839 E: serde::de::Error,
840 {
841 if let Some(visit_borrowed_str) = self.visit_borrowed_str {
842 visit_borrowed_str(v).map_err(error::unerase)
843 } else {
844 self.visit_str(v)
845 }
846 }
847
848 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
849 where
850 E: serde::de::Error,
851 {
852 if let Some(visit_bytes) = self.visit_bytes {
853 visit_bytes(v).map_err(error::unerase)
854 } else {
855 DefaultVisitor::new(&self).visit_bytes(v)
856 }
857 }
858
859 fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
860 where
861 E: serde::de::Error,
862 {
863 if let Some(visit_borrowed_bytes) = self.visit_borrowed_bytes {
864 visit_borrowed_bytes(v).map_err(error::unerase)
865 } else {
866 self.visit_bytes(v)
867 }
868 }
869
870 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
871 where
872 E: serde::de::Error,
873 {
874 if let Some(visit_byte_buf) = self.visit_byte_buf {
875 visit_byte_buf(v).map_err(error::unerase)
876 } else {
877 self.visit_bytes(&v)
878 }
879 }
880
881 fn visit_none<E>(self) -> Result<Self::Value, E>
882 where
883 E: serde::de::Error,
884 {
885 if let Some(visit_none) = self.visit_none {
886 visit_none().map_err(error::unerase)
887 } else {
888 DefaultVisitor::new(&self).visit_none()
889 }
890 }
891
892 fn visit_unit<E>(self) -> Result<Self::Value, E>
893 where
894 E: serde::de::Error,
895 {
896 if let Some(visit_unit) = self.visit_unit {
897 visit_unit().map_err(error::unerase)
898 } else {
899 DefaultVisitor::new(&self).visit_unit()
900 }
901 }
902
903 fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
904 where
905 A: SeqAccess<'de>,
906 {
907 if let Some(visit_seq) = self.visit_seq {
908 visit_seq(Seq::new(seq)).map_err(error::unerase)
909 } else {
910 DefaultVisitor::new(&self).visit_seq(seq)
911 }
912 }
913
914 fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
915 where
916 A: MapAccess<'de>,
917 {
918 if let Some(visit_map) = self.visit_map {
919 visit_map(Map::new(map)).map_err(error::unerase)
920 } else {
921 DefaultVisitor::new(&self).visit_map(map)
922 }
923 }
924}
925
926struct DefaultVisitor<'a, E, T> {
927 expected: &'a E,
928 value: PhantomData<T>,
929}
930
931impl<'a, E, T> DefaultVisitor<'a, E, T> {
932 fn new(expected: &'a E) -> Self {
933 DefaultVisitor {
934 expected,
935 value: PhantomData,
936 }
937 }
938}
939
940impl<'a, 'de, V, T> Visitor<'de> for DefaultVisitor<'a, V, T>
941where
942 V: Expected,
943{
944 type Value = T;
945
946 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
947 self.expected.fmt(formatter)
948 }
949}
950
951struct Expecting<'e, 'a> {
952 formatter: &'e mut fmt::Formatter<'a>,
953 count: usize,
954 last: Option<&'e str>,
955}
956
957impl<'e, 'a> Expecting<'e, 'a> {
958 fn new(formatter: &'e mut fmt::Formatter<'a>) -> Self {
959 Expecting {
960 formatter,
961 count: 0,
962 last: None,
963 }
964 }
965
966 fn push(&mut self, article: &str, item: &'e str) -> fmt::Result {
967 self.count += 1;
968 if self.count == 1 {
969 if !article.is_empty() {
970 self.formatter.write_str(article)?;
971 self.formatter.write_str(" ")?;
972 }
973 self.formatter.write_str(item)?;
974 } else {
975 if let Some(last) = self.last.take() {
976 self.formatter.write_str(", ")?;
977 self.formatter.write_str(last)?;
978 }
979 self.last = Some(item);
980 }
981 Ok(())
982 }
983
984 fn flush(&mut self) -> fmt::Result {
985 if self.count == 0 {
986 self.formatter.write_str("unspecified") } else if let Some(last) = self.last.take() {
988 self.formatter.write_str(" or ")?;
989 self.formatter.write_str(last)
990 } else {
991 Ok(())
992 }
993 }
994}