serde_prc/
de.rs

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        // SAFETY: We check that all chars are non-zero and ascii above
243        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        // Subtract 1 from the current position to get the base offset all of the elemenets
439        // are relative to
440        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 the map deserializer finishes prematurely, we need to parse the last value
467        // so that we can advance to the correct cursor position
468        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                // Subtract 1 from the current position to get the base offset all of the elemenets
547                // are relative to
548                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 the list deserializer finishes prematurely, we need to parse the last value
572                // so that we can advance to the correct cursor position
573                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}