envelope_cli/setup/steps/
period.rs

1//! Budget period setup step
2//!
3//! Allows users to select their preferred budget period type.
4
5use std::io::{self, Write};
6
7use crate::config::settings::BudgetPeriodType;
8use crate::error::EnvelopeResult;
9
10/// Period setup step result
11pub struct PeriodSetupResult {
12    /// The user's preferred period type
13    pub period_type: BudgetPeriodType,
14}
15
16/// Period setup step
17pub struct PeriodSetupStep;
18
19impl PeriodSetupStep {
20    /// Run the period setup step
21    pub fn run() -> EnvelopeResult<PeriodSetupResult> {
22        println!();
23        println!("Step 3: Budget Period");
24        println!("=====================");
25        println!();
26        println!("How often would you like to budget?");
27        println!();
28        println!("  1. Monthly (recommended) - Budget once per month");
29        println!("  2. Weekly - Budget every week");
30        println!("  3. Bi-weekly - Budget every two weeks");
31        println!();
32
33        let choice_str = prompt_string("Select budget period [1]: ")?;
34        let period_type = match choice_str.trim() {
35            "" | "1" => BudgetPeriodType::Monthly,
36            "2" => BudgetPeriodType::Weekly,
37            "3" => BudgetPeriodType::BiWeekly,
38            _ => BudgetPeriodType::Monthly,
39        };
40
41        println!();
42        match period_type {
43            BudgetPeriodType::Monthly => {
44                println!("You've selected monthly budgeting.");
45                println!("Your budget will reset at the beginning of each month.");
46            }
47            BudgetPeriodType::Weekly => {
48                println!("You've selected weekly budgeting.");
49                println!("Your budget will reset every week.");
50            }
51            BudgetPeriodType::BiWeekly => {
52                println!("You've selected bi-weekly budgeting.");
53                println!("Your budget will reset every two weeks.");
54            }
55        }
56
57        Ok(PeriodSetupResult { period_type })
58    }
59}
60
61/// Prompt for a string input
62fn prompt_string(prompt: &str) -> EnvelopeResult<String> {
63    print!("{}", prompt);
64    io::stdout().flush()?;
65
66    let mut input = String::new();
67    io::stdin().read_line(&mut input)?;
68
69    Ok(input.trim().to_string())
70}