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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//! ctl10n (compile time localization) provides you a simple way to embed messages
//! into binary file without embedding them into source. Internally, ctl10n generates
//! a simple `macro_rules!` macro `tr!()` from the provided a TOML file with strings.
//!
//! # Basic usage
//! Add ctl10n to your `build-dependencies` in your `Cargo.toml`.
//! If you want to use `include_strings` you'll need it in `dependencies` as well.
//!
//! ```toml
//! [package]
//! name = "example"
//! version = "0.1"
//! edition = "2018"
//!
//! [build-dependencies]
//! ctl10n = "0.1.0"
//!
//! [dependencies]
//! ctl10n = "0.1.0"
//! ```
//!
//! Add the following to your `build.rs`:
//! ```no_run
//! use ctl10n;
//!
//! fn main() {
//! println!("cargo:rerun-if-changed=build.rs");
//! println!("cargo:rerun-if-changed=strings.toml");
//! if let Err(err) = ctl10n::convert_default_strings_file() {
//! panic!("{}", err);
//! }
//! }
//! ```
//!
//! This will generate the file `$OUT_DIR/strings.rs` from `strings.toml`.
//! The TOML file with strings must be a table where all values are strings. Example `strings.toml`:
//! ```toml
//! message = "Some message"
//! message-with-args = "Some message with {arg}"
//! ```
//!
//! You should include `strings.rs` somewhere (for example, in `lib.rs`) to use the generated
//! macro. You can do this by calling the macro `ctl10n::include_strings!()` or manually,
//! using `include!()`.
//! After including the macro it can be used like this:
//! ```ignore
//! use ctl10n;
//!
//! ctl10n::include_strings!();
//!
//! fn main() {
//! // `tr!()` with one argument will be translated to string literal
//! println!(tr!("message"));
//! println!(tr!("message-with-args"), arg = "foobar");
//! // `tr!()` with multiple arguments will be translated to formatted `&String`
//! println!("{}", tr!("message-with-args", arg = "foobaz"))
//! }
//! ```
//!
//! Output of this code (assuming `strings.toml` from above):
//! ```text
//! Some message
//! Some message with foobar
//! Some message with foobaz
//! ```
//! Trying to use an unknown key or wrong format arguments is a compile-time error.
//!
//! # Multiple locales
//! You can use environment variables to provide a different locale at compile time:
//!
//! ```
//! use ctl10n;
//! use std::env;
//!
//! fn main() {
//! println!("cargo:rerun-if-changed=build.rs");
//! println!("cargo:rerun-if-changed=locales/*.toml");
//! if let Err(err) = ctl10n::convert_strings_file(
//! format!(
//! "locales/{}.toml",
//! &env::var("LOCALE").unwrap_or("en".to_string())
//! ),
//! "strings.rs",
//! ) {
//! panic!("{}", err);
//! }
//! }
//! ```
//!
//! `LOCALE=de cargo build`
use env;
use Display;
use fs;
use ;
use Path;
use quote;
pub use crate;
use parse_toml;
/// Include `tr!()` macro from generated file to current namespace.
/// If called without arguments includes file `$OUT_DIR/strings.rs`.
/// If called with one argument includes corresponding file in `$OUT_DIR`.
/// Convert TOML string to Rust source code with `tr!()` macro
/// Convert given TOML file to Rust source code in given location, providing
/// macro `tr!()`
/// Convert file `strings.toml` in current diretory to file `strings.rs` in `$OUT_DIR`
/// # Panics
/// If environment variable `OUT_DIR` is not set. You should call this function only
/// from `build.rs` script