sphinx_rustdocgen/directives/
type_directive.rs1use syn::{ForeignItemType, ImplItemType, ItemType, TraitItemType, Visibility};
20
21use crate::directives::directive_options::{DirectiveOption, DirectiveVisibility, IndexEntryType};
22use crate::directives::{extract_doc_from_attrs, Directive};
23use crate::formats::{MdContent, MdDirective, RstContent, RstDirective};
24use crate::nodes::{nodes_for_generics, nodes_for_where_clause, Node};
25
26#[derive(Clone, Debug)]
28pub struct TypeDirective {
29 pub(crate) name: String,
31 pub(crate) ident: String,
33 pub(crate) options: Vec<DirectiveOption>,
35 pub(crate) content: Vec<String>,
37}
38
39macro_rules! type_from_item {
41 ($parent_path:expr, $item:expr, $vis:expr, $inherited:expr, $index:expr) => {{
42 let name = format!("{}::{}", $parent_path, &$item.ident);
43
44 let mut nodes = vec![
45 Node::Keyword(TypeDirective::DIRECTIVE_NAME),
46 Node::Space,
47 Node::Name($item.ident.to_string()),
48 ];
49 nodes.extend(nodes_for_generics(&$item.generics));
50 if let Some(wc) = &$item.generics.where_clause {
51 nodes.extend(nodes_for_where_clause(wc));
52 }
53
54 let options = vec![
55 DirectiveOption::Index($index),
56 DirectiveOption::Vis(DirectiveVisibility::effective_visibility(&$vis, $inherited)),
57 DirectiveOption::Layout(nodes),
58 ];
59
60 TypeDirective {
61 name,
62 ident: $item.ident.to_string(),
63 options,
64 content: extract_doc_from_attrs(&$item.attrs),
65 }
66 }};
67}
68
69impl TypeDirective {
70 const DIRECTIVE_NAME: &'static str = "type";
71
72 pub(crate) fn from_item(parent_path: &str, item: &ItemType) -> Directive {
74 Directive::Type(type_from_item!(
75 parent_path,
76 item,
77 item.vis,
78 &None,
79 IndexEntryType::Normal
80 ))
81 }
82
83 pub(crate) fn from_impl_item(
85 parent_path: &str,
86 item: &ImplItemType,
87 inherited_visibility: &Option<&Visibility>,
88 ) -> Directive {
89 Directive::Type(type_from_item!(
90 parent_path,
91 item,
92 item.vis,
93 inherited_visibility,
94 IndexEntryType::None
95 ))
96 }
97
98 pub(crate) fn from_trait_item(
101 parent_path: &str,
102 item: &TraitItemType,
103 inherited_visibility: &Option<&Visibility>,
104 ) -> Directive {
105 Directive::Type(type_from_item!(
106 parent_path,
107 item,
108 Visibility::Inherited,
109 inherited_visibility,
110 IndexEntryType::SubEntry
111 ))
112 }
113
114 pub(crate) fn from_extern(parent_path: &str, item: &ForeignItemType) -> Directive {
116 Directive::Type(type_from_item!(
117 parent_path,
118 item,
119 item.vis,
120 &None,
121 IndexEntryType::Normal
122 ))
123 }
124
125 pub(crate) fn directive_visibility(&self) -> &DirectiveVisibility {
127 if let DirectiveOption::Vis(v) = &self.options[1] {
128 return v;
129 }
130 unreachable!("Type: order of options changed")
131 }
132
133 pub(crate) fn change_parent(&mut self, new_parent: &str) {
135 self.name = format!("{new_parent}::{}", self.ident);
136 }
137}
138
139impl RstDirective for TypeDirective {
140 fn get_rst_text(self, level: usize, max_visibility: &DirectiveVisibility) -> Vec<String> {
142 if self.directive_visibility() > max_visibility {
143 return vec![];
144 }
145 let content_indent = Self::make_content_indent(level);
146
147 let mut text =
148 Self::make_rst_header(Self::DIRECTIVE_NAME, &self.name, &self.options, level);
149 text.extend(self.content.get_rst_text(&content_indent));
150
151 text
152 }
153}
154
155impl MdDirective for TypeDirective {
156 fn get_md_text(self, fence_size: usize, max_visibility: &DirectiveVisibility) -> Vec<String> {
158 if self.directive_visibility() > max_visibility {
159 return vec![];
160 }
161 let fence = Self::make_fence(fence_size);
162
163 let mut text =
164 Self::make_md_header(Self::DIRECTIVE_NAME, &self.name, &self.options, &fence);
165 text.extend(self.content.get_md_text());
166
167 text.push(fence);
168 text
169 }
170}