playdate_bindgen/gen/
mod.rs1#![cfg(feature = "extra-codegen")]
2use std::io::Write;
3use std::path::Path;
4use utils::toolchain::sdk::Sdk;
5use quote::ToTokens;
6use proc_macro2::TokenStream;
7
8use crate::Result;
9
10pub mod docs;
11
12
13#[allow(unused_variables)]
14pub fn engage(source: &bindgen::Bindings,
15 features: &crate::cfg::Features,
16 sdk: &Sdk,
17 root: Option<&str>)
18 -> Result<Bindings> {
19 let root_struct_name = root.unwrap_or("PlaydateAPI");
20
21 #[allow(unused_mut)]
22 let mut bindings = syn::parse_file(&source.to_string())?;
23
24 #[allow(unused_assignments)]
25 #[cfg(feature = "documentation")]
26 let docset = if features.documentation {
27 let docset_new = docs::parser::parse(sdk)?;
28 docs::gen::engage(&mut bindings, root_struct_name, &docset_new)?;
29 Some(docset_new)
30 } else {
31 None
32 };
33
34 let mut module = TokenStream::new();
35 bindings.to_tokens(&mut module);
36
37 Ok(Bindings { module,
38 #[cfg(feature = "documentation")]
39 docset })
40}
41
42
43#[derive(Debug)]
45pub struct Bindings {
46 module: TokenStream,
47
48 #[cfg(feature = "documentation")]
50 docset: Option<docs::DocsMap>,
51 }
53
54impl crate::Bindings {
55 #[cfg(feature = "documentation")]
56 pub fn docset(&self) -> Option<&docs::DocsMap> {
57 match self {
58 crate::Bindings::Bindgen(_) => None,
59 crate::Bindings::Engaged(this) => this.docset.as_ref(),
60 }
61 }
62}
63
64impl Bindings {
65 pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> std::io::Result<()> {
67 let file = std::fs::OpenOptions::new().write(true)
68 .truncate(true)
69 .create(true)
70 .open(path.as_ref())?;
71 self.write(Box::new(file))?;
72 Ok(())
73 }
74
75 pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> std::io::Result<()> {
77 let source = self.module.to_string();
79 let output = match crate::rustfmt(None, source.clone(), None) {
80 Ok(output) => output,
81 Err(err) => {
82 println!("cargo::warning=Rustfmt error: {err}");
83
84 let output: String;
85 #[cfg(feature = "pretty-please")]
86 {
87 let tokens = &self.module;
88 output = prettyplease::unparse(&syn::parse_quote!(#tokens));
89 }
90 #[cfg(not(feature = "prettyplease"))]
91 {
92 output = source;
93 }
94 output
95 },
96 };
97
98 writer.write_all(output.as_bytes())?;
99 Ok(())
100 }
101}
102
103
104impl std::fmt::Display for Bindings {
105 #[inline(always)]
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 let mut bytes = vec![];
108 self.write(Box::new(&mut bytes) as Box<dyn Write>)
109 .expect("writing to a vec cannot fail");
110 f.write_str(std::str::from_utf8(&bytes).expect("we should only write bindings that are valid utf-8"))
111 }
112}