1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// TODO: replace with simple contant when rust supports using them as arguments for std macros
// https://github.com/rust-lang/rust/issues/53749
#[macro_export]
macro_rules! MAPPINGS_FILE_NAME {
    () => {
        "css_mod_mappings.rs"
    };
}

#[allow(clippy::needless_doctest_main)]
/// Initializes CSS name mappings which is later retreived with `css_mod::get!()`.
///
/// Should be called once in a lifetime of the program, before first call to `css_mod::get!()`.
/// Expects mappings where already generated by `css_mod::Compiler` in build script.
///
/// # Example
///
/// ```ignore
/// // main.rs
///
/// fn main() {
///     css_mod::init!();
/// }
/// ```
#[macro_export]
macro_rules! init {
    () => {{
        let mappings = include!(concat!(
            env!(
                "OUT_DIR",
                "OUT_DIR environment variable was not found. \
                    Help: setup css_mod::Compiler in build.rs"
            ),
            "/",
            ::css_mod::MAPPINGS_FILE_NAME!()
        ));

        // cannot add friendly error message if mappings file doesn't not exist since include!()
        // does not support custom error messages. mappings file can be absent eg. when user adds
        // build.rs to their project but does not call compiler in it.
        // fix for this is to create custom proc_macro which includes mappings and produces good
        // error message, but i don't want to bother with separate proc_macro crate only because
        // of error messages.

        ::css_mod::MAPPINGS.set(mappings).expect(
            "Mappings were already initialized before. \
                Help: call css_mod::init!() once early (eg. in main.rs)",
        );
    }};
}

/// Gets name mapping for CSS module.
///
/// # Example
///
/// ```no_run
/// // my-component.rs
///
/// let css = css_mod::get!("my-component.css");
/// let global_class_name = css["local-class-name"];
/// ```
#[macro_export]
macro_rules! get {
    ($a:expr) => {{
        let css_file = ::std::path::Path::new(file!()).with_file_name($a);
        ::css_mod::get_mapping(css_file)
    }};
}