88use std:: collections:: HashMap ;
99
1010use crate :: meta:: ClassId ;
11- use crate :: registry:: plugin:: { ITraitImpl , InherentImpl , PluginItem , Struct } ;
11+ use crate :: obj:: GodotClass ;
12+
13+ /// Piece of information that is gathered by the self-registration ("plugin") system.
14+ ///
15+ /// You should not manually construct this struct, but rather use [`DocsPlugin::new()`].
16+ #[ derive( Debug ) ]
17+ pub struct DocsPlugin {
18+ /// The name of the class to register docs for.
19+ class_name : ClassId ,
20+
21+ /// The actual item being registered.
22+ item : DocsItem ,
23+ }
24+
25+ impl DocsPlugin {
26+ /// Creates a new `DocsPlugin`, automatically setting the `class_name` to the values defined in [`GodotClass`].
27+ pub fn new < T : GodotClass > ( item : DocsItem ) -> Self {
28+ Self {
29+ class_name : T :: class_id ( ) ,
30+ item,
31+ }
32+ }
33+ }
34+
35+ type ITraitImplDocs = & ' static str ;
36+
37+ #[ derive( Debug ) ]
38+ pub enum DocsItem {
39+ /// Docs for `#[derive(GodotClass)] struct MyClass`.
40+ Struct ( StructDocs ) ,
41+ /// Docs for `#[godot_api] impl MyClass`.
42+ InherentImpl ( InherentImplDocs ) ,
43+ /// Docs for `#[godot_api] impl ITrait for MyClass`.
44+ ITraitImpl ( ITraitImplDocs ) ,
45+ }
1246
1347/// Created for documentation on
1448/// ```ignore
@@ -29,7 +63,7 @@ pub struct StructDocs {
2963 pub members : & ' static str ,
3064}
3165
32- /// Keeps documentation for inherent `impl` blocks, such as:
66+ /// Keeps documentation for inherent `impl` blocks (primary and secondary) , such as:
3367/// ```ignore
3468/// #[godot_api]
3569/// impl Struct {
@@ -46,18 +80,19 @@ pub struct StructDocs {
4680/// }
4781/// ```
4882/// All fields are XML parts, escaped where necessary.
49- #[ derive( Default , Copy , Clone , Debug ) ]
83+ #[ derive( Default , Clone , Debug ) ]
5084pub struct InherentImplDocs {
51- pub methods : Vec < & ' static str > ,
52- pub signals : Vec < & ' static str > ,
53- pub constants : Vec < & ' static str > ,
85+ pub methods : & ' static str ,
86+ pub signals : & ' static str ,
87+ pub constants : & ' static str ,
5488}
5589
5690#[ derive( Default ) ]
5791struct DocPieces {
5892 definition : StructDocs ,
59- inherent : InherentImplDocs ,
60- virtual_methods : Vec < & ' static str > ,
93+ methods : Vec < & ' static str > ,
94+ signals : Vec < & ' static str > ,
95+ constants : Vec < & ' static str > ,
6196}
6297
6398/// This function scours the registered plugins to find their documentation pieces,
@@ -76,68 +111,66 @@ struct DocPieces {
76111#[ doc( hidden) ]
77112pub fn gather_xml_docs ( ) -> impl Iterator < Item = String > {
78113 let mut map = HashMap :: < ClassId , DocPieces > :: new ( ) ;
79- crate :: private:: iterate_plugins ( |x| {
114+ crate :: private:: iterate_docs_plugins ( |x| {
80115 let class_name = x. class_name ;
81-
82116 match & x. item {
83- PluginItem :: InherentImpl ( InherentImpl { docs , .. } ) => {
84- map. entry ( class_name) . or_default ( ) . inherent = docs . clone ( ) ;
117+ DocsItem :: Struct ( s ) => {
118+ map. entry ( class_name) . or_default ( ) . definition = * s ;
85119 }
86- PluginItem :: ITraitImpl ( ITraitImpl {
87- virtual_method_docs,
88- ..
89- } ) => map
90- . entry ( class_name)
91- . or_default ( )
92- . virtual_methods
93- . push ( virtual_method_docs) ,
94-
95- PluginItem :: Struct ( Struct { docs, .. } ) => {
96- map. entry ( class_name) . or_default ( ) . definition = * docs;
120+ DocsItem :: InherentImpl ( trait_docs) => {
121+ let InherentImplDocs {
122+ methods,
123+ constants,
124+ signals,
125+ } = trait_docs;
126+ map. entry ( class_name) . or_default ( ) . methods . push ( methods) ;
127+ map. entry ( class_name)
128+ . and_modify ( |pieces| pieces. constants . push ( constants) ) ;
129+ map. entry ( class_name)
130+ . and_modify ( |pieces| pieces. signals . push ( signals) ) ;
131+ }
132+ DocsItem :: ITraitImpl ( methods) => {
133+ map. entry ( class_name) . or_default ( ) . methods . push ( methods) ;
97134 }
98-
99- _ => ( ) ,
100135 }
101136 } ) ;
102137
103138 map. into_iter ( ) . map ( |( class, pieces) | {
104- let StructDocs {
105- base,
106- description,
107- experimental,
108- deprecated,
109- members,
110- } = pieces. definition ;
111-
112- let virtual_methods = pieces. virtual_methods ;
113-
114- let mut method_docs = String :: from_iter ( pieces. inherent . methods ) ;
115- let signal_docs = String :: from_iter ( pieces. inherent . signals ) ;
116- let constant_docs = String :: from_iter ( pieces. inherent . constants ) ;
117-
118- method_docs. extend ( virtual_methods) ;
119- let methods_block = if method_docs. is_empty ( ) {
120- String :: new ( )
121- } else {
122- format ! ( "<methods>{method_docs}</methods>" )
123- } ;
124- let signals_block = if signal_docs. is_empty ( ) {
125- String :: new ( )
126- } else {
127- format ! ( "<signals>{signal_docs}</signals>" )
128- } ;
129- let constants_block = if constant_docs. is_empty ( ) {
130- String :: new ( )
131- } else {
132- format ! ( "<constants>{constant_docs}</constants>" )
133- } ;
134- let ( brief, description) = match description
135- . split_once ( "[br]" ) {
136- Some ( ( brief, description) ) => ( brief, description. trim_start_matches ( "[br]" ) ) ,
137- None => ( description, "" ) ,
138- } ;
139-
140- format ! ( r#"<?xml version="1.0" encoding="UTF-8"?>
139+ let StructDocs {
140+ base,
141+ description,
142+ experimental,
143+ deprecated,
144+ members,
145+ } = pieces. definition ;
146+
147+
148+ let method_docs = String :: from_iter ( pieces. methods ) ;
149+ let signal_docs = String :: from_iter ( pieces. signals ) ;
150+ let constant_docs = String :: from_iter ( pieces. constants ) ;
151+
152+ let methods_block = if method_docs. is_empty ( ) {
153+ String :: new ( )
154+ } else {
155+ format ! ( "<methods>{method_docs}</methods>" )
156+ } ;
157+ let signals_block = if signal_docs. is_empty ( ) {
158+ String :: new ( )
159+ } else {
160+ format ! ( "<signals>{signal_docs}</signals>" )
161+ } ;
162+ let constants_block = if constant_docs. is_empty ( ) {
163+ String :: new ( )
164+ } else {
165+ format ! ( "<constants>{constant_docs}</constants>" )
166+ } ;
167+ let ( brief, description) = match description
168+ . split_once ( "[br]" ) {
169+ Some ( ( brief, description) ) => ( brief, description. trim_start_matches ( "[br]" ) ) ,
170+ None => ( description, "" ) ,
171+ } ;
172+
173+ format ! ( r#"<?xml version="1.0" encoding="UTF-8"?>
141174<class name="{class}" inherits="{base}"{deprecated}{experimental} xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
142175<brief_description>{brief}</brief_description>
143176<description>{description}</description>
@@ -146,8 +179,8 @@ pub fn gather_xml_docs() -> impl Iterator<Item = String> {
146179{signals_block}
147180<members>{members}</members>
148181</class>"# )
149- } ,
150- )
182+ } ,
183+ )
151184}
152185
153186/// # Safety
0 commit comments