use rand::distr::{Alphanumeric, SampleString};
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct RandomURLConfig {
#[deprecated(note = "disable by commenting out [paste].random_url")]
pub enabled: Option<bool>,
pub words: Option<u8>,
pub separator: Option<String>,
pub length: Option<usize>,
#[serde(rename = "type")]
pub type_: RandomURLType,
pub suffix_mode: Option<bool>,
pub no_extension: Option<bool>,
}
#[allow(deprecated)]
impl RandomURLConfig {
pub fn generate(&self) -> Option<String> {
if !self.enabled.unwrap_or(true) {
return None;
}
Some(match self.type_ {
RandomURLType::PetName => {
let mut buf = String::new();
petname::Petnames::large()
.namer(
self.words.unwrap_or(2),
self.separator.as_deref().unwrap_or("-"),
)
.generate_into(&mut buf, &mut rand::rng());
buf
}
RandomURLType::Alphanumeric => {
Alphanumeric.sample_string(&mut rand::rng(), self.length.unwrap_or(8))
}
})
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
#[derive(Default)]
pub enum RandomURLType {
#[default]
PetName,
Alphanumeric,
}
#[cfg(test)]
mod tests {
use super::*;
#[allow(deprecated)]
#[test]
fn test_generate_url() {
let random_config = RandomURLConfig {
enabled: Some(true),
words: Some(3),
separator: Some(String::from("~")),
type_: RandomURLType::PetName,
..RandomURLConfig::default()
};
let random_url = random_config
.generate()
.expect("cannot generate random URL");
assert_eq!(3, random_url.split('~').count());
let random_config = RandomURLConfig {
length: Some(21),
type_: RandomURLType::Alphanumeric,
..RandomURLConfig::default()
};
let random_url = random_config
.generate()
.expect("cannot generate random URL");
assert_eq!(21, random_url.len());
let random_config = RandomURLConfig {
enabled: Some(false),
..RandomURLConfig::default()
};
assert!(random_config.generate().is_none());
}
}