Skip to main content

jstrict/serde/
de.rs

1use serde::{
2	Deserialize,
3	de::{
4		DeserializeSeed, EnumAccess, Expected, IntoDeserializer, MapAccess, SeqAccess, Unexpected,
5		VariantAccess, Visitor,
6	},
7	forward_to_deserialize_any,
8};
9use std::fmt;
10
11use crate::{
12	Array, NumberBuf, Object, Value,
13	object::{Entry, Key},
14};
15
16use super::NUMBER_TOKEN;
17
18impl Value {
19	#[cold]
20	fn invalid_type<E>(&self, exp: &dyn Expected) -> E
21	where
22		E: serde::de::Error,
23	{
24		serde::de::Error::invalid_type(self.unexpected(), exp)
25	}
26
27	#[cold]
28	fn unexpected(&self) -> Unexpected<'_> {
29		match self {
30			Self::Null => Unexpected::Unit,
31			Self::Boolean(b) => Unexpected::Bool(*b),
32			Self::Number(n) => match n.as_u64() {
33				Some(u) => Unexpected::Unsigned(u),
34				None => match n.as_i64() {
35					Some(i) => Unexpected::Signed(i),
36					None => Unexpected::Float(n.as_f64_lossy()),
37				},
38			},
39			Self::String(s) => Unexpected::Str(s),
40			Self::Array(_) => Unexpected::Seq,
41			Self::Object(_) => Unexpected::Map,
42		}
43	}
44}
45
46impl<'de> Deserialize<'de> for Value {
47	#[inline]
48	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
49	where
50		D: serde::Deserializer<'de>,
51	{
52		struct ValueVisitor;
53
54		impl<'de> Visitor<'de> for ValueVisitor {
55			type Value = Value;
56
57			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
58				formatter.write_str("any valid JSON value")
59			}
60
61			#[inline]
62			fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
63				Ok(Value::Boolean(value))
64			}
65
66			#[inline]
67			fn visit_i64<E>(self, value: i64) -> Result<Value, E> {
68				Ok(Value::Number(value.into()))
69			}
70
71			#[inline]
72			fn visit_u64<E>(self, value: u64) -> Result<Value, E> {
73				Ok(Value::Number(value.into()))
74			}
75
76			#[inline]
77			fn visit_f64<E>(self, value: f64) -> Result<Value, E> {
78				Ok(NumberBuf::try_from(value).map_or(Value::Null, Value::Number))
79			}
80
81			#[inline]
82			fn visit_str<E>(self, value: &str) -> Result<Value, E>
83			where
84				E: serde::de::Error,
85			{
86				Ok(Value::String(value.into()))
87			}
88
89			#[inline]
90			fn visit_string<E>(self, value: String) -> Result<Value, E> {
91				Ok(Value::String(value.into()))
92			}
93
94			#[inline]
95			fn visit_none<E>(self) -> Result<Value, E> {
96				Ok(Value::Null)
97			}
98
99			#[inline]
100			fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
101			where
102				D: serde::Deserializer<'de>,
103			{
104				Deserialize::deserialize(deserializer)
105			}
106
107			#[inline]
108			fn visit_unit<E>(self) -> Result<Value, E> {
109				Ok(Value::Null)
110			}
111
112			#[inline]
113			fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
114			where
115				V: SeqAccess<'de>,
116			{
117				let mut vec = Vec::with_capacity(visitor.size_hint().unwrap_or(0));
118
119				while let Some(elem) = visitor.next_element()? {
120					vec.push(elem);
121				}
122
123				Ok(Value::Array(vec))
124			}
125
126			fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
127			where
128				V: MapAccess<'de>,
129			{
130				enum MapTag {
131					Number,
132					None(Key),
133				}
134
135				impl<'de> Deserialize<'de> for MapTag {
136					fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
137					where
138						D: serde::Deserializer<'de>,
139					{
140						struct Visitor;
141
142						impl<'de> serde::de::Visitor<'de> for Visitor {
143							type Value = MapTag;
144
145							fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
146								formatter.write_str("a string key")
147							}
148
149							fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
150							where
151								E: serde::de::Error,
152							{
153								if v == NUMBER_TOKEN {
154									Ok(MapTag::Number)
155								} else {
156									Ok(MapTag::None(v.into()))
157								}
158							}
159
160							fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
161							where
162								E: serde::de::Error,
163							{
164								if v == NUMBER_TOKEN {
165									Ok(MapTag::Number)
166								} else {
167									Ok(MapTag::None(v.into()))
168								}
169							}
170						}
171
172						deserializer.deserialize_string(Visitor)
173					}
174				}
175
176				match visitor.next_key()? {
177					Some(MapTag::Number) => {
178						let value: String = visitor.next_value()?;
179						NumberBuf::new(value.into_bytes().into())
180							.map(Value::Number)
181							.map_err(|crate::number::InvalidNumber(bytes)| {
182								serde::de::Error::custom(crate::number::InvalidNumber(
183									String::from_utf8(bytes.into_vec()).unwrap(),
184								))
185							})
186					}
187					Some(MapTag::None(key)) => {
188						let cap = visitor.size_hint().unwrap_or(0);
189						let mut object = Object::with_capacity(cap);
190
191						object.push(key, visitor.next_value()?);
192						while let Some((key, value)) = visitor.next_entry()? {
193							object.push(key, value);
194						}
195
196						Ok(Value::Object(object))
197					}
198					None => Ok(Value::Object(Object::new())),
199				}
200			}
201		}
202
203		deserializer.deserialize_any(ValueVisitor)
204	}
205}
206
207impl<'de> IntoDeserializer<'de, DeserializeError> for Value {
208	type Deserializer = Self;
209
210	fn into_deserializer(self) -> Self::Deserializer {
211		self
212	}
213}
214
215impl<'de> Deserialize<'de> for Object {
216	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
217	where
218		D: serde::Deserializer<'de>,
219	{
220		struct Visitor;
221
222		impl<'de> serde::de::Visitor<'de> for Visitor {
223			type Value = Object;
224
225			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
226				write!(formatter, "a JSON object")
227			}
228
229			fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
230			where
231				A: MapAccess<'de>,
232			{
233				let cap = map.size_hint().unwrap_or(0);
234				let mut object = Object::with_capacity(cap);
235
236				while let Some((key, value)) = map.next_entry()? {
237					object.push(key, value);
238				}
239
240				Ok(object)
241			}
242		}
243
244		deserializer.deserialize_map(Visitor)
245	}
246}
247
248impl<'de> IntoDeserializer<'de, DeserializeError> for Object {
249	type Deserializer = Value;
250
251	fn into_deserializer(self) -> Self::Deserializer {
252		Value::Object(self)
253	}
254}
255
256/// Error returned when deserializing a type from a [`Value`].
257#[derive(Debug, Clone)]
258pub enum DeserializeError {
259	/// Error reported by the `Deserialize` implementation.
260	Custom(String),
261
262	/// A map key was not a string, which JSON cannot represent.
263	NonStringKey,
264}
265
266impl fmt::Display for DeserializeError {
267	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
268		match self {
269			Self::Custom(msg) => msg.fmt(f),
270			Self::NonStringKey => write!(f, "key must be a string"),
271		}
272	}
273}
274
275impl From<crate::number::serde::Unexpected> for DeserializeError {
276	fn from(value: crate::number::serde::Unexpected) -> Self {
277		Self::Custom(value.to_string())
278	}
279}
280
281impl std::error::Error for DeserializeError {}
282
283impl serde::de::Error for DeserializeError {
284	fn custom<T>(msg: T) -> Self
285	where
286		T: fmt::Display,
287	{
288		Self::Custom(msg.to_string())
289	}
290}
291
292macro_rules! deserialize_number {
293	($method:ident) => {
294		fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
295		where
296			V: serde::de::Visitor<'de>,
297		{
298			match self {
299				Value::Number(n) => Ok(n.deserialize_any(visitor)?),
300				_ => Err(self.invalid_type(&visitor)),
301			}
302		}
303	};
304}
305
306impl<'de> serde::Deserializer<'de> for Value {
307	type Error = DeserializeError;
308
309	#[inline]
310	fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
311	where
312		V: serde::de::Visitor<'de>,
313	{
314		match self {
315			Self::Null => visitor.visit_unit(),
316			Self::Boolean(v) => visitor.visit_bool(v),
317			Self::Number(n) => Ok(n.deserialize_any(visitor)?),
318			Self::String(s) => visitor.visit_string(s.into_string()),
319			Self::Array(a) => visit_array(a, visitor),
320			Self::Object(o) => visit_object(o, visitor),
321		}
322	}
323
324	deserialize_number!(deserialize_i8);
325	deserialize_number!(deserialize_i16);
326	deserialize_number!(deserialize_i32);
327	deserialize_number!(deserialize_i64);
328	deserialize_number!(deserialize_i128);
329	deserialize_number!(deserialize_u8);
330	deserialize_number!(deserialize_u16);
331	deserialize_number!(deserialize_u32);
332	deserialize_number!(deserialize_u64);
333	deserialize_number!(deserialize_u128);
334	deserialize_number!(deserialize_f32);
335	deserialize_number!(deserialize_f64);
336
337	#[inline]
338	fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
339	where
340		V: serde::de::Visitor<'de>,
341	{
342		match self {
343			Value::Null => visitor.visit_none(),
344			_ => visitor.visit_some(self),
345		}
346	}
347
348	#[inline]
349	fn deserialize_enum<V>(
350		self,
351		_name: &str,
352		_variants: &'static [&'static str],
353		visitor: V,
354	) -> Result<V::Value, Self::Error>
355	where
356		V: serde::de::Visitor<'de>,
357	{
358		let (variant, value) = match self {
359			Value::Object(value) => {
360				let mut iter = value.into_iter();
361				let Entry {
362					key: variant,
363					value,
364				} = match iter.next() {
365					Some(v) => v,
366					None => {
367						return Err(serde::de::Error::invalid_value(
368							Unexpected::Map,
369							&"map with a single key",
370						));
371					}
372				};
373				// enums are encoded in json as maps with a single key:value pair
374				if iter.next().is_some() {
375					return Err(serde::de::Error::invalid_value(
376						Unexpected::Map,
377						&"map with a single key",
378					));
379				}
380				(variant, Some(value))
381			}
382			Value::String(variant) => (variant, None),
383			other => {
384				return Err(serde::de::Error::invalid_type(
385					other.unexpected(),
386					&"string or map",
387				));
388			}
389		};
390
391		visitor.visit_enum(EnumDeserializer { variant, value })
392	}
393
394	#[inline]
395	fn deserialize_newtype_struct<V>(
396		self,
397		_name: &'static str,
398		visitor: V,
399	) -> Result<V::Value, Self::Error>
400	where
401		V: serde::de::Visitor<'de>,
402	{
403		visitor.visit_newtype_struct(self)
404	}
405
406	fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
407	where
408		V: serde::de::Visitor<'de>,
409	{
410		match self {
411			Value::Boolean(v) => visitor.visit_bool(v),
412			_ => Err(self.invalid_type(&visitor)),
413		}
414	}
415
416	fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
417	where
418		V: serde::de::Visitor<'de>,
419	{
420		self.deserialize_string(visitor)
421	}
422
423	fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
424	where
425		V: serde::de::Visitor<'de>,
426	{
427		self.deserialize_string(visitor)
428	}
429
430	fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
431	where
432		V: serde::de::Visitor<'de>,
433	{
434		match self {
435			Value::String(v) => visitor.visit_string(v.into_string()),
436			_ => Err(self.invalid_type(&visitor)),
437		}
438	}
439
440	fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
441	where
442		V: serde::de::Visitor<'de>,
443	{
444		self.deserialize_byte_buf(visitor)
445	}
446
447	fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
448	where
449		V: serde::de::Visitor<'de>,
450	{
451		match self {
452			Value::String(v) => visitor.visit_string(v.into_string()),
453			Value::Array(v) => visit_array(v, visitor),
454			_ => Err(self.invalid_type(&visitor)),
455		}
456	}
457
458	fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
459	where
460		V: serde::de::Visitor<'de>,
461	{
462		match self {
463			Value::Null => visitor.visit_unit(),
464			_ => Err(self.invalid_type(&visitor)),
465		}
466	}
467
468	fn deserialize_unit_struct<V>(
469		self,
470		_name: &'static str,
471		visitor: V,
472	) -> Result<V::Value, Self::Error>
473	where
474		V: serde::de::Visitor<'de>,
475	{
476		self.deserialize_unit(visitor)
477	}
478
479	fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
480	where
481		V: serde::de::Visitor<'de>,
482	{
483		match self {
484			Value::Array(v) => visit_array(v, visitor),
485			_ => Err(self.invalid_type(&visitor)),
486		}
487	}
488
489	fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
490	where
491		V: serde::de::Visitor<'de>,
492	{
493		self.deserialize_seq(visitor)
494	}
495
496	fn deserialize_tuple_struct<V>(
497		self,
498		_name: &'static str,
499		_len: usize,
500		visitor: V,
501	) -> Result<V::Value, Self::Error>
502	where
503		V: serde::de::Visitor<'de>,
504	{
505		self.deserialize_seq(visitor)
506	}
507
508	fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
509	where
510		V: serde::de::Visitor<'de>,
511	{
512		match self {
513			Value::Object(v) => visit_object(v, visitor),
514			_ => Err(self.invalid_type(&visitor)),
515		}
516	}
517
518	fn deserialize_struct<V>(
519		self,
520		_name: &'static str,
521		_fields: &'static [&'static str],
522		visitor: V,
523	) -> Result<V::Value, Self::Error>
524	where
525		V: serde::de::Visitor<'de>,
526	{
527		match self {
528			Value::Array(v) => visit_array(v, visitor),
529			Value::Object(v) => visit_object(v, visitor),
530			_ => Err(self.invalid_type(&visitor)),
531		}
532	}
533
534	fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
535	where
536		V: serde::de::Visitor<'de>,
537	{
538		self.deserialize_string(visitor)
539	}
540
541	fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
542	where
543		V: serde::de::Visitor<'de>,
544	{
545		drop(self);
546		visitor.visit_unit()
547	}
548}
549
550fn visit_array<'de, V>(a: Array, visitor: V) -> Result<V::Value, DeserializeError>
551where
552	V: serde::de::Visitor<'de>,
553{
554	let len = a.len();
555	let mut deserializer = ArrayDeserializer::new(a);
556	let seq = visitor.visit_seq(&mut deserializer)?;
557	let remaining = deserializer.iter.len();
558	if remaining == 0 {
559		Ok(seq)
560	} else {
561		Err(serde::de::Error::invalid_length(
562			len,
563			&"fewer elements in array",
564		))
565	}
566}
567
568fn visit_object<'de, V>(o: Object, visitor: V) -> Result<V::Value, DeserializeError>
569where
570	V: serde::de::Visitor<'de>,
571{
572	let len = o.len();
573	let mut deserializer = ObjectDeserializer::new(o);
574	let map = visitor.visit_map(&mut deserializer)?;
575	let remaining = deserializer.iter.len();
576	if remaining == 0 {
577		Ok(map)
578	} else {
579		Err(serde::de::Error::invalid_length(
580			len,
581			&"fewer elements in map",
582		))
583	}
584}
585
586struct ArrayDeserializer {
587	iter: std::vec::IntoIter<Value>,
588}
589
590impl ArrayDeserializer {
591	fn new(array: Array) -> Self {
592		Self {
593			iter: array.into_iter(),
594		}
595	}
596}
597
598impl<'de> SeqAccess<'de> for ArrayDeserializer {
599	type Error = DeserializeError;
600
601	fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
602	where
603		T: DeserializeSeed<'de>,
604	{
605		match self.iter.next() {
606			Some(value) => seed.deserialize(value).map(Some),
607			None => Ok(None),
608		}
609	}
610
611	fn size_hint(&self) -> Option<usize> {
612		match self.iter.size_hint() {
613			(lower, Some(upper)) if lower == upper => Some(upper),
614			_ => None,
615		}
616	}
617}
618
619struct ObjectDeserializer {
620	iter: std::vec::IntoIter<Entry>,
621	value: Option<Value>,
622}
623
624impl ObjectDeserializer {
625	fn new(obj: Object) -> Self {
626		Self {
627			iter: obj.into_iter(),
628			value: None,
629		}
630	}
631}
632
633impl<'de> MapAccess<'de> for ObjectDeserializer {
634	type Error = DeserializeError;
635
636	fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
637	where
638		T: DeserializeSeed<'de>,
639	{
640		match self.iter.next() {
641			Some(Entry { key, value }) => {
642				self.value = Some(value);
643				let key_de = MapKeyDeserializer { key };
644				seed.deserialize(key_de).map(Some)
645			}
646			None => Ok(None),
647		}
648	}
649
650	fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
651	where
652		T: DeserializeSeed<'de>,
653	{
654		match self.value.take() {
655			Some(value) => seed.deserialize(value),
656			None => Err(serde::de::Error::custom("value is missing")),
657		}
658	}
659
660	fn size_hint(&self) -> Option<usize> {
661		match self.iter.size_hint() {
662			(lower, Some(upper)) if lower == upper => Some(upper),
663			_ => None,
664		}
665	}
666}
667
668struct MapKeyDeserializer {
669	key: Key,
670}
671
672macro_rules! deserialize_integer_key {
673	($method:ident => $visit:ident) => {
674		fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
675		where
676			V: serde::de::Visitor<'de>,
677		{
678			match (self.key.parse(), self.key) {
679				(Ok(integer), _) => visitor.$visit(integer),
680				(Err(_), key) => visitor.visit_string(key.into_string()),
681			}
682		}
683	};
684}
685
686impl<'de> serde::Deserializer<'de> for MapKeyDeserializer {
687	type Error = DeserializeError;
688
689	fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
690	where
691		V: serde::de::Visitor<'de>,
692	{
693		visitor.visit_string(self.key.into_string())
694	}
695
696	deserialize_integer_key!(deserialize_i8 => visit_i8);
697	deserialize_integer_key!(deserialize_i16 => visit_i16);
698	deserialize_integer_key!(deserialize_i32 => visit_i32);
699	deserialize_integer_key!(deserialize_i64 => visit_i64);
700	deserialize_integer_key!(deserialize_i128 => visit_i128);
701	deserialize_integer_key!(deserialize_u8 => visit_u8);
702	deserialize_integer_key!(deserialize_u16 => visit_u16);
703	deserialize_integer_key!(deserialize_u32 => visit_u32);
704	deserialize_integer_key!(deserialize_u64 => visit_u64);
705	deserialize_integer_key!(deserialize_u128 => visit_u128);
706
707	#[inline]
708	fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
709	where
710		V: serde::de::Visitor<'de>,
711	{
712		// Map keys cannot be null.
713		visitor.visit_some(self)
714	}
715
716	#[inline]
717	fn deserialize_newtype_struct<V>(
718		self,
719		_name: &'static str,
720		visitor: V,
721	) -> Result<V::Value, Self::Error>
722	where
723		V: serde::de::Visitor<'de>,
724	{
725		visitor.visit_newtype_struct(self)
726	}
727
728	fn deserialize_enum<V>(
729		self,
730		name: &'static str,
731		variants: &'static [&'static str],
732		visitor: V,
733	) -> Result<V::Value, Self::Error>
734	where
735		V: serde::de::Visitor<'de>,
736	{
737		self.key
738			.into_deserializer()
739			.deserialize_enum(name, variants, visitor)
740	}
741
742	forward_to_deserialize_any! {
743		bool f32 f64 char str string bytes byte_buf unit unit_struct seq tuple
744		tuple_struct map struct identifier ignored_any
745	}
746}
747
748struct EnumDeserializer {
749	variant: Key,
750	value: Option<Value>,
751}
752
753impl<'de> EnumAccess<'de> for EnumDeserializer {
754	type Error = DeserializeError;
755	type Variant = VariantDeserializer;
756
757	fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Self::Error>
758	where
759		V: DeserializeSeed<'de>,
760	{
761		let variant = self.variant.into_deserializer();
762		let visitor = VariantDeserializer { value: self.value };
763		seed.deserialize(variant).map(|v| (v, visitor))
764	}
765}
766
767struct VariantDeserializer {
768	value: Option<Value>,
769}
770
771impl<'de> VariantAccess<'de> for VariantDeserializer {
772	type Error = DeserializeError;
773
774	fn unit_variant(self) -> Result<(), Self::Error> {
775		match self.value {
776			Some(value) => serde::Deserialize::deserialize(value),
777			None => Ok(()),
778		}
779	}
780
781	fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
782	where
783		T: DeserializeSeed<'de>,
784	{
785		match self.value {
786			Some(value) => seed.deserialize(value),
787			None => Err(serde::de::Error::invalid_type(
788				Unexpected::UnitVariant,
789				&"newtype variant",
790			)),
791		}
792	}
793
794	fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
795	where
796		V: serde::de::Visitor<'de>,
797	{
798		match self.value {
799			Some(Value::Array(v)) => {
800				if v.is_empty() {
801					visitor.visit_unit()
802				} else {
803					visit_array(v, visitor)
804				}
805			}
806			Some(other) => Err(serde::de::Error::invalid_type(
807				other.unexpected(),
808				&"tuple variant",
809			)),
810			None => Err(serde::de::Error::invalid_type(
811				Unexpected::UnitVariant,
812				&"tuple variant",
813			)),
814		}
815	}
816
817	fn struct_variant<V>(
818		self,
819		_fields: &'static [&'static str],
820		visitor: V,
821	) -> Result<V::Value, Self::Error>
822	where
823		V: serde::de::Visitor<'de>,
824	{
825		match self.value {
826			Some(Value::Object(v)) => visit_object(v, visitor),
827			Some(other) => Err(serde::de::Error::invalid_type(
828				other.unexpected(),
829				&"struct variant",
830			)),
831			None => Err(serde::de::Error::invalid_type(
832				Unexpected::UnitVariant,
833				&"struct variant",
834			)),
835		}
836	}
837}