mp3cut 0.1.0

mp3 file splitter
Documentation
use chrono::{NaiveTime, Timelike};
use lazy_static::lazy_static;
use regex::Regex;

pub struct Chapter<'a> {
    pub title: &'a str,
    pub timestamp: NaiveTime,
}

impl<'a> Chapter<'a> {
    /// Returns the timestamp as seconds
    pub fn as_secs(&self) -> u32 {
        self.timestamp.hour() * 60 + self.timestamp.minute() * 60 + self.timestamp.second()
    }

    /// Returns a vec of chapters
    /// input must be like:
    /// 0:00 Song 1
    /// 3:14 Song 2
    /// 12:03 Song 3
    pub fn from(input: &'a str) -> Option<Vec<Self>> {
        lazy_static! {
            // debug: https://regex101.com/r/MZ7QYa/1
            static ref REGEX: Regex = Regex::new(r"(\d{1,2}):(\d{2}) ?-? ?(\w.+)").unwrap();
        }

        let mut out = Vec::new();

        for capture in REGEX.captures_iter(input) {
            out.push(Chapter {
                timestamp: NaiveTime::from_hms(
                    0,
                    capture.get(1).unwrap().as_str().parse().unwrap(),
                    capture.get(2).unwrap().as_str().parse().unwrap(),
                ),
                title: capture.get(3).unwrap().as_str(),
            });
        }

        return if out.len() == 0 { None } else { Some(out) };
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn find_nothing() {
        assert!(Chapter::from("").is_none());
    }

    #[test]
    fn find_exactly_one() {
        let result = Chapter::from("0:00 - to the gateway").expect("No results");
        assert_eq!(result.len(), 1);
        assert_eq!(
            result.first().unwrap().timestamp,
            NaiveTime::from_hms(0, 0, 0),
        );
        assert_eq!(result.first().unwrap().title, "to the gateway");
    }

    #[test]
    fn find_exactly_two() {
        let result = Chapter::from(
            r#"
            0:00 - to the gateway
            3:32 - star festival
        "#,
        )
        .expect("No results");

        assert_eq!(
            result.get(1).unwrap().timestamp,
            NaiveTime::from_hms(0, 3, 32),
        );

        assert_eq!(result.len(), 2);
    }

    #[test]
    fn ignore_blank_lines() {
        let result = Chapter::from(
            r#"
            
            0:00 - to the gateway
            
            3:32 - star festival
            
        "#,
        )
        .expect("No results");

        assert_eq!(result.len(), 2);
    }
}