interoptopus_backend_c/
docs.rs1use crate::CWriter;
2use interoptopus::indented;
3use interoptopus::lang::c::{CType, Function};
4use interoptopus::util::sort_types_by_dependencies;
5use interoptopus::writer::IndentWriter;
6use interoptopus::{Error, Inventory};
7use std::fs::File;
8use std::path::Path;
9
10pub struct DocGenerator<W> {
11 inventory: Inventory,
12 c_writer: W,
13}
14
15impl<W: CWriter> DocGenerator<W> {
16 pub fn new(inventory: Inventory, w: W) -> Self {
17 Self { inventory, c_writer: w }
18 }
19
20 pub fn inventory(&self) -> &Inventory {
21 &self.inventory
22 }
23
24 pub fn write_types(&self, w: &mut IndentWriter) -> Result<(), Error> {
25 indented!(w, r#"# Types "#)?;
26
27 let mut known_function_pointers = vec![];
28
29 for the_type in &sort_types_by_dependencies(self.inventory().ctypes().to_vec()) {
30 self.write_type_definition(w, the_type, &mut known_function_pointers)?;
31 }
32
33 Ok(())
34 }
35
36 pub fn write_type_definition(&self, w: &mut IndentWriter, the_type: &CType, known_function_pointers: &mut Vec<String>) -> Result<(), Error> {
37 let meta = match the_type {
38 CType::Primitive(_) => return Ok(()),
39 CType::Array(_) => return Ok(()),
40 CType::Enum(e) => e.meta(),
41 CType::Opaque(o) => o.meta(),
42 CType::Composite(c) => c.meta(),
43 CType::FnPointer(_) => return Ok(()),
44 CType::ReadPointer(_) => return Ok(()),
45 CType::ReadWritePointer(_) => return Ok(()),
46 CType::Pattern(_) => return Ok(()),
47 };
48
49 w.newline()?;
50 w.newline()?;
51
52 indented!(w, r#"## {} "#, the_type.name_within_lib())?;
53 w.newline()?;
54
55 for line in meta.documentation().lines() {
56 indented!(w, r#"{}"#, line.trim())?;
57 w.newline()?;
58 }
59
60 indented!(w, r#"```"#)?;
61 self.c_writer.write_type_definition(w, the_type, known_function_pointers)?;
62 indented!(w, r#"```"#)?;
63
64 Ok(())
65 }
66
67 pub fn write_functions(&self, w: &mut IndentWriter) -> Result<(), Error> {
68 indented!(w, r#"# Functions "#)?;
69
70 for the_type in self.inventory().functions() {
71 self.write_function(w, the_type)?;
72 }
73
74 Ok(())
75 }
76
77 fn write_function(&self, w: &mut IndentWriter, function: &Function) -> Result<(), Error> {
78 indented!(w, r#"## {} "#, function.name())?;
79
80 for line in function.meta().documentation().lines() {
81 if line.trim().starts_with('#') {
82 write!(w.writer(), "##")?;
83 }
84 indented!(w, r#"{}"#, line.trim())?;
85 w.newline()?;
86 }
87
88 indented!(w, r#"```"#)?;
89 self.c_writer.write_function_declaration(w, function, 80)?;
90 indented!(w, r#"```"#)?;
91
92 w.newline()?;
93
94 Ok(())
95 }
96
97 pub fn write_to(&self, w: &mut IndentWriter) -> Result<(), Error> {
98 self.write_types(w)?;
99 self.write_functions(w)?;
100
101 w.newline()?;
102
103 Ok(())
104 }
105
106 pub fn write_file<P: AsRef<Path>>(&self, file_name: P) -> Result<(), Error> {
107 let mut file = File::create(file_name)?;
108 let mut writer = IndentWriter::new(&mut file);
109
110 self.write_to(&mut writer)
111 }
112}