1use byteorder::{ByteOrder, LittleEndian, ReadBytesExt};
2use hash40::Hash40;
3use indexmap::IndexMap;
4use serde::{
5 de::{MapAccess, SeqAccess, Visitor},
6 forward_to_deserialize_any, Deserialize, Deserializer,
7};
8use std::{
9 collections::HashMap,
10 fmt::{Debug, Display},
11 io::{Read, Seek, SeekFrom},
12};
13use thiserror::Error;
14
15use crate::{ParamId, Value};
16
17#[derive(Debug)]
18enum ParseId {
19 ParamId,
20 Bool,
21 I8,
22 U8,
23 I16,
24 U16,
25 I32,
26 U32,
27 F32,
28 Hash,
29 String,
30 List,
31 Map,
32}
33
34pub struct Error {
35 cause: ErrorKind,
36 position_stack: Vec<(ParseId, Option<u64>)>,
37}
38
39impl Debug for Error {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 Display::fmt(self, f)
42 }
43}
44
45impl Display for Error {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 write!(f, "{}", self.cause)?;
48 for (id, position) in self.position_stack.iter() {
49 if let Some(position) = position {
50 write!(f, "\nwhile parsing {id:?} @ {position:#x}")?;
51 } else {
52 write!(f, "\nwhile parsing {id:?} @ <unknown>")?;
53 }
54 }
55
56 Ok(())
57 }
58}
59
60impl std::error::Error for Error {}
61
62#[derive(Error, Debug)]
63pub enum ErrorKind {
64 #[error("Invalid param id {0:#x}")]
65 InvalidParamId(u8),
66
67 #[error("Hash param points out of bounds (index {0:#x})")]
68 HashOutOfBounds(usize),
69
70 #[error("String reference points out of bounds (start index {0:#x})")]
71 StringRefOutOfBounds(usize),
72
73 #[error("String data is not ascii (problem byte at {0:#x})")]
74 StringNotAscii(usize),
75
76 #[error(
77 "Map reference points of out bounds (start index {start:#x}, num elements {num_elements})"
78 )]
79 MapRefOutOfBounds { start: usize, num_elements: usize },
80
81 #[error(transparent)]
82 IO(#[from] std::io::Error),
83
84 #[error("{0}")]
85 Custom(String),
86}
87
88impl serde::de::Error for Error {
89 fn custom<T>(msg: T) -> Self
90 where
91 T: std::fmt::Display,
92 {
93 Self {
94 cause: ErrorKind::Custom(msg.to_string()),
95 position_stack: vec![],
96 }
97 }
98}
99
100impl<T> From<T> for Error
101where
102 ErrorKind: From<T>,
103{
104 fn from(value: T) -> Self {
105 Self {
106 cause: ErrorKind::from(value),
107 position_stack: vec![],
108 }
109 }
110}
111
112macro_rules! tri {
113 ($reader:expr, $parsing:ident, $e:expr) => {{
114 let __position = $reader.stream_position().ok();
115 let __result: Result<_, Error> = $e;
116 match __result {
117 Ok(__value) => __value,
118 Err(mut __error) => {
119 __error.position_stack.push((ParseId::$parsing, __position));
120 return Err(__error);
121 }
122 }
123 }};
124}
125
126macro_rules! tri_map {
127 ($reader:expr, $parsing:ident, $e:expr) => {
128 tri!($reader, $parsing, $e.map_err(Error::from))
129 };
130}
131
132pub(crate) struct ReferenceData {
133 file_offset: usize,
134 raw: Vec<u8>,
135 strings: HashMap<u32, String>,
136 maps: HashMap<u32, Vec<(Hash40, u32)>>,
137}
138
139impl ReferenceData {
140 #[cfg(test)]
141 pub fn mock(bytes: &[u8]) -> Self {
142 Self {
143 file_offset: 0,
144 raw: bytes.to_vec(),
145 strings: HashMap::new(),
146 maps: HashMap::new(),
147 }
148 }
149
150 pub fn new(bytes: Vec<u8>, file_offset: usize) -> Self {
151 Self {
152 file_offset,
153 raw: bytes,
154 strings: HashMap::new(),
155 maps: HashMap::new(),
156 }
157 }
158
159 #[cfg(test)]
160 pub fn empty() -> Self {
161 Self {
162 file_offset: 0,
163 raw: vec![],
164 strings: HashMap::new(),
165 maps: HashMap::new(),
166 }
167 }
168}
169
170struct ParamFileReader<'a, R: Read + Seek> {
171 reference: ReferenceData,
172 hashes: &'a [Hash40],
173 reader: &'a mut R,
174 peeked_param_id: Option<ParamId>,
175}
176
177impl<'a, R: Read + Seek> Read for ParamFileReader<'a, R> {
178 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
179 self.reader.read(buf)
180 }
181}
182
183impl<'a, R: Read + Seek> Seek for ParamFileReader<'a, R> {
184 fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
185 self.reader.seek(pos)
186 }
187}
188
189impl<'a, R: Read + Seek> ParamFileReader<'a, R> {
190 fn read_param_id(&mut self) -> Result<ParamId, Error> {
191 let param_id = tri_map!(self.reader, ParamId, self.reader.read_u8());
192 Ok(tri_map!(
193 self.reader,
194 ParamId,
195 ParamId::try_from(param_id).map_err(ErrorKind::InvalidParamId)
196 ))
197 }
198
199 fn peek_param_id(&mut self) -> Result<ParamId, Error> {
200 if let Some(peeked) = self.peeked_param_id {
201 Ok(peeked)
202 } else {
203 let param = self.read_param_id()?;
204 self.peeked_param_id = Some(param);
205 Ok(param)
206 }
207 }
208
209 fn next_param_id(&mut self) -> Result<ParamId, Error> {
210 if let Some(peeked) = self.peeked_param_id.take() {
211 Ok(peeked)
212 } else {
213 self.read_param_id()
214 }
215 }
216
217 fn get_string(&mut self, offset: u32) -> Result<String, Error> {
218 if let Some(cached) = self.reference.strings.get(&offset) {
219 return Ok(cached.clone());
220 }
221
222 let offset = offset as usize;
223
224 if offset >= self.reference.raw.len() {
225 return Err(Error::from(ErrorKind::StringRefOutOfBounds(offset)));
226 }
227
228 let data = &self.reference.raw[offset..];
229 let len =
230 data.iter()
231 .position(|byte| *byte == b'\0')
232 .ok_or(ErrorKind::StringRefOutOfBounds(
233 self.reference.file_offset + offset,
234 ))?;
235 let string = &data[..len];
236 if let Some(pos) = string.iter().position(|byte| !byte.is_ascii()) {
237 return Err(Error::from(ErrorKind::StringNotAscii(
238 self.reference.file_offset + offset + pos,
239 )));
240 }
241
242 let string = unsafe { std::str::from_utf8_unchecked(string).to_string() };
244 self.reference.strings.insert(offset as u32, string.clone());
245 Ok(string)
246 }
247
248 fn get_map(
249 &mut self,
250 offset: u32,
251 len: usize,
252 data_start: u64,
253 ) -> Result<Vec<(Hash40, u64)>, Error> {
254 if let Some(cached) = self.reference.maps.get(&offset) {
255 return Ok(cached
256 .iter()
257 .map(|(hash, offset)| (*hash, data_start + *offset as u64))
258 .collect());
259 }
260
261 let offset = offset as usize;
262
263 if offset + len * 8 > self.reference.raw.len() {
264 return Err(Error::from(ErrorKind::MapRefOutOfBounds {
265 start: self.reference.file_offset + offset,
266 num_elements: len,
267 }));
268 }
269
270 let mut fields = Vec::with_capacity(len as usize);
271
272 for index in 0..len {
273 let local_hash_offset = offset + index * 8;
274 let local_data_offset = local_hash_offset + 4;
275 let hash_index =
276 LittleEndian::read_u32(&self.reference.raw[local_hash_offset..local_data_offset])
277 as usize;
278 let data_offset = LittleEndian::read_u32(
279 &self.reference.raw[local_data_offset..local_data_offset + 4],
280 );
281
282 let Some(hash) = self.hashes.get(hash_index) else {
283 return Err(Error::from(ErrorKind::HashOutOfBounds(hash_index)));
284 };
285
286 fields.push((*hash, data_offset));
287 }
288
289 self.reference.maps.insert(offset as u32, fields.clone());
290
291 Ok(fields
292 .into_iter()
293 .map(|(hash, offset)| (hash, data_start + offset as u64))
294 .collect())
295 }
296}
297
298pub struct ValueDeserializer<'a, R: Read + Seek> {
299 reader: ParamFileReader<'a, R>,
300}
301
302pub struct ListDeserializer<'a: 'b, 'b, R: Read + Seek> {
303 offsets: Vec<u64>,
304 current: usize,
305 value_deserializer: &'b mut ValueDeserializer<'a, R>,
306}
307
308impl<'de, 'a: 'b, 'b, R: Read + Seek + 'de> SeqAccess<'de> for &mut ListDeserializer<'a, 'b, R> {
309 type Error = Error;
310
311 fn size_hint(&self) -> Option<usize> {
312 Some(self.offsets.len())
313 }
314
315 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
316 where
317 T: serde::de::DeserializeSeed<'de>,
318 {
319 match self.offsets.get(self.current) {
320 Some(offset) => {
321 let _ = tri_map!(
322 self.value_deserializer.reader,
323 ParamId,
324 self.value_deserializer
325 .reader
326 .seek(SeekFrom::Start(*offset))
327 );
328
329 self.current += 1;
330 let value = tri!(
331 self.value_deserializer.reader,
332 ParamId,
333 seed.deserialize(&mut *self.value_deserializer)
334 );
335
336 Ok(Some(value))
337 }
338 None => Ok(None),
339 }
340 }
341}
342
343pub struct MapDeserializer<'a: 'b, 'b, R: Read + Seek> {
344 keys: Vec<(Hash40, u64)>,
345 current: usize,
346 current_key: usize,
347 fields: Option<&'static [&'static str]>,
348 value_deserializer: &'b mut ValueDeserializer<'a, R>,
349}
350
351impl<'de, 'a: 'b, 'b, R: Read + Seek + 'de> MapAccess<'de> for &mut MapDeserializer<'a, 'b, R> {
352 type Error = Error;
353
354 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
355 where
356 K: serde::de::DeserializeSeed<'de>,
357 {
358 if self.current >= self.keys.len() {
359 return Ok(None);
360 }
361
362 let key = self.keys[self.current].0;
363 let map_key = if let Some(field) = self
364 .fields
365 .and_then(|fields| fields.iter().find(|field| hash40::hash40(*field) == key))
366 {
367 MapKeyDeserializer::Member(*field)
368 } else {
369 MapKeyDeserializer::Hash(key)
370 };
371
372 let key = tri!(
373 self.value_deserializer.reader,
374 Map,
375 seed.deserialize(map_key)
376 );
377
378 self.current_key = self.current;
379 self.current += 1;
380
381 Ok(Some(key))
382 }
383
384 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
385 where
386 V: serde::de::DeserializeSeed<'de>,
387 {
388 if self.current_key == self.current {
389 return Err(Error::from(ErrorKind::Custom(
390 "logical error requesting value before key".to_string(),
391 )));
392 }
393
394 let offset = self.keys[self.current_key].1;
395
396 tri_map!(
397 self.value_deserializer.reader,
398 Map,
399 self.value_deserializer.reader.seek(SeekFrom::Start(offset))
400 );
401
402 let result = tri!(
403 self.value_deserializer.reader,
404 Map,
405 seed.deserialize(&mut *self.value_deserializer)
406 );
407
408 self.current_key = self.current;
409
410 Ok(result)
411 }
412}
413
414impl<'a, R: Read + Seek> ValueDeserializer<'a, R> {
415 pub(crate) fn new(
416 reference_data: ReferenceData,
417 hashes: &'a [Hash40],
418 reader: &'a mut R,
419 ) -> Self {
420 Self {
421 reader: ParamFileReader {
422 reference: reference_data,
423 hashes,
424 reader,
425 peeked_param_id: None,
426 },
427 }
428 }
429
430 fn deserialize_map<'de, V: Visitor<'de>>(
431 &mut self,
432 fields: Option<&'static [&'static str]>,
433 visitor: V,
434 ) -> Result<V::Value, Error>
435 where
436 R: 'de,
437 {
438 let base_position = tri_map!(self.reader, Map, self.reader.stream_position())
441 .checked_sub(1)
442 .unwrap();
443
444 let num_elements =
445 tri_map!(self.reader, Map, self.reader.read_u32::<LittleEndian>()) as usize;
446
447 let ref_position = tri_map!(self.reader, Map, self.reader.read_u32::<LittleEndian>());
448
449 let keys = tri!(
450 self.reader,
451 Map,
452 self.reader
453 .get_map(ref_position, num_elements, base_position)
454 );
455
456 let mut map_deserializer = MapDeserializer {
457 keys,
458 current: 0,
459 current_key: 0,
460 fields,
461 value_deserializer: self,
462 };
463
464 let result = visitor.visit_map(&mut map_deserializer);
465
466 if map_deserializer.current < num_elements {
469 let offset = map_deserializer.keys.last().unwrap().1;
470 tri_map!(self.reader, Map, self.reader.seek(SeekFrom::Start(offset)));
471 tri!(self.reader, Map, Value::deserialize(&mut *self));
472 }
473
474 Ok(tri!(self.reader, Map, result))
475 }
476}
477
478impl<'de, 'a, R: Read + Seek + 'de> Deserializer<'de> for &mut ValueDeserializer<'a, R> {
479 type Error = Error;
480
481 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
482 where
483 V: serde::de::Visitor<'de>,
484 {
485 use ParamId as P;
486
487 let offset = self.reader.stream_position()?;
488 let next = self.reader.next_param_id()?;
489
490 match next {
491 P::Bool => {
492 let value = tri_map!(self.reader, Bool, self.reader.read_u8());
493 Ok(tri!(self.reader, Bool, visitor.visit_bool(value != 0)))
494 }
495 P::I8 => {
496 let value = tri_map!(self.reader, I8, self.reader.read_i8());
497 Ok(tri!(self.reader, I8, visitor.visit_i8(value)))
498 }
499 P::U8 => {
500 let value = tri_map!(self.reader, U8, self.reader.read_u8());
501 Ok(tri!(self.reader, U8, visitor.visit_u8(value)))
502 }
503 P::I16 => {
504 let value = tri_map!(self.reader, I16, self.reader.read_i16::<LittleEndian>());
505 Ok(tri!(self.reader, I16, visitor.visit_i16(value)))
506 }
507 P::U16 => {
508 let value = tri_map!(self.reader, U16, self.reader.read_u16::<LittleEndian>());
509 Ok(tri!(self.reader, U16, visitor.visit_u16(value)))
510 }
511 P::I32 => {
512 let value = tri_map!(self.reader, I32, self.reader.read_i32::<LittleEndian>());
513 Ok(tri!(self.reader, I32, visitor.visit_i32(value)))
514 }
515 P::U32 => {
516 let value = tri_map!(self.reader, U32, self.reader.read_u32::<LittleEndian>());
517 Ok(tri!(self.reader, U32, visitor.visit_u32(value)))
518 }
519 P::F32 => {
520 let value = tri_map!(self.reader, F32, self.reader.read_f32::<LittleEndian>());
521 Ok(tri!(self.reader, F32, visitor.visit_f32(value)))
522 }
523 P::Hash => {
524 let index =
525 tri_map!(self.reader, Hash, self.reader.read_u32::<LittleEndian>()) as usize;
526
527 let position = self.reader.stream_position().ok();
528 let Some(hash) = self.reader.hashes.get(index).copied() else {
529 return Err(Error {
530 cause: ErrorKind::HashOutOfBounds(index),
531 position_stack: vec![(ParseId::Hash, position)],
532 });
533 };
534
535 Ok(tri!(self.reader, Hash, visitor.visit_u64(hash.0)))
536 }
537 P::String => {
538 let ref_offset =
539 tri_map!(self.reader, String, self.reader.read_u32::<LittleEndian>());
540
541 let string = tri!(self.reader, String, self.reader.get_string(ref_offset));
542
543 Ok(tri!(self.reader, String, visitor.visit_string(string)))
544 }
545 P::List => {
546 let base_position = tri_map!(self.reader, List, self.reader.stream_position())
549 .checked_sub(1)
550 .unwrap();
551
552 let num_elements =
553 tri_map!(self.reader, List, self.reader.read_u32::<LittleEndian>());
554
555 let mut offsets = Vec::with_capacity(num_elements as usize);
556
557 for _ in 0..num_elements {
558 let el_offset =
559 tri_map!(self.reader, List, self.reader.read_u32::<LittleEndian>());
560 offsets.push(base_position + el_offset as u64);
561 }
562
563 let mut list_deserializer = ListDeserializer {
564 offsets,
565 current: 0,
566 value_deserializer: self,
567 };
568
569 let value = visitor.visit_seq(&mut list_deserializer);
570
571 if list_deserializer.current < list_deserializer.offsets.len() {
574 let offset = *list_deserializer.offsets.last().unwrap();
575 tri_map!(self.reader, List, self.reader.seek(SeekFrom::Start(offset)));
576 tri!(self.reader, List, Value::deserialize(&mut *self));
577 }
578
579 Ok(tri!(self.reader, List, value))
580 }
581 P::Map => self.deserialize_map(None, visitor),
582 }
583 }
584
585 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
586 where
587 V: serde::de::Visitor<'de>,
588 {
589 self.deserialize_string(visitor)
590 }
591
592 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
593 where
594 V: serde::de::Visitor<'de>,
595 {
596 if self.reader.peek_param_id()? == ParamId::Hash {
597 let _ = self.reader.next_param_id();
598 let index =
599 tri_map!(self.reader, Hash, self.reader.read_u32::<LittleEndian>()) as usize;
600
601 let position = self.reader.stream_position().ok();
602 let Some(hash) = self.reader.hashes.get(index).copied() else {
603 return Err(Error {
604 cause: ErrorKind::HashOutOfBounds(index),
605 position_stack: vec![(ParseId::Hash, position)],
606 });
607 };
608
609 Ok(tri!(
610 self.reader,
611 Hash,
612 visitor.visit_string(format!("{hash}"))
613 ))
614 } else {
615 self.deserialize_any(visitor)
616 }
617 }
618
619 fn deserialize_struct<V>(
620 self,
621 _name: &'static str,
622 fields: &'static [&'static str],
623 visitor: V,
624 ) -> Result<V::Value, Self::Error>
625 where
626 V: Visitor<'de>,
627 {
628 if self.reader.peek_param_id()? == ParamId::Map {
629 let _ = self.reader.next_param_id();
630 self.deserialize_map(Some(fields), visitor)
631 } else {
632 self.deserialize_any(visitor)
633 }
634 }
635
636 forward_to_deserialize_any! {
637 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char
638 bytes byte_buf option unit unit_struct newtype_struct seq tuple
639 tuple_struct map enum identifier ignored_any
640 }
641}
642
643struct ValueVisitor;
644
645impl<'de> Visitor<'de> for ValueVisitor {
646 type Value = Value;
647
648 fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
649 where
650 E: serde::de::Error,
651 {
652 Ok(Value::I8(v))
653 }
654
655 fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
656 where
657 E: serde::de::Error,
658 {
659 Ok(Value::U8(v))
660 }
661
662 fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
663 where
664 E: serde::de::Error,
665 {
666 Ok(Value::I16(v))
667 }
668
669 fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
670 where
671 E: serde::de::Error,
672 {
673 Ok(Value::U16(v))
674 }
675
676 fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
677 where
678 E: serde::de::Error,
679 {
680 Ok(Value::I32(v))
681 }
682
683 fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
684 where
685 E: serde::de::Error,
686 {
687 Ok(Value::U32(v))
688 }
689
690 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
691 where
692 E: serde::de::Error,
693 {
694 Ok(Value::I32(v.try_into().map_err(|e| E::custom(e))?))
695 }
696
697 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
698 where
699 E: serde::de::Error,
700 {
701 Ok(Value::Hash(Hash40(v)))
702 }
703
704 fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
705 where
706 E: serde::de::Error,
707 {
708 Ok(Value::F32(v))
709 }
710
711 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
712 where
713 E: serde::de::Error,
714 {
715 Ok(Value::F32(v as f32))
716 }
717
718 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
719 where
720 E: serde::de::Error,
721 {
722 if v.starts_with("0x") && v.len() == "0x123456789A".len() {
723 match u64::from_str_radix(v.strip_prefix("0x").unwrap(), 16) {
724 Ok(v) => Ok(Value::Hash(Hash40(v))),
725 Err(_) => Ok(Value::String(v.to_string())),
726 }
727 } else {
728 Ok(Value::String(v.to_string()))
729 }
730 }
731
732 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
733 where
734 E: serde::de::Error,
735 {
736 self.visit_str(v.as_str())
737 }
738
739 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
740 where
741 A: SeqAccess<'de>,
742 {
743 let mut list = Vec::with_capacity(seq.size_hint().unwrap_or_default());
744
745 while let Some(next) = seq.next_element::<Value>()? {
746 list.push(next);
747 }
748
749 Ok(Value::List(list))
750 }
751
752 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
753 where
754 A: serde::de::MapAccess<'de>,
755 {
756 let mut object = IndexMap::with_capacity(map.size_hint().unwrap_or_default());
757
758 while let Some((k, v)) = map.next_entry::<Hash40, Value>()? {
759 object.insert(k, v);
760 }
761
762 Ok(Value::Map(object))
763 }
764
765 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
766 where
767 E: serde::de::Error,
768 {
769 Ok(Value::Bool(v))
770 }
771
772 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
773 formatter.write_str("a prc value")
774 }
775}
776
777impl<'de> Deserialize<'de> for Value {
778 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
779 where
780 D: Deserializer<'de>,
781 {
782 deserializer.deserialize_any(ValueVisitor)
783 }
784}
785
786enum MapKeyDeserializer {
787 Hash(Hash40),
788 Member(&'static str),
789}
790
791impl<'de> Deserializer<'de> for MapKeyDeserializer {
792 type Error = Error;
793
794 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
795 where
796 V: Visitor<'de>,
797 {
798 match self {
799 Self::Hash(hash) => visitor.visit_u64(hash.0),
800 Self::Member(member) => visitor.visit_str(member),
801 }
802 }
803
804 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
805 where
806 V: Visitor<'de>,
807 {
808 match self {
809 Self::Hash(hash) => visitor.visit_u64(hash.0),
810 Self::Member(member) => visitor.visit_u64(hash40::hash40(member).0),
811 }
812 }
813
814 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
815 where
816 V: Visitor<'de>,
817 {
818 match self {
819 Self::Hash(hash) => visitor.visit_string(format!("{hash}")),
820 Self::Member(member) => visitor.visit_str(member),
821 }
822 }
823
824 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
825 where
826 V: Visitor<'de>,
827 {
828 match self {
829 Self::Hash(hash) => visitor.visit_string(format!("{hash}")),
830 Self::Member(member) => visitor.visit_string(member.to_string()),
831 }
832 }
833
834 forward_to_deserialize_any! {
835 bool i8 i16 i32 i64 i128 u8 u16 u32 u128 f32 f64 char
836 bytes byte_buf option unit unit_struct newtype_struct seq tuple
837 tuple_struct map struct enum identifier ignored_any
838 }
839}