ph-haptics 0.1.0

Host-compiled haptics DSL and no-std, no-alloc scheduling runtime modeling ERM and LRA motors using ph-curves
Documentation
use crate::motor::MotorKind;
use core::fmt;

/// Compiled-runner construction errors.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Error {
    /// Program has no instructions.
    EmptyProgram,
    /// Program motor type and runtime motor config do not match.
    MotorKindMismatch {
        /// Motor type declared by the program.
        expected: MotorKind,
        /// Motor type provided to the runner.
        got: MotorKind,
    },
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::EmptyProgram => f.write_str("program has no instructions"),
            Self::MotorKindMismatch { expected, got } => {
                write!(
                    f,
                    "motor kind mismatch: program is {expected}, runner is {got}"
                )
            }
        }
    }
}

impl core::error::Error for Error {}

impl fmt::Display for MotorKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(match self {
            Self::Erm => "ERM",
            Self::Lra => "LRA",
        })
    }
}

#[cfg(test)]
// This crate is no_alloc and has no `extern crate alloc`, so the lint's advice
// to import from `alloc` does not apply. Tests pull in `std` deliberately.
#[allow(clippy::std_instead_of_alloc)]
mod tests {
    use super::*;
    use std::string::ToString;

    #[test]
    fn errors_render_readable_messages() {
        assert_eq!(
            Error::EmptyProgram.to_string(),
            "program has no instructions"
        );
        assert_eq!(
            Error::MotorKindMismatch {
                expected: MotorKind::Erm,
                got: MotorKind::Lra,
            }
            .to_string(),
            "motor kind mismatch: program is ERM, runner is LRA"
        );
    }
}