use rand::prelude::IndexedRandom;
use rand::rng;
include!(concat!(env!("OUT_DIR"), "/content.rs"));
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
Text,
Code,
}
impl Mode {
pub fn all() -> &'static [Mode] {
&[Mode::Text, Mode::Code]
}
pub fn as_str(&self) -> &'static str {
match self {
Mode::Text => "text",
Mode::Code => "code",
}
}
pub fn from_str(s: &str) -> Option<Self> {
match s {
"text" => Some(Mode::Text),
"code" => Some(Mode::Code),
_ => None,
}
}
pub fn languages(&self) -> &'static [&'static str] {
match self {
Mode::Text => TEXT_LANGUAGES,
Mode::Code => CODE_LANGUAGES,
}
}
pub fn default_language(&self) -> &'static str {
match self {
Mode::Text => TEXT_LANGUAGES.first().copied().unwrap_or("english"),
Mode::Code => CODE_LANGUAGES.first().copied().unwrap_or("python"),
}
}
}
#[derive(Debug, Clone)]
pub struct ContentProvider {
mode: Mode,
language: String,
}
impl ContentProvider {
pub fn new(mode: Mode, language: impl Into<String>) -> Self {
Self {
mode,
language: language.into(),
}
}
pub fn generate_text(&self, word_count: usize) -> String {
match self.mode {
Mode::Text => self.generate_words(word_count),
Mode::Code => self.generate_code_snippet(),
}
}
fn generate_words(&self, count: usize) -> String {
let words = get_word_list(&self.language);
if words.is_empty() {
return "the quick brown fox jumps over the lazy dog".to_string();
}
let mut rng = rng();
let selected: Vec<&str> = (0..count)
.map(|_| *words.choose(&mut rng).unwrap_or(&"the"))
.collect();
selected.join(" ")
}
pub fn generate_code_snippet(&self) -> String {
let snippets = get_snippets(&self.language);
if snippets.is_empty() {
return "print('hello world')".to_string();
}
let mut rng = rng();
snippets
.choose(&mut rng)
.unwrap_or(&"print('hello world')")
.to_string()
}
pub fn available_languages(&self) -> &'static [&'static str] {
self.mode.languages()
}
pub fn validate_language(&self, lang: &str) -> bool {
self.available_languages().contains(&lang)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mode_from_str() {
assert_eq!(Mode::from_str("text"), Some(Mode::Text));
assert_eq!(Mode::from_str("code"), Some(Mode::Code));
assert_eq!(Mode::from_str("unknown"), None);
}
#[test]
fn test_content_provider_text() {
let provider = ContentProvider::new(Mode::Text, "english");
let text = provider.generate_text(10);
assert!(!text.is_empty());
let words: Vec<&str> = text.split_whitespace().collect();
assert_eq!(words.len(), 10);
}
#[test]
fn test_content_provider_code() {
let provider = ContentProvider::new(Mode::Code, "python");
let text = provider.generate_text(10);
assert!(!text.is_empty());
}
}