precis_tools/generators.rs
1use crate::error::Error;
2use crate::file_writer;
3use std::fs::File;
4use std::path::Path;
5
6pub mod ascii7;
7pub mod backward_compatible;
8pub mod bidi_class;
9pub mod codepoints;
10pub mod derived_property;
11pub mod exceptions;
12pub mod ucd_generator;
13pub mod unicode_version;
14
15/// This is the main code generator element. It aggregates other
16/// [`CodeGen`] elements. The resulting file will contain the
17/// code generated by every element added to the code generator.
18pub struct RustCodeGen {
19 file: File,
20 generators: Vec<Box<dyn CodeGen>>,
21}
22
23impl RustCodeGen {
24 /// Creates a new Rust code generator
25 /// # Arguments:
26 /// * `filename` - The file name
27 /// # Returns:
28 /// This method returns a new [`RustCodeGen`] instance if no errors
29 /// occurs when the file is created
30 pub fn new<P>(filename: P) -> Result<Self, Error>
31 where
32 P: AsRef<Path>,
33 {
34 Ok(Self {
35 file: File::create(filename)?,
36 generators: Vec::new(),
37 })
38 }
39
40 /// Adds an element to the code generator. Each element must implement
41 /// [`CodeGen`] trait.
42 /// # Arguments:
43 /// * `gen` - The code generator element
44 pub fn add(&mut self, gen: Box<dyn CodeGen>) {
45 self.generators.push(gen);
46 }
47
48 /// Write the code into the file created on construction. In case of
49 /// error, the file generated could stay in an incomplete or
50 /// inconsistent state.
51 pub fn generate_code(&mut self) -> Result<(), Error> {
52 file_writer::generate_file_header(&mut self.file)?;
53 let it = self.generators.iter_mut();
54 for gen in it {
55 gen.generate_code(&mut self.file)?;
56 }
57 Ok(())
58 }
59}
60
61/// Trait implemented by all elements which are able to generate code.
62pub trait CodeGen {
63 /// Writes the Rust code itself.
64 /// # Arguments:
65 /// * `file` - The output file
66 fn generate_code(&mut self, file: &mut File) -> Result<(), Error>;
67}