Skip to content

Commit 8bf6dd5

Browse files
committed
feat: ✨ improved define_app! macro
`root` now has a default (`root`) and `locales` doesn't need to be specified if it's not being used. BREAKING CHANGE: `error_pages` now comes after `templates` and `no_i18n` apps should not define `locales` at all
1 parent e41d3e5 commit 8bf6dd5

File tree

4 files changed

+91
-20
lines changed

4 files changed

+91
-20
lines changed

examples/cli/src/lib.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,9 @@ mod pages;
44
use perseus::define_app;
55

66
define_app! {
7-
root: "root",
8-
error_pages: crate::error_pages::get_error_pages(),
97
templates: [
108
crate::pages::index::get_page::<G>(),
119
crate::pages::about::get_page::<G>()
1210
],
13-
locales: {
14-
default: "en-US",
15-
other: [],
16-
no_i18n: true
17-
}
11+
error_pages: crate::error_pages::get_error_pages()
1812
}

examples/i18n/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ mod templates;
44
use perseus::define_app;
55

66
define_app! {
7-
root: "root",
8-
error_pages: crate::error_pages::get_error_pages(),
97
templates: [
108
crate::templates::about::get_template::<G>(),
119
crate::templates::index::get_template::<G>()
1210
],
11+
error_pages: crate::error_pages::get_error_pages(),
1312
locales: {
1413
default: "en-US",
1514
other: ["fr-FR", "es-ES"]

examples/showcase/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ mod templates;
44
use perseus::define_app;
55

66
define_app! {
7-
root: "root",
8-
error_pages: crate::error_pages::get_error_pages(),
97
templates: [
108
crate::templates::index::get_template::<G>(),
119
crate::templates::about::get_template::<G>(),
@@ -16,6 +14,7 @@ define_app! {
1614
crate::templates::time::get_template::<G>(),
1715
crate::templates::amalgamation::get_template::<G>()
1816
],
17+
error_pages: crate::error_pages::get_error_pages(),
1918
locales: {
2019
default: "en-US",
2120
other: ["fr-FR", "es-ES"]

packages/perseus/src/macros.rs

+88-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ macro_rules! define_get_config_manager {
1515
}
1616
};
1717
}
18+
/// An internal macro used for defining the HTML `id` at which to render the Perseus app (which requires multiple branches). The default
19+
/// is `root`.
20+
#[macro_export]
21+
macro_rules! define_app_root {
22+
() => {
23+
pub static APP_ROOT: &str = "root";
24+
};
25+
($root_id:literal) => {
26+
pub static APP_ROOT: &str = $root_id;
27+
};
28+
}
1829
/// An internal macro used for defining a function to get the user's preferred translations manager (which requires multiple branches).
1930
#[macro_export]
2031
macro_rules! define_get_translations_manager {
@@ -72,18 +83,17 @@ macro_rules! define_get_locales {
7283
}
7384
}
7485
};
86+
// With i18n disabled, the default locale will be `xx-XX`
7587
{
7688
default: $default_locale:literal,
7789
other: [$($other_locale:literal),*],
7890
no_i18n: $no_i18n:literal
7991
} => {
8092
pub fn get_locales() -> $crate::Locales {
8193
$crate::Locales {
82-
default: $default_locale.to_string(),
83-
other: vec![
84-
$($other_locale.to_string()),*
85-
],
86-
using_i18n: !$no_i18n
94+
default: "xx-XX".to_string(),
95+
other: Vec::new(),
96+
using_i18n: false
8797
}
8898
}
8999
};
@@ -95,17 +105,18 @@ macro_rules! define_get_locales {
95105
/// to `true` in `locales`. Note that you must still specify a default locale for verbosity and correctness. If you specify `no_i18n` and
96106
/// a custom translations manager, the latter will override.
97107
///
98-
/// Warning: all properties must currently be in the correct order (`root`, `error_pages`, `templates`, `locales`, `config_manager`,
108+
/// Warning: all properties must currently be in the correct order (`root`, `templates`, `error_pages`, `locales`, `config_manager`,
99109
/// `translations_manager`).
100110
// TODO make this syntax even more compact and beautiful? (error pages inside templates?)
101111
#[macro_export]
102112
macro_rules! define_app {
113+
// With locales
103114
{
104-
root: $root_selector:literal,
105-
error_pages: $error_pages:expr,
115+
$(root: $root_selector:literal,)?
106116
templates: [
107117
$($template:expr),+
108118
],
119+
error_pages: $error_pages:expr,
109120
// This deliberately enforces verbose i18n definition, and forces developers to consider i18n as integral
110121
locales: {
111122
default: $default_locale:literal,
@@ -116,9 +127,77 @@ macro_rules! define_app {
116127
$(,config_manager: $config_manager:expr)?
117128
$(,translations_manager: $translations_manager:expr)?
118129
} => {
130+
define_app!(
131+
@define_app,
132+
{
133+
$(root: $root_selector,)?
134+
templates: [
135+
$($template),+
136+
],
137+
error_pages: $error_pages,
138+
locales: {
139+
default: $default_locale,
140+
// The user doesn't have to define any other locales (but they'll still get locale detection and the like)
141+
other: [$($other_locale),*]
142+
}
143+
$(,config_manager: $config_manager)?
144+
$(,translations_manager: $translations_manager)?
145+
}
146+
);
147+
};
148+
// Without locales (default locale is set to xx-XX)
149+
{
150+
$(root: $root_selector:literal,)?
151+
templates: [
152+
$($template:expr),+
153+
],
154+
error_pages: $error_pages:expr
155+
$(,config_manager: $config_manager:expr)?
156+
$(,translations_manager: $translations_manager:expr)?
157+
} => {
158+
define_app!(
159+
@define_app,
160+
{
161+
$(root: $root_selector,)?
162+
templates: [
163+
$($template),+
164+
],
165+
error_pages: $error_pages,
166+
// This deliberately enforces verbose i18n definition, and forces developers to consider i18n as integral
167+
locales: {
168+
default: "xx-XX",
169+
other: [],
170+
no_i18n: true
171+
}
172+
$(,config_manager: $config_manager)?
173+
$(,translations_manager: $translations_manager)?
174+
}
175+
);
176+
};
177+
// This is internal, and allows syntax abstractions and defaults
178+
(
179+
@define_app,
180+
{
181+
$(root: $root_selector:literal,)?
182+
templates: [
183+
$($template:expr),+
184+
],
185+
error_pages: $error_pages:expr,
186+
// This deliberately enforces verbose i18n definition, and forces developers to consider i18n as integral
187+
locales: {
188+
default: $default_locale:literal,
189+
// The user doesn't have to define any other locales
190+
other: [$($other_locale:literal),*]
191+
// If this is defined at all, i18n will be disabled and the default locale will be set to `xx-XX`
192+
$(,no_i18n: $no_i18n:literal)?
193+
}
194+
$(,config_manager: $config_manager:expr)?
195+
$(,translations_manager: $translations_manager:expr)?
196+
}
197+
) => {
119198
/// The html `id` that will find the app root to render Perseus in. For server-side interpolation, this MUST be an element of
120199
/// the form <div id="root_id">` in your markup (double or single quotes, `root_id` replaced by what this property is set to).
121-
pub const APP_ROOT: &str = $root_selector;
200+
$crate::define_app_root!($($root_selector)?);
122201

123202
/// Gets the config manager to use. This allows the user to conveniently test production managers in development. If nothing is
124203
/// given, the filesystem will be used.

0 commit comments

Comments
 (0)