serde_name/
trace.rs

1// Copyright (c) Facebook, Inc. and its affiliates
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use serde::de::Visitor;
5use thiserror::Error;
6
7/// Compute the Serde name of a container.
8pub fn trace_name<'de, T>() -> Option<&'static str>
9where
10    T: serde::de::Deserialize<'de>,
11{
12    match T::deserialize(NameTracer) {
13        Err(NameTracerError(name)) => name,
14        _ => unreachable!(),
15    }
16}
17
18/// Minimal instrumented implementation of `serde::de::Deserializer`
19/// This always returns a `NameTracerError` as soon as we have learnt the name
20/// of the type (or the absence of name) from Serde.
21struct NameTracer;
22
23/// Custom error value used to report the result of the analysis.
24#[derive(Clone, Debug, Error, PartialEq)]
25#[error("{0:?}")]
26struct NameTracerError(Option<&'static str>);
27
28impl serde::de::Error for NameTracerError {
29    fn custom<T: std::fmt::Display>(_msg: T) -> Self {
30        unreachable!();
31    }
32}
33
34macro_rules! declare_deserialize {
35    ($method:ident) => {
36        fn $method<V>(self, _visitor: V) -> std::result::Result<V::Value, NameTracerError>
37        where
38            V: Visitor<'de>,
39        {
40            Err(NameTracerError(None))
41        }
42    };
43}
44
45impl<'de> serde::de::Deserializer<'de> for NameTracer {
46    type Error = NameTracerError;
47
48    declare_deserialize!(deserialize_any);
49    declare_deserialize!(deserialize_identifier);
50    declare_deserialize!(deserialize_ignored_any);
51    declare_deserialize!(deserialize_bool);
52    declare_deserialize!(deserialize_i8);
53    declare_deserialize!(deserialize_i16);
54    declare_deserialize!(deserialize_i32);
55    declare_deserialize!(deserialize_i64);
56    declare_deserialize!(deserialize_i128);
57    declare_deserialize!(deserialize_u8);
58    declare_deserialize!(deserialize_u16);
59    declare_deserialize!(deserialize_u32);
60    declare_deserialize!(deserialize_u64);
61    declare_deserialize!(deserialize_u128);
62    declare_deserialize!(deserialize_f32);
63    declare_deserialize!(deserialize_f64);
64    declare_deserialize!(deserialize_char);
65    declare_deserialize!(deserialize_str);
66    declare_deserialize!(deserialize_string);
67    declare_deserialize!(deserialize_bytes);
68    declare_deserialize!(deserialize_byte_buf);
69    declare_deserialize!(deserialize_option);
70    declare_deserialize!(deserialize_unit);
71    declare_deserialize!(deserialize_seq);
72    declare_deserialize!(deserialize_map);
73
74    fn deserialize_tuple<V>(
75        self,
76        _len: usize,
77        _visitor: V,
78    ) -> std::result::Result<V::Value, NameTracerError>
79    where
80        V: Visitor<'de>,
81    {
82        Err(NameTracerError(None))
83    }
84
85    fn deserialize_unit_struct<V>(
86        self,
87        name: &'static str,
88        _visitor: V,
89    ) -> std::result::Result<V::Value, NameTracerError>
90    where
91        V: Visitor<'de>,
92    {
93        Err(NameTracerError(Some(name)))
94    }
95
96    fn deserialize_newtype_struct<V>(
97        self,
98        name: &'static str,
99        _visitor: V,
100    ) -> std::result::Result<V::Value, NameTracerError>
101    where
102        V: Visitor<'de>,
103    {
104        Err(NameTracerError(Some(name)))
105    }
106
107    fn deserialize_tuple_struct<V>(
108        self,
109        name: &'static str,
110        _len: usize,
111        _visitor: V,
112    ) -> std::result::Result<V::Value, NameTracerError>
113    where
114        V: Visitor<'de>,
115    {
116        Err(NameTracerError(Some(name)))
117    }
118
119    fn deserialize_struct<V>(
120        self,
121        name: &'static str,
122        _fields: &'static [&'static str],
123        _visitor: V,
124    ) -> std::result::Result<V::Value, NameTracerError>
125    where
126        V: Visitor<'de>,
127    {
128        Err(NameTracerError(Some(name)))
129    }
130
131    fn deserialize_enum<V>(
132        self,
133        name: &'static str,
134        _variants: &'static [&'static str],
135        _visitor: V,
136    ) -> std::result::Result<V::Value, NameTracerError>
137    where
138        V: Visitor<'de>,
139    {
140        Err(NameTracerError(Some(name)))
141    }
142
143    fn is_human_readable(&self) -> bool {
144        false
145    }
146}