rm_lines/
tool.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 tool: {value}")]
8pub struct ToolError {
9    value: u32,
10}
11
12/// Data representation of a drawing tool in a reMarkable document line
13#[derive(Debug, PartialEq)]
14pub enum Tool {
15    Brush,
16    Pencil,
17    BallPoint,
18    Marker,
19    FineLiner,
20    Highlighter,
21    Eraser,
22    MechanicalPencil,
23    EraseArea,
24    EraseAll,
25    SelectionBrush,
26    Calligraphy,
27}
28
29impl TryFrom<u32> for Tool {
30    /// Used to represent a [u32] that does not map to a known `Tool`
31    type Error = ToolError;
32
33    /// Attempts to map a [u32] value to a known and supported `Tool`
34    fn try_from(value: u32) -> Result<Self, Self::Error> {
35        match value {
36            0x00 | 0x0c => Ok(Tool::Brush),
37            0x01 | 0x0e => Ok(Tool::Pencil),
38            0x02 | 0x0f => Ok(Tool::BallPoint),
39            0x03 | 0x10 => Ok(Tool::Marker),
40            0x04 | 0x11 => Ok(Tool::FineLiner),
41            0x05 | 0x12 => Ok(Tool::Highlighter),
42            0x06 => Ok(Tool::Eraser),
43            0x07 | 0x0d => Ok(Tool::MechanicalPencil),
44            0x08 => Ok(Tool::EraseArea),
45            0x09 => Ok(Tool::EraseAll),
46            0x0a | 0x0b => Ok(Tool::SelectionBrush),
47            0x15 => Ok(Tool::Calligraphy),
48            _ => Err(ToolError { value }),
49        }
50    }
51}
52
53impl<'i> Parse<'i> for Tool {
54    /// Attempts to parse a `Tool` from a byte sequence
55    ///
56    /// A tool is represented by a value-constrained, little-endian, 32-bit integer.
57    fn parse(input: &'i [u8]) -> nom::IResult<&'i [u8], Self> {
58        map_res(le_u32, Tool::try_from)(input)
59    }
60}