cargo_wiki/generators/
struct_gen.rs1use crate::generators::generic_gen::GenericGenerator;
2use crate::generators::type_gen::TypeGenerator;
3use crate::generators::visibility_gen::VisibilityGenerator;
4use crate::generators::{ExternalCrates, Generator, Index, Paths};
5use anyhow::Result;
6use rustdoc_types::{Item, ItemEnum, StructKind};
7
8pub struct StructGenerator;
9
10impl Generator for StructGenerator {
11 fn generate_syntax(
14 item: &Item,
15 index: &Index,
16 paths: &Paths,
17 external_crates: &ExternalCrates,
18 ) -> Result<String> {
19 if let ItemEnum::Struct(rustdoc_types::Struct {
20 kind,
21 generics,
22 impls,
23 }) = &item.inner
24 {
25 let mut syntax = String::from("```rust\n");
26 syntax.push_str(&VisibilityGenerator::generate_visibility(&item.visibility));
27 syntax.push_str("struct ");
28
29 if let Some(struct_name) = &item.name {
30 let (generic_params, where_predicates) =
31 GenericGenerator::generate_generics(&generics)?;
32 syntax.push_str(struct_name);
33 syntax.push_str(&generic_params);
34 syntax.push_str(&where_predicates);
35
36 match kind {
37 StructKind::Unit => {
38 syntax.push_str(";");
39 }
40 StructKind::Tuple(unnamed_fields) => {
41 syntax.push_str("(");
42 for (i, unnamed_field) in unnamed_fields.iter().enumerate() {
43 if i != 0 {
44 syntax.push_str(", ");
45 }
46
47 if let Some(field_id) = unnamed_field {
48 let Some(field_item) = index.get(field_id) else {
49 return Err(anyhow::Error::msg(format!(
50 "Failed to find item with id: {} in index",
51 field_id.0
52 )));
53 };
54 let ItemEnum::StructField(type_) = &field_item.inner else {
55 return Err(anyhow::Error::msg(format!("inner can't be anything other than `StructField in index id: {}", field_id.0)));
56 };
57 syntax.push_str(&TypeGenerator::type_to_string(type_));
58 } else {
59 syntax.push_str("/* private field */");
60 }
61 }
62 syntax.push_str(")");
63 }
64 StructKind::Plain {
65 fields,
66 has_stripped_fields,
67 } => {
68 if where_predicates.is_empty() {
69 syntax.push_str(" {\n");
70 } else {
71 syntax.push_str("\n{")
72 }
73
74 for field_id in fields {
75 let Some(field_item) = index.get(field_id) else {
76 return Err(anyhow::Error::msg(format!(
77 "Failed to find item with id: {} in index",
78 field_id.0
79 )));
80 };
81 let Some(field_name) = &field_item.name else {
82 return Err(anyhow::Error::msg(format!(
83 "Failed to find name of struct field with id: {} in index",
84 field_id.0
85 )));
86 };
87 let ItemEnum::StructField(type_) = &field_item.inner else {
88 return Err(anyhow::Error::msg(format!("inner can't be anything other than `StructField in index id: {}", field_id.0)));
89 };
90
91 syntax.push_str("\t");
92 syntax.push_str(&VisibilityGenerator::generate_visibility(
93 &field_item.visibility,
94 ));
95 syntax.push_str(field_name);
96 syntax.push_str(": ");
97 syntax.push_str(&TypeGenerator::type_to_string(type_));
98 syntax.push_str(",\n");
99 }
100
101 if *has_stripped_fields {
102 syntax.push_str("\t/* private fields */\n");
103 }
104 syntax.push_str("}");
105 }
106 }
107 syntax.push_str("\n```\n");
108 return Ok(syntax);
109 }
110 return Err(anyhow::Error::msg("Can't document a struct with no name"));
111 }
112 Err(anyhow::Error::msg(
113 "Umm... Only Item with inner ItemEnum::Struct to be used here",
114 ))
115 }
116}