fea_rs/compile/
opts.rs

1//! Options used during compilation
2//!
3
4// NOTE: This was designed to originate from the command line, but that isn't
5// a very important part of our API, and a more natural place for us to specify
6// options is in the 'Compiler' struct itself.
7
8const DEFAULT_N_MESSAGES_TO_PRINT: usize = 100;
9
10/// Options for configuring compilation behaviour.
11#[derive(Clone, Debug)]
12pub struct Opts {
13    pub(crate) make_post_table: bool,
14    pub(crate) max_n_errors: usize,
15    pub(crate) compile_gsub: bool,
16    pub(crate) compile_gpos: bool,
17}
18
19impl Opts {
20    /// Create a new empty set of options
21    pub fn new() -> Self {
22        Self::default()
23    }
24
25    /// If `true`, we will generate a post table from the glyph map.
26    pub fn make_post_table(mut self, flag: bool) -> Self {
27        self.make_post_table = flag;
28        self
29    }
30
31    /// Specify the number of errors to print when printing a [`DiagnosticSet`].
32    ///
33    /// Default is some arbitrary 'reasonable' number (currently 100.) To
34    /// suppress errors, pass `0`. For 'all errors', pass `usize::MAX`.
35    ///
36    /// [`DiagnosticSet`]: crate::DiagnosticSet
37    pub fn max_error_messages(mut self, max_n_errors: usize) -> Self {
38        self.max_n_errors = max_n_errors;
39        self
40    }
41
42    /// Specify whether or not we should compile the GPOS table. Default is `true`.
43    pub fn compile_gpos(mut self, flag: bool) -> Self {
44        self.compile_gpos = flag;
45        self
46    }
47
48    /// Specify whether or not we should compile the GSUB table. Default is `true`.
49    pub fn compile_gsub(mut self, flag: bool) -> Self {
50        self.compile_gsub = flag;
51        self
52    }
53}
54
55impl Default for Opts {
56    fn default() -> Self {
57        Self {
58            make_post_table: false,
59            max_n_errors: DEFAULT_N_MESSAGES_TO_PRINT,
60            compile_gsub: true,
61            compile_gpos: true,
62        }
63    }
64}
65
66#[cfg(test)]
67mod tests {
68
69    static OSWALD_DIR: &str = "./test-data/real-files/oswald";
70    use std::path::Path;
71
72    use crate::{
73        compile::{Compilation, MockVariationInfo, NopFeatureProvider},
74        Compiler,
75    };
76
77    use super::*;
78
79    #[test]
80    fn skip_tables() {
81        fn compile_oswald(opts: Opts) -> Compilation {
82            let glyph_order = Path::new(OSWALD_DIR).join("glyph_order.txt");
83            let features = Path::new(OSWALD_DIR).join("features.fea");
84            let glyph_order = std::fs::read_to_string(glyph_order).unwrap();
85            let glyph_order = crate::compile::parse_glyph_order(&glyph_order).unwrap();
86            Compiler::<NopFeatureProvider, MockVariationInfo>::new(features, &glyph_order)
87                .with_opts(opts)
88                .compile()
89                .unwrap()
90        }
91
92        // compile everything:
93        let compilation = compile_oswald(Opts::new());
94        assert!(compilation.gpos.is_some());
95        assert!(compilation.gsub.is_some());
96
97        // only gpos
98        let compilation = compile_oswald(Opts::new().compile_gsub(false));
99        assert!(compilation.gpos.is_some());
100        assert!(compilation.gsub.is_none());
101
102        // only gsub
103        let compilation = compile_oswald(Opts::new().compile_gpos(false));
104        assert!(compilation.gpos.is_none());
105        assert!(compilation.gsub.is_some());
106    }
107}