@@ -20,19 +20,63 @@ use syn::{parse::Parser, Ident, Lit, Meta, NestedMeta};
20
20
fn full_path ( krate : & Crate , item : & Id ) -> Option < ( String , String ) > {
21
21
let item_summary = krate. paths . get ( item) ?;
22
22
let kind = & item_summary. kind ;
23
- let kind_str = serde_json:: to_string ( kind) . ok ( ) ?;
23
+ let kind_str = match kind {
24
+ rustdoc_json_types:: ItemKind :: AssocConst => todo ! ( "assoc_const" ) ,
25
+ rustdoc_json_types:: ItemKind :: AssocType => todo ! ( "assoc_type" ) ,
26
+ rustdoc_json_types:: ItemKind :: Constant => "constant" ,
27
+ rustdoc_json_types:: ItemKind :: Enum => "enum" ,
28
+ rustdoc_json_types:: ItemKind :: ExternCrate => todo ! ( "extern_crate" ) ,
29
+ rustdoc_json_types:: ItemKind :: ForeignType => todo ! ( "foreign_type" ) ,
30
+ rustdoc_json_types:: ItemKind :: Function => "fn" ,
31
+ rustdoc_json_types:: ItemKind :: Impl => todo ! ( "impl" ) ,
32
+ rustdoc_json_types:: ItemKind :: Import => todo ! ( "import" ) ,
33
+ rustdoc_json_types:: ItemKind :: Keyword => todo ! ( "keyword" ) ,
34
+ rustdoc_json_types:: ItemKind :: Macro => "macro" ,
35
+ rustdoc_json_types:: ItemKind :: Module => "index" ,
36
+ rustdoc_json_types:: ItemKind :: OpaqueTy => todo ! ( "opaque_ty" ) ,
37
+ rustdoc_json_types:: ItemKind :: Primitive => "primitive" ,
38
+ rustdoc_json_types:: ItemKind :: ProcAttribute => todo ! ( "proc_attribute" ) ,
39
+ rustdoc_json_types:: ItemKind :: ProcDerive => todo ! ( "proc_derive" ) ,
40
+ rustdoc_json_types:: ItemKind :: Static => "static" ,
41
+ rustdoc_json_types:: ItemKind :: Struct => "struct" ,
42
+ rustdoc_json_types:: ItemKind :: StructField => todo ! ( "struct_field" ) ,
43
+ rustdoc_json_types:: ItemKind :: Trait => "trait" ,
44
+ rustdoc_json_types:: ItemKind :: TraitAlias => "trait_alias" ,
45
+ rustdoc_json_types:: ItemKind :: Typedef => "type" ,
46
+ rustdoc_json_types:: ItemKind :: Union => todo ! ( "union" ) ,
47
+ rustdoc_json_types:: ItemKind :: Variant => {
48
+ return Some ( ( item_summary. path . join ( "::" ) , specialcase_variant ( & item_summary. path ) ) ) ;
49
+ }
50
+ } ;
24
51
let mut url = String :: from ( "https://doc.rust-lang.org/nightly/" ) ;
25
52
let mut iter = item_summary. path . iter ( ) ;
26
- iter. next_back ( ) ;
53
+ if !matches ! ( kind, rustdoc_json_types:: ItemKind :: Module ) {
54
+ iter. next_back ( ) ;
55
+ }
27
56
url. push_str ( & iter. cloned ( ) . collect :: < Vec < _ > > ( ) . join ( "/" ) ) ;
28
57
url. push ( '/' ) ;
29
- url. push_str ( kind_str. trim_matches ( '"' ) ) ;
30
- url. push ( '.' ) ;
31
- url. push_str ( item_summary. path . last ( ) . unwrap ( ) ) ;
58
+ url. push_str ( kind_str) ;
59
+ if !matches ! ( kind, rustdoc_json_types:: ItemKind :: Module ) {
60
+ url. push ( '.' ) ;
61
+ url. push_str ( item_summary. path . last ( ) . unwrap ( ) ) ;
62
+ }
32
63
url. push_str ( ".html" ) ;
33
64
Some ( ( item_summary. path . join ( "::" ) , url) )
34
65
}
35
66
67
+ fn specialcase_variant ( path : & [ String ] ) -> String {
68
+ let mut iter = path. iter ( ) ;
69
+ let mut out = String :: from ( "https://doc.rust-lang.org/nightly/" ) ;
70
+ let variant = iter. next_back ( ) ;
71
+ let enum_name = iter. next_back ( ) ;
72
+ out. push_str ( & iter. cloned ( ) . collect :: < Vec < _ > > ( ) . join ( "/" ) ) ;
73
+ out. push_str ( "/enum." ) ;
74
+ out. push_str ( enum_name. unwrap ( ) ) ;
75
+ out. push_str ( ".html#variant." ) ;
76
+ out. push_str ( variant. unwrap ( ) ) ;
77
+ out
78
+ }
79
+
36
80
fn is_ident ( ident : & Ident , name : & str ) -> bool {
37
81
* ident == Ident :: new ( name, ident. span ( ) )
38
82
}
@@ -41,6 +85,20 @@ fn is_ident(ident: &Ident, name: &str) -> bool {
41
85
pub fn load_rustdoc_json_metadata ( doc_dir : & Path ) -> HashMap < String , Vec < ( String , String ) > > {
42
86
let mut all_items = HashMap :: new ( ) ;
43
87
88
+ // Given a `NestedMeta` like `feature = "xyz"`, returns `xyz`.
89
+ let get_feature_name = |nested : & _ | match nested {
90
+ NestedMeta :: Meta ( Meta :: NameValue ( name_value) ) => {
91
+ if !is_ident ( name_value. path . get_ident ( ) ?, "feature" ) {
92
+ return None ;
93
+ }
94
+ match & name_value. lit {
95
+ Lit :: Str ( s) => Some ( s. value ( ) ) ,
96
+ _ => None ,
97
+ }
98
+ }
99
+ _ => None ,
100
+ } ;
101
+
44
102
for file in fs:: read_dir ( doc_dir) . expect ( "failed to list files in directory" ) {
45
103
let entry = file. expect ( "failed to list file in directory" ) ;
46
104
let file = fs:: File :: open ( entry. path ( ) ) . expect ( "failed to open file" ) ;
@@ -53,41 +111,26 @@ pub fn load_rustdoc_json_metadata(doc_dir: &Path) -> HashMap<String, Vec<(String
53
111
continue ;
54
112
}
55
113
let unstable_feature = item. attrs . iter ( ) . find_map ( |attr : & String | {
56
- let Ok ( parsed) = syn:: Attribute :: parse_outer. parse_str ( attr) . map ( |mut v| v. swap_remove ( 0 ) ) else { return None } ;
114
+ let Ok ( parseable) = syn:: Attribute :: parse_outer. parse_str ( attr) else { return None ; } ;
115
+ for parsed in parseable {
116
+ let Some ( ident) = parsed. path . get_ident ( ) else { continue ; } ;
117
+ // Make sure this is an `unstable` attribute.
118
+ if !is_ident ( ident, "unstable" ) {
119
+ continue ;
120
+ }
57
121
58
- // Make sure this is an `unstable` attribute.
59
- if !is_ident ( parsed. path . get_ident ( ) ?, "unstable" ) {
60
- return None ;
61
- }
122
+ // Given `#[unstable(feature = "xyz")]`, return `(feature = "xyz")`.
123
+ let list = match parsed. parse_meta ( ) {
124
+ Ok ( Meta :: List ( list) ) => list,
125
+ _ => continue ,
126
+ } ;
62
127
63
- // Given `#[unstable(feature = "xyz")]`, return `(feature = "xyz")`.
64
- let list = match parsed. parse_meta ( ) {
65
- Ok ( Meta :: List ( list) ) => list,
66
- _ => return None ,
67
- } ;
68
-
69
- // Given a `NestedMeta` like `feature = "xyz"`, returns `xyz`.
70
- let get_feature_name = |nested : & _ | {
71
- match nested {
72
- NestedMeta :: Meta ( Meta :: NameValue ( name_value) ) => {
73
- if !is_ident ( name_value. path . get_ident ( ) ?, "feature" ) {
74
- return None ;
75
- }
76
- match & name_value. lit {
77
- Lit :: Str ( s) => Some ( s. value ( ) ) ,
78
- _ => None ,
79
- }
128
+ for nested in list. nested . iter ( ) {
129
+ if let Some ( feat) = get_feature_name ( nested) {
130
+ return Some ( feat) ;
80
131
}
81
- _ => None ,
82
- }
83
- } ;
84
-
85
- for nested in list. nested . iter ( ) {
86
- if let Some ( feat) = get_feature_name ( nested) {
87
- return Some ( feat) ;
88
132
}
89
133
}
90
-
91
134
None
92
135
} ) ;
93
136
if let Some ( feat) = unstable_feature {
0 commit comments