rustdoc_index/
doc.rs

1use std::str::FromStr;
2
3/// src/librustdoc/html/render/search_index.rs
4#[derive(Debug, Deserialize)]
5pub struct Crate {
6    // doc: String,
7    p: Vec<(ParentType, String)>,
8
9    // t, n, q, d, i, f are items array
10    t: Vec<ItemType>,
11    n: Vec<String>,
12    f: F,
13    q: Vec<String>,
14    d: Vec<String>,
15    i: Vec<usize> // p idx
16}
17
18/// <https://github.com/rust-lang/rust/blob/71a567fae4c282aa5ecb1e6e48f020ade8df23e7/src/librustdoc/html/render/mod.rs>
19#[derive(Debug, Deserialize)]
20#[serde(untagged)]
21pub enum F {
22    V1_53_0(Vec<Option<Types>>),
23    V1_55_0(Vec<Option<Types1_55_0>>),
24    V1_58_0(Vec<Option<Types1_58_0>>),
25    V1_64_0(Vec<Option<Types1_64_0>>)
26}
27
28#[derive(Debug, Deserialize)]
29#[serde(untagged)]
30pub enum Types {
31    OnlyArgs((Vec<(String, ItemType)>,)),
32    WithResponse(Vec<(String, ItemType)>, ResponseType)
33}
34
35#[derive(Debug, Deserialize)]
36#[serde(untagged)]
37pub enum ResponseType {
38    Single((String, ItemType)),
39    Complex(Vec<(String, ItemType)>)
40}
41
42/// <https://github.com/rust-lang/rust/blob/71a567fae4c282aa5ecb1e6e48f020ade8df23e7/src/librustdoc/html/render/cache.rs#L219>
43#[derive(Debug, Deserialize)]
44#[serde(untagged)]
45pub enum Types1_55_0 {
46    OnlyArgs((Vec<Type1_55_0>,)),
47    WithMultiResponse(Vec<Type1_55_0>, Vec<Type1_55_0>),
48    WithResponse(Vec<Type1_55_0>, Type1_55_0)
49}
50
51#[derive(Debug)]
52pub struct Type1_55_0 {
53    name: String,
54    generics: Option<Vec<String>>,
55    kind: ItemType
56}
57
58#[derive(Debug, Deserialize)]
59#[serde(untagged)]
60pub enum Types1_58_0 {
61    OnlyArgs((Vec<Type1_58_0>,)),
62    WithMultiResponse(Vec<Type1_58_0>, Vec<Type1_58_0>),
63    WithResponse(Vec<Type1_58_0>, Type1_58_0)
64}
65
66#[derive(Debug)]
67pub struct Type1_58_0 {
68    name: String,
69    generics: Option<Vec<Type1_58_0>>,
70    kind: ItemType
71}
72
73/// <https://github.com/rust-lang/rust/blob/e1d1848cc60a407d06f90fd16877a19bed6edd9b/src/librustdoc/html/render/search_index.rs#L314>
74/// IndexItemFunctionType
75#[derive(Debug, Deserialize)]
76#[serde(untagged)]
77pub enum Types1_64_0 {
78    Unit(usize),
79    OnlyArgs((Args1_64_0,)),
80    F((Args1_64_0, Args1_64_0))
81}
82
83#[derive(Debug, Deserialize)]
84#[serde(untagged)]
85pub enum Args1_64_0 {
86    One(usize),
87    Args(TypeId1_64_0)
88}
89
90#[derive(Debug, Deserialize)]
91#[serde(untagged)]
92pub enum TypeId1_64_0 {
93    One(usize),
94    WithGenerics(Vec<TypeId1_64_0>)
95}
96
97impl<'de> serde::Deserialize<'de> for Type1_55_0 {
98    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
99    where
100        D: serde::Deserializer<'de>
101    {
102        #[derive(Deserialize)]
103        #[serde(untagged)]
104        enum De {
105            Two(String, ItemType),
106            Three(String, ItemType, Vec<String>)
107        }
108        Ok(match De::deserialize(deserializer)? {
109            De::Two(name, kind) => Self {
110                name,
111                generics: None,
112                kind
113            },
114            De::Three(name, kind, generics) => Self {
115                name,
116                generics: Some(generics),
117                kind
118            }
119        })
120    }
121}
122
123impl<'de> serde::Deserialize<'de> for Type1_58_0 {
124    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
125    where
126        D: serde::Deserializer<'de>
127    {
128        #[derive(Deserialize)]
129        #[serde(untagged)]
130        enum De {
131            Two(String, ItemType),
132            Three(String, ItemType, Vec<Type1_58_0>)
133        }
134        Ok(match De::deserialize(deserializer)? {
135            De::Two(name, kind) => Self {
136                name,
137                generics: None,
138                kind
139            },
140            De::Three(name, kind, generics) => Self {
141                name,
142                generics: Some(generics),
143                kind
144            }
145        })
146    }
147}
148
149#[derive(Debug, serde_repr::Deserialize_repr)]
150#[repr(u8)]
151pub enum ParentType {
152    Struct = 3,
153    Enum = 4,
154    Typedef = 6,
155    Trait = 8,
156    Variant = 13,
157    Primitive = 15,
158    Union = 19
159}
160
161/// rust/src/librustdoc/formats/item_type.rs
162#[derive(Debug, serde_repr::Deserialize_repr, PartialEq, Eq, Clone, Copy)]
163#[repr(u8)]
164pub enum ItemType {
165    Module = 0,
166    ExternCrate = 1,
167    Import = 2,
168    Struct = 3,
169    Enum = 4,
170    Function = 5,
171    Typedef = 6,
172    Static = 7,
173    Trait = 8,
174    Impl = 9,
175    TyMethod = 10,
176    Method = 11,
177    StructField = 12,
178    Variant = 13,
179    Macro = 14,
180    Primitive = 15,
181    AssocType = 16,
182    Constant = 17,
183    AssocConst = 18,
184    Union = 19,
185    ForeignType = 20,
186    Keyword = 21,
187    OpaqueTy = 22,
188    ProcAttribute = 23,
189    ProcDerive = 24,
190    TraitAlias = 25,
191    Generic = 26
192}
193
194pub const FILETYPE: &[ItemType] = &[
195    ItemType::Struct,
196    ItemType::Union,
197    ItemType::Enum,
198    ItemType::Typedef,
199    // Positioning after ty
200    ItemType::Function,
201    ItemType::Static,
202    ItemType::Trait,
203    ItemType::Macro,
204    ItemType::Primitive,
205    ItemType::Constant,
206    ItemType::Keyword,
207    ItemType::ProcAttribute,
208    ItemType::ProcDerive,
209    ItemType::TraitAlias
210];
211
212pub const STD_PRIMITIVES: &[&str] = &[
213    "array",
214    "bool",
215    "char",
216    "f32",
217    "f64",
218    "fn",
219    "i128",
220    "i16",
221    "i32",
222    "i64",
223    "i8",
224    "isize",
225    "never",
226    "pointer",
227    "reference",
228    "slice",
229    "str",
230    "tuple",
231    "u128",
232    "u16",
233    "u32",
234    "u64",
235    "u8",
236    "unit",
237    "usize"
238];
239
240impl ItemType {
241    pub fn as_str(&self) -> &'static str {
242        match *self {
243            ItemType::Module => "mod",
244            ItemType::ExternCrate => "externcrate",
245            ItemType::Import => "import",
246            ItemType::Struct => "struct",
247            ItemType::Union => "union",
248            ItemType::Enum => "enum",
249            ItemType::Function => "fn",
250            ItemType::Typedef => "type",
251            ItemType::Static => "static",
252            ItemType::Trait => "trait",
253            ItemType::Impl => "impl",
254            ItemType::TyMethod => "tymethod",
255            ItemType::Method => "method",
256            ItemType::StructField => "structfield",
257            ItemType::Variant => "variant",
258            ItemType::Macro => "macro",
259            ItemType::Primitive => "primitive",
260            ItemType::AssocType => "associatedtype",
261            ItemType::Constant => "constant",
262            ItemType::AssocConst => "associatedconstant",
263            ItemType::ForeignType => "foreigntype",
264            ItemType::Keyword => "keyword",
265            ItemType::OpaqueTy => "opaque",
266            ItemType::ProcAttribute => "attr",
267            ItemType::ProcDerive => "derive",
268            ItemType::TraitAlias => "traitalias",
269            ItemType::Generic => "generic"
270        }
271    }
272}
273
274#[derive(Debug, Error)]
275#[error("Failed to parse ItemType")]
276pub struct ParseItemTypeError;
277
278impl FromStr for ItemType {
279    type Err = ParseItemTypeError;
280
281    fn from_str(s: &str) -> Result<Self, Self::Err> {
282        match s {
283            "mod" => Ok(ItemType::Module),
284            "externcrate" => Ok(ItemType::ExternCrate),
285            "import" => Ok(ItemType::Import),
286            "struct" => Ok(ItemType::Struct),
287            "union" => Ok(ItemType::Union),
288            "enum" => Ok(ItemType::Enum),
289            "fn" => Ok(ItemType::Function),
290            "type" => Ok(ItemType::Typedef),
291            "static" => Ok(ItemType::Static),
292            "trait" => Ok(ItemType::Trait),
293            "impl" => Ok(ItemType::Impl),
294            "tymethod" => Ok(ItemType::TyMethod),
295            "method" => Ok(ItemType::Method),
296            "structfield" => Ok(ItemType::StructField),
297            "variant" => Ok(ItemType::Variant),
298            "macro" => Ok(ItemType::Macro),
299            "primitive" => Ok(ItemType::Primitive),
300            "associatedtype" => Ok(ItemType::AssocType),
301            "constant" => Ok(ItemType::Constant),
302            "associatedconstant" => Ok(ItemType::AssocConst),
303            "foreigntype" => Ok(ItemType::ForeignType),
304            "keyword" => Ok(ItemType::Keyword),
305            "opaque" => Ok(ItemType::OpaqueTy),
306            "attr" => Ok(ItemType::ProcAttribute),
307            "derive" => Ok(ItemType::ProcDerive),
308            "traitalias" => Ok(ItemType::TraitAlias),
309            _ => Err(ParseItemTypeError)
310        }
311    }
312}
313
314impl Crate {
315    // TODO: duplicated methods
316    pub fn items(self) -> Vec<String> {
317        let Self { p, t, n, q, i, .. } = self;
318        let items = (0..)
319            .zip(t.into_iter())
320            .zip(n.into_iter())
321            .zip(i.into_iter())
322            .zip(q.into_iter())
323            .map(|((((no, t), n), i), q)| (no, t, n, i, q));
324        let mut cd: String = String::new();
325        items
326            .map(|(_no, t, n, i, q)| {
327                if !q.is_empty() {
328                    cd = q;
329                }
330                if i == 0 {
331                    format!("{}::{}	{}", &cd, n, t.as_str())
332                } else {
333                    format!("{}::{}::{}	{}", &cd, p[i - 1].1, n, t.as_str())
334                }
335            })
336            .collect()
337    }
338}
339
340#[cfg(test)]
341mod tests {
342    use super::*;
343    #[test]
344    fn parse_f() {
345        let _: F = serde_json::from_str("[null]").unwrap();
346        let _: F = serde_json::from_str(r#"[[[]]]"#).unwrap();
347        let _: F = serde_json::from_str(r#"[[[], ["osstr", 3]]]"#).unwrap();
348        let _: F = serde_json::from_str(r#"[[[["usize", 15]]]]"#).unwrap();
349        let _: Vec<Type1_55_0> =
350            serde_json::from_str(r#"[["pathbuf", 3], ["result", 6, ["pathbuf"]]]"#).unwrap();
351        let _: F = serde_json::from_str(
352            r#"[[
353                [],
354                [["pathbuf", 3], ["result", 6, ["pathbuf"]]]
355            ]]"#
356        )
357        .unwrap();
358        let _: F = serde_json::from_str(
359            r#"[[
360                [["utf8path", 3]],
361                ["ordering", 4]
362            ]]"#
363        )
364        .unwrap();
365    }
366}