bui_backend_codegen/
lib.rs1#![deny(missing_docs)]
3
4use std::error::Error;
5use std::fs::OpenOptions;
6use std::io::Write;
7use std::path::Path;
8
9#[cfg(feature = "bundle_files")]
12fn create_codegen_file<P, Q>(files_dir: P, codegen_fname: Q) -> Result<(), std::io::Error>
13where
14 P: AsRef<Path>,
15 Q: AsRef<Path>,
16{
17 let entries = walkdir::WalkDir::new(files_dir.as_ref())
19 .into_iter()
20 .map(|entry| entry.map(|entry| entry.path().into()))
21 .collect::<Result<Vec<std::path::PathBuf>, walkdir::Error>>()?;
22
23 println!("cargo:rerun-if-changed={}", files_dir.as_ref().display());
25 for entry in entries.iter() {
26 println!("cargo:rerun-if-changed={}", entry.display());
27 }
28
29 let required: std::path::PathBuf = files_dir.as_ref().join("index.html");
31 if !entries.contains(&required) {
32 return Err(std::io::Error::new(
33 std::io::ErrorKind::Other,
34 format!("no {:?} file", required),
35 ));
36 }
37
38 let codegen_fname_str = format!("{}", codegen_fname.as_ref().display());
39 includedir_codegen::start("PUBLIC")
41 .dir(files_dir, includedir_codegen::Compression::None)
42 .build(&codegen_fname_str)?;
43 Ok(())
44}
45
46#[cfg(feature = "serve_files")]
48fn create_codegen_file<P, Q>(_: P, codegen_fname: Q) -> Result<(), Box<dyn Error>>
49where
50 P: AsRef<Path>,
51 Q: AsRef<Path>,
52{
53 let out_dir = std::env::var("OUT_DIR")?;
54 let dest_path = std::path::Path::new(&out_dir).join(codegen_fname);
55 std::fs::File::create(dest_path)?;
56 Ok(())
57}
58
59#[cfg(not(any(feature = "bundle_files", feature = "serve_files")))]
60fn create_codegen_file<P, Q>(_: P, codegen_fname: Q) -> Result<(), Box<Error>>
61where
62 P: AsRef<Path>,
63 Q: AsRef<Path>,
64{
65 compile_error!(
68 "You are attempting to compile without a required feature flag \
69 being used. You must use one of either `bundle_files` or `serve_files`"
70 );
71}
72
73fn include_config<P, Q>(files_dir: P, codegen_fname: Q) -> Result<(), Box<dyn Error>>
76where
77 P: AsRef<Path>,
78 Q: AsRef<Path>,
79{
80 let out_dir = std::env::var("OUT_DIR")?;
81 let dest_path = std::path::Path::new(&out_dir).join(codegen_fname);
82
83 let mut f = OpenOptions::new().append(true).open(dest_path)?;
84
85 writeln!(f, "use bui_backend::lowlevel::Config;")?;
86 writeln!(f, "fn get_default_config() -> Config {{")?;
87 writeln!(f, " Config {{")?;
88 writeln!(
89 f,
90 " serve_filepath: std::path::Path::new(r#\"{}\"#),",
91 files_dir.as_ref().display()
92 )?;
93 #[cfg(feature = "bundle_files")]
94 {
95 writeln!(f, " bundled_files: &PUBLIC,")?;
96 }
97 writeln!(f, " channel_size: 10,")?;
98 writeln!(f, " cookie_name: \"client\".into(),")?;
99 writeln!(f, " }}")?;
100 writeln!(f, "}}")?;
101
102 Ok(())
103}
104
105pub fn codegen<P, Q>(files_dir: P, generated_path: Q) -> Result<(), Box<dyn Error>>
113where
114 P: AsRef<Path>,
115 Q: AsRef<Path>,
116{
117 create_codegen_file(&files_dir, &generated_path)?;
118 include_config(&files_dir, &generated_path)
119}