1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/// A number of constants to give a name to all characters in this block.
mod constants {
    /// \u{2440}: '⑀'
    pub const OCR_HOOK: char = '⑀';
    /// \u{2441}: '⑁'
    pub const OCR_CHAIR: char = '⑁';
    /// \u{2442}: '⑂'
    pub const OCR_FORK: char = '⑂';
    /// \u{2443}: '⑃'
    pub const OCR_INVERTED_FORK: char = '⑃';
    /// \u{2444}: '⑄'
    pub const OCR_BELT_BUCKLE: char = '⑄';
    /// \u{2445}: '⑅'
    pub const OCR_BOW_TIE: char = '⑅';
    /// \u{2446}: '⑆'
    pub const OCR_BRANCH_BANK_IDENTIFICATION: char = '⑆';
    /// \u{2447}: '⑇'
    pub const OCR_AMOUNT_OF_CHECK: char = '⑇';
    /// \u{2448}: '⑈'
    pub const OCR_DASH: char = '⑈';
    /// \u{2449}: '⑉'
    pub const OCR_CUSTOMER_ACCOUNT_NUMBER: char = '⑉';
    /// \u{244a}: '⑊'
    pub const OCR_DOUBLE_BACKSLASH: char = '⑊';
}

/// An enum to represent all characters in the OpticalCharacterRecognition block.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum OpticalCharacterRecognition {
    /// \u{2440}: '⑀'
    OcrHook,
    /// \u{2441}: '⑁'
    OcrChair,
    /// \u{2442}: '⑂'
    OcrFork,
    /// \u{2443}: '⑃'
    OcrInvertedFork,
    /// \u{2444}: '⑄'
    OcrBeltBuckle,
    /// \u{2445}: '⑅'
    OcrBowTie,
    /// \u{2446}: '⑆'
    OcrBranchBankIdentification,
    /// \u{2447}: '⑇'
    OcrAmountOfCheck,
    /// \u{2448}: '⑈'
    OcrDash,
    /// \u{2449}: '⑉'
    OcrCustomerAccountNumber,
    /// \u{244a}: '⑊'
    OcrDoubleBackslash,
}

impl Into<char> for OpticalCharacterRecognition {
    fn into(self) -> char {
        use constants::*;
        match self {
            OpticalCharacterRecognition::OcrHook => OCR_HOOK,
            OpticalCharacterRecognition::OcrChair => OCR_CHAIR,
            OpticalCharacterRecognition::OcrFork => OCR_FORK,
            OpticalCharacterRecognition::OcrInvertedFork => OCR_INVERTED_FORK,
            OpticalCharacterRecognition::OcrBeltBuckle => OCR_BELT_BUCKLE,
            OpticalCharacterRecognition::OcrBowTie => OCR_BOW_TIE,
            OpticalCharacterRecognition::OcrBranchBankIdentification => OCR_BRANCH_BANK_IDENTIFICATION,
            OpticalCharacterRecognition::OcrAmountOfCheck => OCR_AMOUNT_OF_CHECK,
            OpticalCharacterRecognition::OcrDash => OCR_DASH,
            OpticalCharacterRecognition::OcrCustomerAccountNumber => OCR_CUSTOMER_ACCOUNT_NUMBER,
            OpticalCharacterRecognition::OcrDoubleBackslash => OCR_DOUBLE_BACKSLASH,
        }
    }
}

impl std::convert::TryFrom<char> for OpticalCharacterRecognition {
    type Error = ();
    fn try_from(c: char) -> Result<Self, Self::Error> {
        use constants::*;
        match c {
            OCR_HOOK => Ok(OpticalCharacterRecognition::OcrHook),
            OCR_CHAIR => Ok(OpticalCharacterRecognition::OcrChair),
            OCR_FORK => Ok(OpticalCharacterRecognition::OcrFork),
            OCR_INVERTED_FORK => Ok(OpticalCharacterRecognition::OcrInvertedFork),
            OCR_BELT_BUCKLE => Ok(OpticalCharacterRecognition::OcrBeltBuckle),
            OCR_BOW_TIE => Ok(OpticalCharacterRecognition::OcrBowTie),
            OCR_BRANCH_BANK_IDENTIFICATION => Ok(OpticalCharacterRecognition::OcrBranchBankIdentification),
            OCR_AMOUNT_OF_CHECK => Ok(OpticalCharacterRecognition::OcrAmountOfCheck),
            OCR_DASH => Ok(OpticalCharacterRecognition::OcrDash),
            OCR_CUSTOMER_ACCOUNT_NUMBER => Ok(OpticalCharacterRecognition::OcrCustomerAccountNumber),
            OCR_DOUBLE_BACKSLASH => Ok(OpticalCharacterRecognition::OcrDoubleBackslash),
            _ => Err(()),
        }
    }
}

impl Into<u32> for OpticalCharacterRecognition {
    fn into(self) -> u32 {
        let c: char = self.into();
        let hex = c
            .escape_unicode()
            .to_string()
            .replace("\\u{", "")
            .replace("}", "");
        u32::from_str_radix(&hex, 16).unwrap()
    }
}

impl std::convert::TryFrom<u32> for OpticalCharacterRecognition {
    type Error = ();
    fn try_from(u: u32) -> Result<Self, Self::Error> {
        if let Ok(c) = char::try_from(u) {
            Self::try_from(c)
        } else {
            Err(())
        }
    }
}

impl Iterator for OpticalCharacterRecognition {
    type Item = Self;
    fn next(&mut self) -> Option<Self> {
        let index: u32 = (*self).into();
        use std::convert::TryFrom;
        Self::try_from(index + 1).ok()
    }
}

impl OpticalCharacterRecognition {
    /// The character with the lowest index in this unicode block
    pub fn new() -> Self {
        OpticalCharacterRecognition::OcrHook
    }

    /// The character's name, all lowercase and space-separated
    pub fn name(&self) -> &str {
        match self {
            OpticalCharacterRecognition::OcrHook => "ocr hook",
            OpticalCharacterRecognition::OcrChair => "ocr chair",
            OpticalCharacterRecognition::OcrFork => "ocr fork",
            OpticalCharacterRecognition::OcrInvertedFork => "ocr inverted fork",
            OpticalCharacterRecognition::OcrBeltBuckle => "ocr belt buckle",
            OpticalCharacterRecognition::OcrBowTie => "ocr bow tie",
            OpticalCharacterRecognition::OcrBranchBankIdentification => "ocr branch bank identification",
            OpticalCharacterRecognition::OcrAmountOfCheck => "ocr amount of check",
            OpticalCharacterRecognition::OcrDash => "ocr dash",
            OpticalCharacterRecognition::OcrCustomerAccountNumber => "ocr customer account number",
            OpticalCharacterRecognition::OcrDoubleBackslash => "ocr double backslash",
        }
    }
}