rm_lines/
color.rs

1use crate::Parse;
2
3use nom::{combinator::map_res, number::complete::le_u32};
4use thiserror::Error;
5
6#[derive(Debug, Error, PartialEq)]
7#[error("Invalid color specified: {value}")]
8pub struct ColorError {
9    value: u32,
10}
11
12/// Data representation of an exported color in a reMarkable document line
13#[derive(Debug, PartialEq)]
14pub enum Color {
15    Black,
16    Grey,
17    White,
18    Blue,
19    Red,
20}
21
22impl TryFrom<u32> for Color {
23    /// Used to represent a [u32] which does not map to a known `Color`
24    type Error = ColorError;
25
26    /// Attempts to map a [u32] value to a known and supported `Color`
27    fn try_from(value: u32) -> Result<Self, Self::Error> {
28        match value {
29            0x00 => Ok(Color::Black),
30            0x01 => Ok(Color::Grey),
31            0x02 => Ok(Color::White),
32            0x06 => Ok(Color::Red),
33            0x07 => Ok(Color::Blue),
34            _ => Err(ColorError { value }),
35        }
36    }
37}
38
39impl<'i> Parse<'i> for Color {
40    /// Attempts to parse a `Color` from a byte sequence
41    ///
42    /// A color is represented by a value-constrained,
43    /// little-endian, 32-bit integer.
44    fn parse(input: &'i [u8]) -> nom::IResult<&'i [u8], Self> {
45        map_res(le_u32, Color::try_from)(input)
46    }
47}