klavier-core 0.1.15

Core library of klavier.
Documentation
use std::fmt;


#[derive(Debug, Clone, PartialEq, Eq)]
pub enum GridError {
    ParseError(String),
}

#[derive(serde::Deserialize, serde::Serialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Grid {
    value: u32,
}

impl Grid {
    pub fn value_of(s: &str) -> Result<Self, GridError> {
        s.parse::<u32>()
            .map_err(|_| {
                GridError::ParseError(s.to_owned())
            })
            .and_then(|i| {
                Self::from_u32(i)
            })
    }

    #[inline]
    pub fn from_u32(i: u32) -> Result<Self, GridError> {
        if i == 0 {
            Err(GridError::ParseError("0".to_owned()))
        } else {
            Ok(Self { value: i })
        }
    }

    #[inline]
    pub fn as_u32(self) -> u32 {
        self.value
    }

    #[inline]
    pub fn snap(self, tick: i64) -> i64 {
        let i = self.value as i64;
        if tick < 0 {
            i * ((tick - i / 2) / i)
        } else {
            i * ((tick + i / 2) / i)
        }
    }
}

impl Default for Grid {
    fn default() -> Self {
        Self { value: 60 }
    }
}

impl fmt::Display for Grid {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.value)
    }
}

#[cfg(test)]
mod tests {
    use crate::grid::{Grid, GridError};

    #[test]
    fn empty_str() {
        assert_eq!(Grid::value_of(""), Err(GridError::ParseError("".to_owned())));
    }


    #[test]
    fn non_numerical_str() {
        assert_eq!(Grid::value_of("1a"), Err(GridError::ParseError("1a".to_owned())));
    }

    #[test]
    fn zero() {
        assert_eq!(Grid::value_of("0"), Err(GridError::ParseError("0".to_owned())));
    }

    #[test]
    fn ok() {
        assert_eq!(Grid::value_of("120"), Ok(Grid { value: 120 }));
    }

    #[test]
    fn snap() {
        assert_eq!(Grid::from_u32(100).unwrap().snap(49), 0);
        assert_eq!(Grid::from_u32(100).unwrap().snap(50), 100);
        assert_eq!(Grid::from_u32(100).unwrap().snap(99), 100);
        assert_eq!(Grid::from_u32(100).unwrap().snap(149), 100);
        assert_eq!(Grid::from_u32(100).unwrap().snap(150), 200);
        assert_eq!(Grid::from_u32(100).unwrap().snap(199), 200);
        assert_eq!(Grid::from_u32(100).unwrap().snap(249), 200);
 
        assert_eq!(Grid::from_u32(100).unwrap().snap(-49), 0);
        assert_eq!(Grid::from_u32(100).unwrap().snap(-50), -100);
    }
}