~ruther/simple-clock

d9c5680c8b4c53374089a228d6f41d9b86b96665 — František Boháček 1 year, 8 months ago 617aab4
feat(src): add app state with calendar
2 files changed, 128 insertions(+), 0 deletions(-)

A src/calendar.rs
A src/clock_state.rs
A src/calendar.rs => src/calendar.rs +102 -0
@@ 0,0 1,102 @@
pub struct Calendar {
    hours: u8,
    minutes: u8,
    seconds: u8,
    day: u8,
    month: u8,
    year: u16,
}

impl Calendar {
    pub fn new(hours: u8, minutes: u8, seconds: u8, day: u8, month: u8, year: u16) -> Self {
        Self {
            hours,
            minutes,
            seconds,
            day,
            month,
            year,
        }
    }

    pub fn from_seconds(base: Calendar, seconds: u32) -> Self {
        let total_seconds = seconds + base.seconds as u32;
        let seconds = total_seconds % 60;

        let total_minutes = total_seconds / 60 + base.minutes as u32;
        let minutes = total_minutes % 60;

        let total_hours = total_minutes / 60 + base.hours as u32;
        let hours = total_hours % 24;

        let total_days = total_hours / 24 + base.day as u32;
        let day = total_days % 30; // TODO...
                                   // the current month and year has to be known prior to the calculation of the day

        Self {
            seconds: seconds as u8,
            minutes: minutes as u8,
            hours: hours as u8,
            day: day as u8,
            month: base.month,
            year: base.year,
        }
    }

    pub fn hours(&self) -> u8 {
        self.hours
    }

    pub fn minutes(&self) -> u8 {
        self.minutes
    }

    pub fn seconds(&self) -> u8 {
        self.seconds
    }

    pub fn day(&self) -> u8 {
        self.day
    }

    pub fn month(&self) -> u8 {
        self.month
    }

    pub fn year(&self) -> u16 {
        self.year
    }

    pub fn second_elapsed(&mut self) {
        self.seconds = (self.seconds + 1) % 60;
        let minute_elapsed = self.seconds == 0;
        self.minutes = (self.minutes + if minute_elapsed { 1 } else { 0 }) % 60;

        let hour_elapsed = minute_elapsed && self.minutes == 0;
        self.hours = (self.hours + if hour_elapsed { 1 } else { 0 }) % 24;

        let day_elapsed = hour_elapsed && self.hours == 0;
        let day = self.day - 1 + if day_elapsed { 1 } else { 0 };
        let days_in_month = Self::days_in_month(self.month, Self::is_leap_year(self.year));
        self.day = day % days_in_month + 1;

        let month_elapsed = day_elapsed && self.day == 1;
        self.month = (self.month - 1 + if month_elapsed { 1 } else { 0 }) % 12 + 1;
        let year_elapsed = month_elapsed && self.month == 1;
        self.year += if year_elapsed { 1 } else { 0 };
    }

    fn is_leap_year(year: u16) -> bool {
        matches!(year % 4, 0 if year % 100 != 0 || year % 400 == 0)
    }

    fn days_in_month(month: u8, leap_year: bool) -> u8 {
        match month {
            2 if leap_year => 29,
            2 => 28,
            1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
            4 | 6 | 9 | 11 => 31,
            _ => panic!(),
        }
    }
}

A src/clock_state.rs => src/clock_state.rs +26 -0
@@ 0,0 1,26 @@
use stm32f1xx_hal::time::MonoTimer;

use crate::calendar::Calendar;

pub struct ClockState {
    calendar: Calendar,
    timer: MonoTimer,
}

impl ClockState {
    pub fn new(calendar: Calendar, timer: MonoTimer) -> Self {
        Self { calendar, timer }
    }

    pub fn timer(&self) -> MonoTimer {
        self.timer
    }

    pub fn calendar(&self) -> &Calendar {
        &self.calendar
    }

    pub fn second_elapsed(&mut self) {
        self.calendar.second_elapsed()
    }
}

Do not follow this link