feat: voice note config fields

This commit is contained in:
Lewis Wynne 2026-04-10 02:12:57 +01:00
parent c05cbf4cbc
commit ca9eaf0662
3 changed files with 38 additions and 0 deletions

View file

@ -25,6 +25,9 @@ pub struct Config {
pub label_drawing: String,
pub canvas_width: u32,
pub canvas_height: u32,
pub enable_voice_notes: bool,
pub label_voice_note: String,
pub voice_note_max_duration: u32,
pub template: Option<String>,
pub success_template: Option<String>,
pub separator: String,
@ -49,6 +52,12 @@ impl Config {
self.canvas_width as usize * self.canvas_height as usize * 4
}
/// Maximum voice note file size: duration * 10KB.
/// Generous cap — real WebM/Opus clips are much smaller.
pub fn max_voice_note_bytes(&self) -> usize {
self.voice_note_max_duration as usize * 10 * 1024
}
pub fn from_env() -> Result<Self, String> {
Ok(Config {
port: env::var("BOOK_PORT")
@ -115,6 +124,15 @@ impl Config {
.unwrap_or_else(|_| "200".into())
.parse()
.map_err(|_| "BOOK_CANVAS_HEIGHT must be a number")?,
enable_voice_notes: env::var("BOOK_ENABLE_VOICE_NOTES")
.map(|v| v != "false")
.unwrap_or(false),
label_voice_note: env::var("BOOK_LABEL_VOICE_NOTE")
.unwrap_or_else(|_| "Voice note (optional):".into()),
voice_note_max_duration: env::var("BOOK_VOICE_NOTE_MAX_DURATION")
.unwrap_or_else(|_| "20".into())
.parse()
.map_err(|_| "BOOK_VOICE_NOTE_MAX_DURATION must be a number")?,
separator: env::var("BOOK_SEPARATOR")
.unwrap_or_else(|_| "------------------------------------------------------------".into()),
template: env::var("BOOK_TEMPLATE").ok().map(|path| {
@ -286,6 +304,20 @@ mod tests {
assert_eq!(config.label_drawing, "Draw (optional):");
}
#[test]
fn test_enable_voice_notes_default() {
let _lock = ENV_LOCK.lock().unwrap();
env::remove_var("BOOK_ENABLE_VOICE_NOTES");
env::remove_var("BOOK_TELEGRAM_BOT_TOKEN");
env::remove_var("BOOK_TELEGRAM_CHAT_ID");
let config = Config::from_env().unwrap();
assert!(!config.enable_voice_notes);
assert_eq!(config.voice_note_max_duration, 20);
assert_eq!(config.max_voice_note_bytes(), 20 * 10 * 1024);
assert_eq!(config.label_voice_note, "Voice note (optional):");
}
#[test]
fn test_success_template_default() {
let _lock = ENV_LOCK.lock().unwrap();

View file

@ -237,6 +237,9 @@ mod tests {
label_drawing: "Draw (optional):".into(),
canvas_width: 400,
canvas_height: 200,
enable_voice_notes: false,
label_voice_note: "Voice note (optional):".into(),
voice_note_max_duration: 20,
template: None,
success_template: None,
separator: "---".into(),

View file

@ -265,6 +265,9 @@ mod tests {
label_drawing: "Draw (optional):".into(),
canvas_width: 400,
canvas_height: 200,
enable_voice_notes: false,
label_voice_note: "Voice note (optional):".into(),
voice_note_max_duration: 20,
template: None,
success_template: None,
separator: "---".into(),