lwb_parser/codegen/
mod.rs1use convert_case::{Case, Casing};
2use regex::Captures;
3use std::fs::File;
4use std::io::{Read, Write};
5use std::path::{Path, PathBuf};
6use std::process::Command;
7use std::{fs, io};
8
9mod check_recursive;
10mod error;
11mod generate_file_headers;
12mod generate_from_pairs;
13mod generate_misc;
14mod generate_structs;
15mod generate_trait_impls;
16pub mod manager;
17
18fn sanitize_identifier(id: &str) -> String {
19 id.to_case(Case::UpperCamel)
20}
21
22pub struct FormattingFile(Option<File>, PathBuf);
24
25impl FormattingFile {
26 pub fn create(p: impl AsRef<Path>) -> io::Result<Self> {
27 Ok(Self(Some(File::create(&p)?), p.as_ref().to_path_buf()))
28 }
29
30 pub fn open(p: impl AsRef<Path>) -> io::Result<Self> {
31 Ok(Self(Some(File::open(&p)?), p.as_ref().to_path_buf()))
32 }
33}
34
35fn try_fmt(p: impl AsRef<Path>) -> io::Result<()> {
36 println!("Formatting {:?}", p.as_ref());
37 Command::new("rustfmt").arg(p.as_ref()).spawn()?.wait()?;
38
39 let r = regex::Regex::new(r#"#\[doc *= *"(.*)"\]"#).expect("should compile");
40 let rq = regex::Regex::new(r#"\\(.)"#).expect("should compile");
41
42 let code = fs::read_to_string(&p)?;
43 let replaced = r.replace_all(&code, |caps: &Captures| {
44 format!("///{}", rq.replace_all(&caps[1], "$1"))
45 });
46 fs::write(&p, replaced.as_ref())?;
47
48 Ok(())
49}
50
51impl Drop for FormattingFile {
52 fn drop(&mut self) {
53 drop(self.0.take());
54
55 if let Err(e) = try_fmt(&self.1) {
56 eprintln!("{}", e);
57 }
58 }
59}
60
61impl Read for FormattingFile {
62 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
63 self.0.as_ref().unwrap().read(buf)
64 }
65}
66
67impl Write for FormattingFile {
68 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
69 self.0.as_ref().unwrap().write(buf)
70 }
71
72 fn flush(&mut self) -> std::io::Result<()> {
73 self.0.as_ref().unwrap().flush()
74 }
75}