cli: templates check: add option to --stabilise date and RNG
This commit is contained in:
@@ -8,6 +8,7 @@ use std::{fmt::Write, process::ExitCode};
|
||||
|
||||
use anyhow::{Context as _, bail};
|
||||
use camino::Utf8PathBuf;
|
||||
use chrono::DateTime;
|
||||
use clap::Parser;
|
||||
use figment::Figment;
|
||||
use mas_config::{
|
||||
@@ -34,6 +35,12 @@ enum Subcommand {
|
||||
/// The directory must either not exist or be empty.
|
||||
#[arg(long = "out-dir")]
|
||||
out_dir: Option<Utf8PathBuf>,
|
||||
|
||||
/// Attempt to remove 'unstable' template input data such as asset
|
||||
/// hashes, in order to make renders more reproducible between
|
||||
/// versions.
|
||||
#[arg(long = "stabilise")]
|
||||
stabilise: bool,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -41,7 +48,7 @@ impl Options {
|
||||
pub async fn run(self, figment: &Figment) -> anyhow::Result<ExitCode> {
|
||||
use Subcommand as SC;
|
||||
match self.subcommand {
|
||||
SC::Check { out_dir } => {
|
||||
SC::Check { out_dir, stabilise } => {
|
||||
let _span = info_span!("cli.templates.check").entered();
|
||||
|
||||
let template_config = TemplatesConfig::extract_or_default(figment)
|
||||
@@ -59,9 +66,17 @@ impl Options {
|
||||
let captcha_config = CaptchaConfig::extract_or_default(figment)
|
||||
.map_err(anyhow::Error::from_boxed)?;
|
||||
|
||||
let clock = SystemClock::default();
|
||||
// XXX: we should disallow SeedableRng::from_entropy
|
||||
let mut rng = rand_chacha::ChaChaRng::from_entropy();
|
||||
let now = if stabilise {
|
||||
DateTime::from_timestamp_secs(0).unwrap()
|
||||
} else {
|
||||
SystemClock::default().now()
|
||||
};
|
||||
let rng = if stabilise {
|
||||
rand_chacha::ChaChaRng::from_seed([42; 32])
|
||||
} else {
|
||||
// XXX: we should disallow SeedableRng::from_entropy
|
||||
rand_chacha::ChaChaRng::from_entropy()
|
||||
};
|
||||
let url_builder =
|
||||
mas_router::UrlBuilder::new("https://example.com/".parse()?, None, None);
|
||||
let site_config = site_config_from_config(
|
||||
@@ -79,7 +94,7 @@ impl Options {
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
let all_renders = templates.check_render(clock.now(), &mut rng)?;
|
||||
let all_renders = templates.check_render(now, &rng)?;
|
||||
|
||||
if let Some(out_dir) = out_dir {
|
||||
// Save renders to disk.
|
||||
|
||||
@@ -106,9 +106,9 @@ pub trait TemplateContext: Serialize {
|
||||
///
|
||||
/// This is then used to check for template validity in unit tests and in
|
||||
/// the CLI (`cargo run -- templates check`)
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -144,9 +144,9 @@ pub(crate) fn sample_list<T: TemplateContext>(samples: Vec<T>) -> BTreeMap<Sampl
|
||||
}
|
||||
|
||||
impl TemplateContext for () {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -181,9 +181,9 @@ impl<T> std::ops::Deref for WithLanguage<T> {
|
||||
}
|
||||
|
||||
impl<T: TemplateContext> TemplateContext for WithLanguage<T> {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -192,7 +192,9 @@ impl<T: TemplateContext> TemplateContext for WithLanguage<T> {
|
||||
locales
|
||||
.iter()
|
||||
.flat_map(|locale| {
|
||||
T::sample(now, rng, locales)
|
||||
// Make samples deterministic between locales
|
||||
let mut rng = rng.clone();
|
||||
T::sample(now, &mut rng, locales)
|
||||
.into_iter()
|
||||
.map(|(sample_id, sample)| {
|
||||
(
|
||||
@@ -218,9 +220,9 @@ pub struct WithCsrf<T> {
|
||||
}
|
||||
|
||||
impl<T: TemplateContext> TemplateContext for WithCsrf<T> {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -251,9 +253,9 @@ pub struct WithSession<T> {
|
||||
}
|
||||
|
||||
impl<T: TemplateContext> TemplateContext for WithSession<T> {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -289,9 +291,9 @@ pub struct WithOptionalSession<T> {
|
||||
}
|
||||
|
||||
impl<T: TemplateContext> TemplateContext for WithOptionalSession<T> {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -340,9 +342,9 @@ impl Serialize for EmptyContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for EmptyContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -368,9 +370,9 @@ impl IndexContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for IndexContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -414,9 +416,9 @@ impl AppContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for AppContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -447,9 +449,9 @@ impl ApiDocContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for ApiDocContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -539,9 +541,9 @@ pub struct LoginContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for LoginContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -647,9 +649,9 @@ pub struct RegisterContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for RegisterContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -690,9 +692,9 @@ pub struct PasswordRegisterContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for PasswordRegisterContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -732,9 +734,9 @@ pub struct ConsentContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for ConsentContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -790,9 +792,9 @@ pub struct PolicyViolationContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for PolicyViolationContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -865,9 +867,9 @@ pub struct CompatSsoContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for CompatSsoContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -927,9 +929,9 @@ impl EmailRecoveryContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for EmailRecoveryContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -992,9 +994,9 @@ impl EmailVerificationContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for EmailVerificationContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1067,9 +1069,9 @@ impl RegisterStepsVerifyEmailContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for RegisterStepsVerifyEmailContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1107,9 +1109,9 @@ impl RegisterStepsEmailInUseContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for RegisterStepsEmailInUseContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1162,9 +1164,9 @@ impl RegisterStepsDisplayNameContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for RegisterStepsDisplayNameContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<chrono::Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1217,9 +1219,9 @@ impl RegisterStepsRegistrationTokenContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for RegisterStepsRegistrationTokenContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<chrono::Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1268,9 +1270,9 @@ impl RecoveryStartContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for RecoveryStartContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1310,9 +1312,9 @@ impl RecoveryProgressContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for RecoveryProgressContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1356,9 +1358,9 @@ impl RecoveryExpiredContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for RecoveryExpiredContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1420,9 +1422,9 @@ impl RecoveryFinishContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for RecoveryFinishContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1469,9 +1471,9 @@ impl UpstreamExistingLinkContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for UpstreamExistingLinkContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1507,9 +1509,9 @@ impl UpstreamSuggestLink {
|
||||
}
|
||||
|
||||
impl TemplateContext for UpstreamSuggestLink {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1636,9 +1638,9 @@ impl UpstreamRegister {
|
||||
}
|
||||
|
||||
impl TemplateContext for UpstreamRegister {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1722,9 +1724,9 @@ impl DeviceLinkContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for DeviceLinkContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1756,9 +1758,9 @@ impl DeviceConsentContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for DeviceConsentContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1801,9 +1803,9 @@ impl AccountInactiveContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for AccountInactiveContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1837,9 +1839,9 @@ impl DeviceNameContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for DeviceNameContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1863,9 +1865,9 @@ pub struct FormPostContext<T> {
|
||||
}
|
||||
|
||||
impl<T: TemplateContext> TemplateContext for FormPostContext<T> {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut R,
|
||||
locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -1945,9 +1947,9 @@ impl std::fmt::Display for ErrorContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for ErrorContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: chrono::DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
@@ -2039,9 +2041,9 @@ impl NotFoundContext {
|
||||
}
|
||||
|
||||
impl TemplateContext for NotFoundContext {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
_now: DateTime<Utc>,
|
||||
_rng: &mut impl Rng,
|
||||
_rng: &mut R,
|
||||
_locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
|
||||
@@ -11,6 +11,7 @@ use minijinja::{
|
||||
Value,
|
||||
value::{Enumerator, Object},
|
||||
};
|
||||
use rand::Rng;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{TemplateContext, context::SampleIdentifier};
|
||||
@@ -58,9 +59,9 @@ impl<T> WithCaptcha<T> {
|
||||
}
|
||||
|
||||
impl<T: TemplateContext> TemplateContext for WithCaptcha<T> {
|
||||
fn sample(
|
||||
fn sample<R: Rng + Clone>(
|
||||
now: chrono::DateTime<chrono::prelude::Utc>,
|
||||
rng: &mut impl rand::prelude::Rng,
|
||||
rng: &mut R,
|
||||
locales: &[DataLocale],
|
||||
) -> BTreeMap<SampleIdentifier, Self>
|
||||
where
|
||||
|
||||
@@ -471,10 +471,10 @@ impl Templates {
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if any of the templates fails to render
|
||||
pub fn check_render(
|
||||
pub fn check_render<R: Rng + Clone>(
|
||||
&self,
|
||||
now: chrono::DateTime<chrono::Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &R,
|
||||
) -> anyhow::Result<BTreeMap<(&'static str, SampleIdentifier), String>> {
|
||||
check::all(self, now, rng)
|
||||
}
|
||||
@@ -489,7 +489,7 @@ mod tests {
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let now = chrono::Utc::now();
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let mut rng = rand::thread_rng();
|
||||
let rng = rand::thread_rng();
|
||||
|
||||
let path = Utf8Path::new(env!("CARGO_MANIFEST_DIR")).join("../../templates/");
|
||||
let url_builder = UrlBuilder::new("https://example.com/".parse().unwrap(), None, None);
|
||||
@@ -517,6 +517,6 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
templates.check_render(now, &mut rng).unwrap();
|
||||
templates.check_render(now, &rng).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,15 +78,18 @@ macro_rules! register_templates {
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if any template fails to render with any of the sample.
|
||||
pub(crate) fn all(templates: &Templates, now: chrono::DateTime<chrono::Utc>, rng: &mut impl rand::Rng) -> anyhow::Result<::std::collections::BTreeMap<(&'static str, SampleIdentifier), String>> {
|
||||
pub(crate) fn all<R: Rng + Clone>(templates: &Templates, now: chrono::DateTime<chrono::Utc>, rng: &R) -> anyhow::Result<::std::collections::BTreeMap<(&'static str, SampleIdentifier), String>> {
|
||||
let mut out = ::std::collections::BTreeMap::new();
|
||||
// TODO shouldn't the Rng be independent for each render?
|
||||
$(
|
||||
out.extend(
|
||||
$name $(::< $( $generic_default ),* >)? (templates, now, rng)?
|
||||
.into_iter()
|
||||
.map(|(sample_identifier, rendered)| (($template, sample_identifier), rendered))
|
||||
);
|
||||
{
|
||||
let mut rng = rng.clone();
|
||||
out.extend(
|
||||
$name $(::< _ $( , $generic_default ),* >)? (templates, now, &mut rng)?
|
||||
.into_iter()
|
||||
.map(|(sample_identifier, rendered)| (($template, sample_identifier), rendered))
|
||||
);
|
||||
}
|
||||
)*
|
||||
|
||||
Ok(out)
|
||||
@@ -101,8 +104,8 @@ macro_rules! register_templates {
|
||||
///
|
||||
/// Returns an error if the template fails to render with any of the sample.
|
||||
pub(crate) fn $name
|
||||
$(< $( $lt $( : $clt $(+ $dlt )* + TemplateContext )? ),+ >)?
|
||||
(templates: &Templates, now: chrono::DateTime<chrono::Utc>, rng: &mut impl rand::Rng)
|
||||
< __R: Rng + Clone $( , $( $lt $( : $clt $(+ $dlt )* + TemplateContext )? ),+ )? >
|
||||
(templates: &Templates, now: chrono::DateTime<chrono::Utc>, rng: &mut __R)
|
||||
-> anyhow::Result<BTreeMap<SampleIdentifier, String>> {
|
||||
let locales = templates.translator().available_locales();
|
||||
let samples: BTreeMap<SampleIdentifier, $param > = TemplateContext::sample(now, rng, &locales);
|
||||
|
||||
Reference in New Issue
Block a user