zngur/
lib.rs

1//! This crate contains an API for using the Zngur code generator inside build scripts. For more information
2//! about the Zngur itself, see [the documentation](https://hkalbasi.github.io/zngur).
3
4use std::{
5    fs::File,
6    io::Write,
7    path::{Path, PathBuf},
8};
9
10use zngur_generator::{ParsedZngFile, ZngurGenerator};
11
12#[must_use]
13/// Builder for the Zngur generator.
14///
15/// Usage:
16/// ```ignore
17/// let crate_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
18/// let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
19/// Zngur::from_zng_file(crate_dir.join("main.zng"))
20///     .with_cpp_file(out_dir.join("generated.cpp"))
21///     .with_h_file(out_dir.join("generated.h"))
22///     .with_rs_file(out_dir.join("generated.rs"))
23///     .generate();
24/// ```
25pub struct Zngur {
26    zng_file: PathBuf,
27    h_file_path: Option<PathBuf>,
28    cpp_file_path: Option<PathBuf>,
29    rs_file_path: Option<PathBuf>,
30}
31
32impl Zngur {
33    pub fn from_zng_file(zng_file_path: impl AsRef<Path>) -> Self {
34        Zngur {
35            zng_file: zng_file_path.as_ref().to_owned(),
36            h_file_path: None,
37            cpp_file_path: None,
38            rs_file_path: None,
39        }
40    }
41
42    pub fn with_h_file(mut self, path: impl AsRef<Path>) -> Self {
43        self.h_file_path = Some(path.as_ref().to_owned());
44        self
45    }
46
47    pub fn with_cpp_file(mut self, path: impl AsRef<Path>) -> Self {
48        self.cpp_file_path = Some(path.as_ref().to_owned());
49        self
50    }
51
52    pub fn with_rs_file(mut self, path: impl AsRef<Path>) -> Self {
53        self.rs_file_path = Some(path.as_ref().to_owned());
54        self
55    }
56
57    pub fn generate(self) {
58        let file = ZngurGenerator::build_from_zng(ParsedZngFile::parse(self.zng_file));
59
60        let (rust, h, cpp) = file.render();
61        let rs_file_path = self.rs_file_path.expect("No rs file path provided");
62        let h_file_path = self.h_file_path.expect("No h file path provided");
63        File::create(rs_file_path)
64            .unwrap()
65            .write_all(rust.as_bytes())
66            .unwrap();
67        File::create(h_file_path)
68            .unwrap()
69            .write_all(h.as_bytes())
70            .unwrap();
71        if let Some(cpp) = cpp {
72            let cpp_file_path = self.cpp_file_path.expect("No cpp file path provided");
73            File::create(cpp_file_path)
74                .unwrap()
75                .write_all(cpp.as_bytes())
76                .unwrap();
77        }
78    }
79}