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
//! Renders the QR code to different outputs.
//!
//! Outputs to a string representation and svg are supported.
use crate::matrix::{Matrix, Module};

use std::num::ParseIntError;
use std::str::FromStr;
use std::u8;

/// Convert to string, with chars for the different underlying representations.
pub fn to_dbg_string(matrix: &Matrix) -> String {
    let mut res = String::with_capacity(matrix.size * matrix.size);
    res.push('\n');
    for y in 0..matrix.size {
        let mut s = String::with_capacity(matrix.size + 1);
        for x in 0..matrix.size {
            let c = match matrix.get(x, y) {
                Module::Unknown => '?',
                Module::Reserved => '*',
                Module::Function(true) => '#',
                Module::Function(false) => '.',
                Module::Data(true) => 'X',
                Module::Data(false) => '-',
            };
            s.push(c);
        }
        s.push('\n');
        res.push_str(&s);
    }
    res
}

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
/// An RGB color implementation.
pub struct Color {
    pub r: u8,
    pub g: u8,
    pub b: u8,
}

impl Color {
    /// Create a new from rgb parts.
    pub fn new(r: u8, g: u8, b: u8) -> Self {
        Self { r, g, b }
    }

    /// Create a new color from a hex input.
    /// ```
    /// # use qrcode53bytes::*;
    /// let c = Color::hex(0xff3214);
    /// ```
    pub fn hex(v: u32) -> Self {
        Self {
            r: (v >> 16) as u8,
            g: (v >> 8) as u8,
            b: v as u8,
        }
    }

    /// Create a new color from a length 4 input hex.
    /// ```
    /// # use qrcode53bytes::*;
    /// // Short for "#770000"
    /// let c = Color::from_4_hex("#700");
    /// ```
    pub fn from_4_hex(s: &str) -> Result<Self, ParseColorError> {
        let chars: Vec<char> = s.chars().collect();
        if chars[0] != '#' {
            return Err(ParseColorError);
        }
        let r = u8::from_str_radix(&chars[1].to_string(), 16)?;
        let g = u8::from_str_radix(&chars[2].to_string(), 16)?;
        let b = u8::from_str_radix(&chars[3].to_string(), 16)?;
        Ok(Color {
            r: (r << 4) | r,
            g: (g << 4) | g,
            b: (b << 4) | b,
        })
    }

    /// Create a new color from a length 7 input hex.
    /// ```
    /// # use qrcode53bytes::*;
    /// let c = Color::from_7_hex("#3477ff");
    /// ```
    pub fn from_7_hex(s: &str) -> Result<Self, ParseColorError> {
        if s[0..1] != *"#" {
            return Err(ParseColorError);
        }
        let r = u8::from_str_radix(&s[1..3], 16)?;
        let g = u8::from_str_radix(&s[3..5], 16)?;
        let b = u8::from_str_radix(&s[5..7], 16)?;
        Ok(Color { r, g, b })
    }

    /// Convert to a hex string.
    /// ```
    /// # use qrcode53bytes::*;
    /// assert_eq!(Color::hex(0xff7312).to_hex_str(), "#ff7312");
    /// ```
    pub fn to_hex_str(&self) -> String {
        String::from(format!("#{:02x}{:02x}{:02x}", self.r, self.g, self.b))
    }
}

#[derive(Debug, Copy, Clone)]
/// An error from trying to parse a Color instance from string.
pub struct ParseColorError;

impl FromStr for Color {
    type Err = ParseColorError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.len() {
            4 => Color::from_4_hex(s),
            7 => Color::from_7_hex(s),
            _ => Err(ParseColorError),
        }
    }
}

impl From<ParseIntError> for ParseColorError {
    fn from(_: ParseIntError) -> Self {
        ParseColorError
    }
}