rustup for 1.0.
* uint -> usize * range(a, b) -> (a .. b) * #[deriving] -> #[derive] * [T, ..10] -> [T; 10] * Iterator<X> -> Iterator<Item=X>
This commit is contained in:
parent
80d8c266bb
commit
ed2e38031c
36
src/bits.rs
36
src/bits.rs
|
@ -17,7 +17,7 @@ use optimize::{Parser, Optimizer, total_encoded_len, Segment};
|
||||||
/// The `Bits` structure stores the encoded data for a QR code.
|
/// The `Bits` structure stores the encoded data for a QR code.
|
||||||
pub struct Bits {
|
pub struct Bits {
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
bit_offset: uint,
|
bit_offset: usize,
|
||||||
version: Version,
|
version: Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ impl Bits {
|
||||||
/// Note: It is up to the developer to ensure that `number` really only is
|
/// Note: It is up to the developer to ensure that `number` really only is
|
||||||
/// `n` bit in size. Otherwise the excess bits may stomp on the existing
|
/// `n` bit in size. Otherwise the excess bits may stomp on the existing
|
||||||
/// ones.
|
/// ones.
|
||||||
fn push_number(&mut self, n: uint, number: u16) {
|
fn push_number(&mut self, n: usize, number: u16) {
|
||||||
debug_assert!(n == 16 || n < 16 && number < (1 << n),
|
debug_assert!(n == 16 || n < 16 && number < (1 << n),
|
||||||
"{} is too big as a {}-bit number", number, n);
|
"{} is too big as a {}-bit number", number, n);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ impl Bits {
|
||||||
/// that the number does not overflow the bits.
|
/// that the number does not overflow the bits.
|
||||||
///
|
///
|
||||||
/// Returns `Err(QrError::DataTooLong)` on overflow.
|
/// Returns `Err(QrError::DataTooLong)` on overflow.
|
||||||
fn push_number_checked(&mut self, n: uint, number: uint) -> QrResult<()> {
|
fn push_number_checked(&mut self, n: usize, number: usize) -> QrResult<()> {
|
||||||
if n > 16 || number >= (1 << n) {
|
if n > 16 || number >= (1 << n) {
|
||||||
Err(QrError::DataTooLong)
|
Err(QrError::DataTooLong)
|
||||||
} else {
|
} else {
|
||||||
|
@ -75,7 +75,7 @@ impl Bits {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reserves `n` extra bits of space for pushing.
|
/// Reserves `n` extra bits of space for pushing.
|
||||||
fn reserve(&mut self, n: uint) {
|
fn reserve(&mut self, n: usize) {
|
||||||
let extra_bytes = (n + (8 - self.bit_offset) % 8) / 8;
|
let extra_bytes = (n + (8 - self.bit_offset) % 8) / 8;
|
||||||
self.data.reserve(extra_bytes);
|
self.data.reserve(extra_bytes);
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ impl Bits {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Total number of bits.
|
/// Total number of bits.
|
||||||
pub fn len(&self) -> uint {
|
pub fn len(&self) -> usize {
|
||||||
if self.bit_offset == 0 {
|
if self.bit_offset == 0 {
|
||||||
self.data.len() * 8
|
self.data.len() * 8
|
||||||
} else {
|
} else {
|
||||||
|
@ -130,7 +130,7 @@ fn bench_push_splitted_bytes(bencher: &mut Bencher) {
|
||||||
bencher.iter(|| {
|
bencher.iter(|| {
|
||||||
let mut bits = Bits::new(Version::Normal(40));
|
let mut bits = Bits::new(Version::Normal(40));
|
||||||
bits.push_number(4, 0b0101);
|
bits.push_number(4, 0b0101);
|
||||||
for _ in range(0u, 1024) {
|
for _ in 0 .. 1024 {
|
||||||
bits.push_number(8, 0b10101010);
|
bits.push_number(8, 0b10101010);
|
||||||
}
|
}
|
||||||
bits.into_bytes()
|
bits.into_bytes()
|
||||||
|
@ -143,7 +143,7 @@ fn bench_push_splitted_bytes(bencher: &mut Bencher) {
|
||||||
|
|
||||||
/// An "extended" mode indicator, includes all indicators supported by QR code
|
/// An "extended" mode indicator, includes all indicators supported by QR code
|
||||||
/// beyond those bearing data.
|
/// beyond those bearing data.
|
||||||
#[deriving(Copy)]
|
#[derive(Copy)]
|
||||||
pub enum ExtendedMode {
|
pub enum ExtendedMode {
|
||||||
/// ECI mode indicator, to introduce an ECI designator.
|
/// ECI mode indicator, to introduce an ECI designator.
|
||||||
Eci,
|
Eci,
|
||||||
|
@ -298,7 +298,7 @@ mod eci_tests {
|
||||||
//{{{ Mode::Numeric mode
|
//{{{ Mode::Numeric mode
|
||||||
|
|
||||||
impl Bits {
|
impl Bits {
|
||||||
fn push_header(&mut self, mode: Mode, raw_data_len: uint) -> QrResult<()> {
|
fn push_header(&mut self, mode: Mode, raw_data_len: usize) -> QrResult<()> {
|
||||||
let length_bits = mode.length_bits_count(self.version);
|
let length_bits = mode.length_bits_count(self.version);
|
||||||
self.reserve(length_bits + 4 + mode.data_bits_count(raw_data_len));
|
self.reserve(length_bits + 4 + mode.data_bits_count(raw_data_len));
|
||||||
try!(self.push_mode_indicator(ExtendedMode::Data(mode)));
|
try!(self.push_mode_indicator(ExtendedMode::Data(mode)));
|
||||||
|
@ -605,7 +605,7 @@ impl Bits {
|
||||||
//{{{ Finish
|
//{{{ Finish
|
||||||
|
|
||||||
// This table is copied from ISO/IEC 18004:2006 §6.4.10, Table 7.
|
// This table is copied from ISO/IEC 18004:2006 §6.4.10, Table 7.
|
||||||
static DATA_LENGTHS: [[uint, ..4], ..44] = [
|
static DATA_LENGTHS: [[usize; 4]; 44] = [
|
||||||
// Normal versions
|
// Normal versions
|
||||||
[152, 128, 104, 72],
|
[152, 128, 104, 72],
|
||||||
[272, 224, 176, 128],
|
[272, 224, 176, 128],
|
||||||
|
@ -660,7 +660,7 @@ impl Bits {
|
||||||
#[unstable]
|
#[unstable]
|
||||||
pub fn push_terminator(&mut self, ec_level: EcLevel) -> QrResult<()> {
|
pub fn push_terminator(&mut self, ec_level: EcLevel) -> QrResult<()> {
|
||||||
let terminator_size = match self.version {
|
let terminator_size = match self.version {
|
||||||
Version::Micro(a) => (a as uint) * 2 + 1,
|
Version::Micro(a) => (a as usize) * 2 + 1,
|
||||||
_ => 4,
|
_ => 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -754,11 +754,11 @@ mod finish_tests {
|
||||||
|
|
||||||
impl Bits {
|
impl Bits {
|
||||||
/// Push a segmented data to the bits, and then terminate it.
|
/// Push a segmented data to the bits, and then terminate it.
|
||||||
pub fn push_segments<I: Iterator<Segment>>(&mut self,
|
pub fn push_segments<I>(&mut self, data: &[u8], mut segments_iter: I) -> QrResult<()>
|
||||||
data: &[u8],
|
where I: Iterator<Item=Segment>
|
||||||
mut segments_iter: I) -> QrResult<()> {
|
{
|
||||||
for segment in segments_iter {
|
for segment in segments_iter {
|
||||||
let slice = data[segment.begin..segment.end];
|
let slice = data.slice(segment.begin, segment.end);
|
||||||
try!(match segment.mode {
|
try!(match segment.mode {
|
||||||
Mode::Numeric => self.push_numeric_data(slice),
|
Mode::Numeric => self.push_numeric_data(slice),
|
||||||
Mode::Alphanumeric => self.push_alphanumeric_data(slice),
|
Mode::Alphanumeric => self.push_alphanumeric_data(slice),
|
||||||
|
@ -842,12 +842,12 @@ pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
|
||||||
/// Finds the smallest version (QR code only) that can store N bits of data
|
/// Finds the smallest version (QR code only) that can store N bits of data
|
||||||
/// in the given error correction level.
|
/// in the given error correction level.
|
||||||
#[unstable]
|
#[unstable]
|
||||||
fn find_min_version(length: uint, ec_level: EcLevel) -> Version {
|
fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
|
||||||
let mut min = 0u;
|
let mut min = 0us;
|
||||||
let mut max = 39u;
|
let mut max = 39us;
|
||||||
while min < max {
|
while min < max {
|
||||||
let half = (min + max) / 2;
|
let half = (min + max) / 2;
|
||||||
if DATA_LENGTHS[half][ec_level as uint] < length {
|
if DATA_LENGTHS[half][ec_level as usize] < length {
|
||||||
min = half + 1;
|
min = half + 1;
|
||||||
} else {
|
} else {
|
||||||
max = half;
|
max = half;
|
||||||
|
|
111
src/canvas.rs
111
src/canvas.rs
|
@ -20,7 +20,7 @@ use types::{Version, EcLevel};
|
||||||
//{{{ Modules
|
//{{{ Modules
|
||||||
|
|
||||||
/// The color of a module (pixel) in the QR code.
|
/// The color of a module (pixel) in the QR code.
|
||||||
#[deriving(PartialEq, Eq, Clone, Copy, Show)]
|
#[derive(PartialEq, Eq, Clone, Copy, Show)]
|
||||||
pub enum Module {
|
pub enum Module {
|
||||||
/// The module is empty.
|
/// The module is empty.
|
||||||
Empty,
|
Empty,
|
||||||
|
@ -78,7 +78,7 @@ impl Module {
|
||||||
|
|
||||||
/// `Canvas` is an intermediate helper structure to render error-corrected data
|
/// `Canvas` is an intermediate helper structure to render error-corrected data
|
||||||
/// into a QR code.
|
/// into a QR code.
|
||||||
#[deriving(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Canvas {
|
pub struct Canvas {
|
||||||
/// The width and height of the canvas (cached as it is needed frequently).
|
/// The width and height of the canvas (cached as it is needed frequently).
|
||||||
width: i16,
|
width: i16,
|
||||||
|
@ -102,7 +102,7 @@ impl Canvas {
|
||||||
width: width,
|
width: width,
|
||||||
version: version,
|
version: version,
|
||||||
ec_level: ec_level,
|
ec_level: ec_level,
|
||||||
modules: repeat(Module::Empty).take((width*width) as uint).collect()
|
modules: repeat(Module::Empty).take((width*width) as usize).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,10 +110,10 @@ impl Canvas {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn to_debug_str(&self) -> String {
|
fn to_debug_str(&self) -> String {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
let mut res = String::with_capacity((width * (width + 1)) as uint);
|
let mut res = String::with_capacity((width * (width + 1)) as usize);
|
||||||
for y in range(0, width) {
|
for y in (0 .. width) {
|
||||||
res.push('\n');
|
res.push('\n');
|
||||||
for x in range(0, width) {
|
for x in (0 .. width) {
|
||||||
res.push(match self.get(x, y) {
|
res.push(match self.get(x, y) {
|
||||||
Module::Empty => '?',
|
Module::Empty => '?',
|
||||||
Module::Light => '.',
|
Module::Light => '.',
|
||||||
|
@ -126,10 +126,10 @@ impl Canvas {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coords_to_index(&self, x: i16, y: i16) -> uint {
|
fn coords_to_index(&self, x: i16, y: i16) -> usize {
|
||||||
let x = if x < 0 { x + self.width } else { x } as uint;
|
let x = if x < 0 { x + self.width } else { x } as usize;
|
||||||
let y = if y < 0 { y + self.width } else { y } as uint;
|
let y = if y < 0 { y + self.width } else { y } as usize;
|
||||||
y * (self.width as uint) + x
|
y * (self.width as usize) + x
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtains a module at the given coordinates. For convenience, negative
|
/// Obtains a module at the given coordinates. For convenience, negative
|
||||||
|
@ -142,7 +142,7 @@ impl Canvas {
|
||||||
/// negative coordinates will wrap around.
|
/// negative coordinates will wrap around.
|
||||||
pub fn get_mut(&mut self, x: i16, y: i16) -> &mut Module {
|
pub fn get_mut(&mut self, x: i16, y: i16) -> &mut Module {
|
||||||
let index = self.coords_to_index(x, y);
|
let index = self.coords_to_index(x, y);
|
||||||
self.modules.index_mut(&index)
|
&mut self.modules[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the color of a module at the given coordinates. For convenience,
|
/// Sets the color of a module at the given coordinates. For convenience,
|
||||||
|
@ -177,8 +177,8 @@ mod basic_canvas_tests {
|
||||||
fn test_debug_str() {
|
fn test_debug_str() {
|
||||||
let mut c = Canvas::new(Version::Normal(1), EcLevel::L);
|
let mut c = Canvas::new(Version::Normal(1), EcLevel::L);
|
||||||
|
|
||||||
for i in range(3i16, 20) {
|
for i in 3 .. 20 {
|
||||||
for j in range(3i16, 20) {
|
for j in 3 .. 20 {
|
||||||
c.put(i, j, match ((i * 3) ^ j) % 5 {
|
c.put(i, j, match ((i * 3) ^ j) % 5 {
|
||||||
0 => Module::Empty,
|
0 => Module::Empty,
|
||||||
1 => Module::Light,
|
1 => Module::Light,
|
||||||
|
@ -335,7 +335,7 @@ impl Canvas {
|
||||||
Version::Micro(_) | Version::Normal(1) => { return; }
|
Version::Micro(_) | Version::Normal(1) => { return; }
|
||||||
Version::Normal(2...6) => self.draw_alignment_pattern_at(-7, -7),
|
Version::Normal(2...6) => self.draw_alignment_pattern_at(-7, -7),
|
||||||
Version::Normal(a) => {
|
Version::Normal(a) => {
|
||||||
let positions = ALIGNMENT_PATTERN_POSITIONS[a as uint - 7];
|
let positions = ALIGNMENT_PATTERN_POSITIONS[a as usize - 7];
|
||||||
for x in positions.iter() {
|
for x in positions.iter() {
|
||||||
for y in positions.iter() {
|
for y in positions.iter() {
|
||||||
self.draw_alignment_pattern_at(*x, *y);
|
self.draw_alignment_pattern_at(*x, *y);
|
||||||
|
@ -475,7 +475,7 @@ mod alignment_pattern_tests {
|
||||||
/// `ALIGNMENT_PATTERN_POSITIONS` describes the x- and y-coordinates of the
|
/// `ALIGNMENT_PATTERN_POSITIONS` describes the x- and y-coordinates of the
|
||||||
/// center of the alignment patterns. Since the QR code is symmetric, only one
|
/// center of the alignment patterns. Since the QR code is symmetric, only one
|
||||||
/// coordinate is needed.
|
/// coordinate is needed.
|
||||||
static ALIGNMENT_PATTERN_POSITIONS: [&'static [i16], ..34] = [
|
static ALIGNMENT_PATTERN_POSITIONS: [&'static [i16]; 34] = [
|
||||||
&[6, 22, 38],
|
&[6, 22, 38],
|
||||||
&[6, 24, 42],
|
&[6, 24, 42],
|
||||||
&[6, 26, 46],
|
&[6, 26, 46],
|
||||||
|
@ -660,7 +660,7 @@ impl Canvas {
|
||||||
match self.version {
|
match self.version {
|
||||||
Version::Micro(_) | Version::Normal(1...6) => { return; }
|
Version::Micro(_) | Version::Normal(1...6) => { return; }
|
||||||
Version::Normal(a) => {
|
Version::Normal(a) => {
|
||||||
let version_info = VERSION_INFOS[(a - 7) as uint] << 14;
|
let version_info = VERSION_INFOS[(a - 7) as usize] << 14;
|
||||||
self.draw_number(version_info, Module::Dark, Module::Light,
|
self.draw_number(version_info, Module::Dark, Module::Light,
|
||||||
&VERSION_INFO_COORDS_BL);
|
&VERSION_INFO_COORDS_BL);
|
||||||
self.draw_number(version_info, Module::Dark, Module::Light,
|
self.draw_number(version_info, Module::Dark, Module::Light,
|
||||||
|
@ -822,7 +822,7 @@ mod draw_version_info_tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VERSION_INFO_COORDS_BL: [(i16, i16), ..18] = [
|
static VERSION_INFO_COORDS_BL: [(i16, i16); 18] = [
|
||||||
(5, -9), (5, -10), (5, -11),
|
(5, -9), (5, -10), (5, -11),
|
||||||
(4, -9), (4, -10), (4, -11),
|
(4, -9), (4, -10), (4, -11),
|
||||||
(3, -9), (3, -10), (3, -11),
|
(3, -9), (3, -10), (3, -11),
|
||||||
|
@ -831,7 +831,7 @@ static VERSION_INFO_COORDS_BL: [(i16, i16), ..18] = [
|
||||||
(0, -9), (0, -10), (0, -11),
|
(0, -9), (0, -10), (0, -11),
|
||||||
];
|
];
|
||||||
|
|
||||||
static VERSION_INFO_COORDS_TR: [(i16, i16), ..18] = [
|
static VERSION_INFO_COORDS_TR: [(i16, i16); 18] = [
|
||||||
(-9, 5), (-10, 5), (-11, 5),
|
(-9, 5), (-10, 5), (-11, 5),
|
||||||
(-9, 4), (-10, 4), (-11, 4),
|
(-9, 4), (-10, 4), (-11, 4),
|
||||||
(-9, 3), (-10, 3), (-11, 3),
|
(-9, 3), (-10, 3), (-11, 3),
|
||||||
|
@ -840,23 +840,23 @@ static VERSION_INFO_COORDS_TR: [(i16, i16), ..18] = [
|
||||||
(-9, 0), (-10, 0), (-11, 0),
|
(-9, 0), (-10, 0), (-11, 0),
|
||||||
];
|
];
|
||||||
|
|
||||||
static FORMAT_INFO_COORDS_QR_MAIN: [(i16, i16), ..15] = [
|
static FORMAT_INFO_COORDS_QR_MAIN: [(i16, i16); 15] = [
|
||||||
(0, 8), (1, 8), (2, 8), (3, 8), (4, 8), (5, 8),
|
(0, 8), (1, 8), (2, 8), (3, 8), (4, 8), (5, 8),
|
||||||
(7, 8), (8, 8), (8, 7),
|
(7, 8), (8, 8), (8, 7),
|
||||||
(8, 5), (8, 4), (8, 3), (8, 2), (8, 1), (8, 0),
|
(8, 5), (8, 4), (8, 3), (8, 2), (8, 1), (8, 0),
|
||||||
];
|
];
|
||||||
|
|
||||||
static FORMAT_INFO_COORDS_QR_SIDE: [(i16, i16), ..15] = [
|
static FORMAT_INFO_COORDS_QR_SIDE: [(i16, i16); 15] = [
|
||||||
(8, -1), (8, -2), (8, -3), (8, -4), (8, -5), (8, -6), (8, -7),
|
(8, -1), (8, -2), (8, -3), (8, -4), (8, -5), (8, -6), (8, -7),
|
||||||
(-8, 8), (-7, 8), (-6, 8), (-5, 8), (-4, 8), (-3, 8), (-2, 8), (-1, 8),
|
(-8, 8), (-7, 8), (-6, 8), (-5, 8), (-4, 8), (-3, 8), (-2, 8), (-1, 8),
|
||||||
];
|
];
|
||||||
|
|
||||||
static FORMAT_INFO_COORDS_MICRO_QR: [(i16, i16), ..15] = [
|
static FORMAT_INFO_COORDS_MICRO_QR: [(i16, i16); 15] = [
|
||||||
(1, 8), (2, 8), (3, 8), (4, 8), (5, 8), (6, 8), (7, 8), (8, 8),
|
(1, 8), (2, 8), (3, 8), (4, 8), (5, 8), (6, 8), (7, 8), (8, 8),
|
||||||
(8, 7), (8, 6), (8, 5), (8, 4), (8, 3), (8, 2), (8, 1),
|
(8, 7), (8, 6), (8, 5), (8, 4), (8, 3), (8, 2), (8, 1),
|
||||||
];
|
];
|
||||||
|
|
||||||
static VERSION_INFOS: [u32, ..34] = [
|
static VERSION_INFOS: [u32; 34] = [
|
||||||
0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
|
0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
|
||||||
0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
|
0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
|
||||||
0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
|
0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
|
||||||
|
@ -909,7 +909,7 @@ pub fn is_functional(version: Version, width: i16, x: i16, y: i16) -> bool {
|
||||||
} else if 2 <= a && a <= 6 {
|
} else if 2 <= a && a <= 6 {
|
||||||
(width - 7 - x).abs() <= 2 && (width - 7 - y).abs() <= 2
|
(width - 7 - x).abs() <= 2 && (width - 7 - y).abs() <= 2
|
||||||
} else {
|
} else {
|
||||||
let positions = ALIGNMENT_PATTERN_POSITIONS[a as uint - 7];
|
let positions = ALIGNMENT_PATTERN_POSITIONS[a as usize - 7];
|
||||||
let last = positions.len() - 1;
|
let last = positions.len() - 1;
|
||||||
for (i, align_x) in positions.iter().enumerate() {
|
for (i, align_x) in positions.iter().enumerate() {
|
||||||
for (j, align_y) in positions.iter().enumerate() {
|
for (j, align_y) in positions.iter().enumerate() {
|
||||||
|
@ -1060,7 +1060,9 @@ impl DataModuleIter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator<(i16, i16)> for DataModuleIter {
|
impl Iterator for DataModuleIter {
|
||||||
|
type Item = (i16, i16);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<(i16, i16)> {
|
fn next(&mut self) -> Option<(i16, i16)> {
|
||||||
let adjusted_ref_col = if self.x <= self.timing_pattern_column {
|
let adjusted_ref_col = if self.x <= self.timing_pattern_column {
|
||||||
self.x + 1
|
self.x + 1
|
||||||
|
@ -1269,14 +1271,14 @@ impl Canvas {
|
||||||
codewords: &[u8],
|
codewords: &[u8],
|
||||||
is_half_codeword_at_end: bool,
|
is_half_codeword_at_end: bool,
|
||||||
coords: &mut I)
|
coords: &mut I)
|
||||||
where I: Iterator<(i16, i16)>
|
where I: Iterator<Item=(i16, i16)>
|
||||||
{
|
{
|
||||||
let length = codewords.len();
|
let length = codewords.len();
|
||||||
let last_word = if is_half_codeword_at_end { length-1 } else { length };
|
let last_word = if is_half_codeword_at_end { length-1 } else { length };
|
||||||
for (i, b) in codewords.iter().enumerate() {
|
for (i, b) in codewords.iter().enumerate() {
|
||||||
let bits_end = if i == last_word { 4 } else { 0 };
|
let bits_end = if i == last_word { 4 } else { 0 };
|
||||||
'outside:
|
'outside:
|
||||||
for j in range_inclusive(bits_end, 7u).rev() {
|
for j in range_inclusive(bits_end, 7us).rev() {
|
||||||
let color = if (*b & (1 << j)) != 0 {
|
let color = if (*b & (1 << j)) != 0 {
|
||||||
Module::DarkUnmasked
|
Module::DarkUnmasked
|
||||||
} else {
|
} else {
|
||||||
|
@ -1370,7 +1372,7 @@ mod draw_codewords_test {
|
||||||
|
|
||||||
/// The mask patterns. Since QR code and Micro QR code do not use the same
|
/// The mask patterns. Since QR code and Micro QR code do not use the same
|
||||||
/// pattern number, we name them according to their shape instead of the number.
|
/// pattern number, we name them according to their shape instead of the number.
|
||||||
#[deriving(Show, Copy)]
|
#[derive(Show, Copy)]
|
||||||
pub enum MaskPattern {
|
pub enum MaskPattern {
|
||||||
/// QR code pattern 000: `(x + y) % 2 == 0`.
|
/// QR code pattern 000: `(x + y) % 2 == 0`.
|
||||||
Checkerboard = 0b000,
|
Checkerboard = 0b000,
|
||||||
|
@ -1426,8 +1428,8 @@ impl Canvas {
|
||||||
/// patterns.
|
/// patterns.
|
||||||
pub fn apply_mask(&mut self, pattern: MaskPattern) {
|
pub fn apply_mask(&mut self, pattern: MaskPattern) {
|
||||||
let mask_fn = get_mask_function(pattern);
|
let mask_fn = get_mask_function(pattern);
|
||||||
for x in range(0, self.width) {
|
for x in (0 .. self.width) {
|
||||||
for y in range(0, self.width) {
|
for y in (0 .. self.width) {
|
||||||
let module = self.get_mut(x, y);
|
let module = self.get_mut(x, y);
|
||||||
*module = module.mask(mask_fn(x, y));
|
*module = module.mask(mask_fn(x, y));
|
||||||
}
|
}
|
||||||
|
@ -1444,7 +1446,7 @@ impl Canvas {
|
||||||
fn draw_format_info_patterns(&mut self, pattern: MaskPattern) {
|
fn draw_format_info_patterns(&mut self, pattern: MaskPattern) {
|
||||||
let format_number = match self.version {
|
let format_number = match self.version {
|
||||||
Version::Normal(_) => {
|
Version::Normal(_) => {
|
||||||
let simple_format_number = ((self.ec_level as uint) ^ 1) << 3 | (pattern as uint);
|
let simple_format_number = ((self.ec_level as usize) ^ 1) << 3 | (pattern as usize);
|
||||||
FORMAT_INFOS_QR[simple_format_number]
|
FORMAT_INFOS_QR[simple_format_number]
|
||||||
}
|
}
|
||||||
Version::Micro(a) => {
|
Version::Micro(a) => {
|
||||||
|
@ -1558,14 +1560,14 @@ mod mask_tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORMAT_INFOS_QR: [u16, ..32] = [
|
static FORMAT_INFOS_QR: [u16; 32] = [
|
||||||
0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0,
|
0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0,
|
||||||
0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976,
|
0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976,
|
||||||
0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b,
|
0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b,
|
||||||
0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed,
|
0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed,
|
||||||
];
|
];
|
||||||
|
|
||||||
static FORMAT_INFOS_MICRO_QR: [u16, ..32] = [
|
static FORMAT_INFOS_MICRO_QR: [u16; 32] = [
|
||||||
0x4445, 0x4172, 0x4e2b, 0x4b1c, 0x55ae, 0x5099, 0x5fc0, 0x5af7,
|
0x4445, 0x4172, 0x4e2b, 0x4b1c, 0x55ae, 0x5099, 0x5fc0, 0x5af7,
|
||||||
0x6793, 0x62a4, 0x6dfd, 0x68ca, 0x7678, 0x734f, 0x7c16, 0x7921,
|
0x6793, 0x62a4, 0x6dfd, 0x68ca, 0x7678, 0x734f, 0x7c16, 0x7921,
|
||||||
0x06de, 0x03e9, 0x0cb0, 0x0987, 0x1735, 0x1202, 0x1d5b, 0x186c,
|
0x06de, 0x03e9, 0x0cb0, 0x0987, 0x1735, 0x1202, 0x1d5b, 0x186c,
|
||||||
|
@ -1585,14 +1587,14 @@ impl Canvas {
|
||||||
fn compute_adjacent_penalty_score(&self, is_horizontal: bool) -> u16 {
|
fn compute_adjacent_penalty_score(&self, is_horizontal: bool) -> u16 {
|
||||||
let mut total_score = 0;
|
let mut total_score = 0;
|
||||||
|
|
||||||
for i in range(0, self.width) {
|
for i in (0 .. self.width) {
|
||||||
let map_fn = |&:j| if is_horizontal {
|
let map_fn = |&:j| if is_horizontal {
|
||||||
self.get(j, i)
|
self.get(j, i)
|
||||||
} else {
|
} else {
|
||||||
self.get(i, j)
|
self.get(i, j)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut colors = range(0, self.width).map(map_fn)
|
let mut colors = (0 .. self.width).map(map_fn)
|
||||||
.chain(Some(Module::Empty).into_iter());
|
.chain(Some(Module::Empty).into_iter());
|
||||||
let mut last_color = Module::Empty;
|
let mut last_color = Module::Empty;
|
||||||
let mut consecutive_len = 1u16;
|
let mut consecutive_len = 1u16;
|
||||||
|
@ -1621,8 +1623,8 @@ impl Canvas {
|
||||||
fn compute_block_penalty_score(&self) -> u16 {
|
fn compute_block_penalty_score(&self) -> u16 {
|
||||||
let mut total_score = 0;
|
let mut total_score = 0;
|
||||||
|
|
||||||
for i in range(0, self.width-1) {
|
for i in (0 .. self.width-1) {
|
||||||
for j in range(0, self.width-1) {
|
for j in (0 .. self.width-1) {
|
||||||
let this = self.get(i, j);
|
let this = self.get(i, j);
|
||||||
let right = self.get(i+1, j);
|
let right = self.get(i+1, j);
|
||||||
let bottom = self.get(i, j+1);
|
let bottom = self.get(i, j+1);
|
||||||
|
@ -1642,27 +1644,28 @@ impl Canvas {
|
||||||
/// Every pattern that looks like `#.###.#....` in any orientation will add
|
/// Every pattern that looks like `#.###.#....` in any orientation will add
|
||||||
/// 40 points.
|
/// 40 points.
|
||||||
fn compute_finder_penalty_score(&self, is_horizontal: bool) -> u16 {
|
fn compute_finder_penalty_score(&self, is_horizontal: bool) -> u16 {
|
||||||
static PATTERN: [Module, ..7] = [
|
static PATTERN: [Module; 7] = [
|
||||||
Module::Dark, Module::Light, Module::Dark, Module::Dark,
|
Module::Dark, Module::Light, Module::Dark, Module::Dark,
|
||||||
Module::Dark, Module::Light, Module::Dark,
|
Module::Dark, Module::Light, Module::Dark,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut total_score = 0;
|
let mut total_score = 0;
|
||||||
|
|
||||||
for i in range(0, self.width) {
|
for i in (0 .. self.width) {
|
||||||
for j in range(0, self.width-6) {
|
for j in (0 .. self.width-6) {
|
||||||
let get = if is_horizontal {
|
// TODO a ref to a closure should be enough?
|
||||||
|k: i16| self.get(k, i)
|
let get: Box<Fn(i16) -> Module> = if is_horizontal {
|
||||||
|
Box::new(|&: k: i16| self.get(k, i))
|
||||||
} else {
|
} else {
|
||||||
|k: i16| self.get(i, k)
|
Box::new(|&: k: i16| self.get(i, k))
|
||||||
};
|
};
|
||||||
|
|
||||||
if !equals(range(j, j+7).map(|k| get(k)), PATTERN.iter().map(|m| *m)) {
|
if !equals((j .. j+7).map(|k| get(k)), PATTERN.iter().map(|m| *m)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let check = |k| { 0 <= k && k < self.width && get(k).is_dark() };
|
let check = |&: k| { 0 <= k && k < self.width && get(k).is_dark() };
|
||||||
if !range(j-4, j).any(|k| check(k)) || !range(j+7, j+11).any(|k| check(k)) {
|
if !(j-4 .. j).any(|k| check(k)) || !(j+7 .. j+11).any(|k| check(k)) {
|
||||||
total_score += 40;
|
total_score += 40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1698,8 +1701,8 @@ impl Canvas {
|
||||||
/// has the inverse meaning of this method, but it is very easy to convert
|
/// has the inverse meaning of this method, but it is very easy to convert
|
||||||
/// between the two (this score is (16×width − standard-score)).
|
/// between the two (this score is (16×width − standard-score)).
|
||||||
fn compute_light_side_penalty_score(&self) -> u16 {
|
fn compute_light_side_penalty_score(&self) -> u16 {
|
||||||
let h = range(1, self.width).filter(|j| !self.get(*j, -1).is_dark()).count();
|
let h = (1 .. self.width).filter(|j| !self.get(*j, -1).is_dark()).count();
|
||||||
let v = range(1, self.width).filter(|j| !self.get(-1, *j).is_dark()).count();
|
let v = (1 .. self.width).filter(|j| !self.get(-1, *j).is_dark()).count();
|
||||||
|
|
||||||
(h + v + 15 * max(h, v)) as u16
|
(h + v + 15 * max(h, v)) as u16
|
||||||
}
|
}
|
||||||
|
@ -1792,14 +1795,14 @@ mod penalty_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_penalty_score_light_sides() {
|
fn test_penalty_score_light_sides() {
|
||||||
static HORIZONTAL_SIDE: [Module, ..17] = [
|
static HORIZONTAL_SIDE: [Module; 17] = [
|
||||||
Module::Dark, Module::Light, Module::Light, Module::Dark,
|
Module::Dark, Module::Light, Module::Light, Module::Dark,
|
||||||
Module::Dark, Module::Dark, Module::Light, Module::Light,
|
Module::Dark, Module::Dark, Module::Light, Module::Light,
|
||||||
Module::Dark, Module::Light, Module::Dark, Module::Light,
|
Module::Dark, Module::Light, Module::Dark, Module::Light,
|
||||||
Module::Light, Module::Dark, Module::Light, Module::Light,
|
Module::Light, Module::Dark, Module::Light, Module::Light,
|
||||||
Module::Light,
|
Module::Light,
|
||||||
];
|
];
|
||||||
static VERTICAL_SIDE: [Module, ..17] = [
|
static VERTICAL_SIDE: [Module; 17] = [
|
||||||
Module::Dark, Module::Dark, Module::Dark, Module::Light,
|
Module::Dark, Module::Dark, Module::Dark, Module::Light,
|
||||||
Module::Light, Module::Dark, Module::Dark, Module::Light,
|
Module::Light, Module::Dark, Module::Dark, Module::Light,
|
||||||
Module::Dark, Module::Light, Module::Dark, Module::Light,
|
Module::Dark, Module::Light, Module::Dark, Module::Light,
|
||||||
|
@ -1808,9 +1811,9 @@ mod penalty_tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut c = Canvas::new(Version::Micro(4), EcLevel::Q);
|
let mut c = Canvas::new(Version::Micro(4), EcLevel::Q);
|
||||||
for i in range(0, 17) {
|
for i in 0 .. 17 {
|
||||||
c.put(i, -1, HORIZONTAL_SIDE[i as uint]);
|
c.put(i, -1, HORIZONTAL_SIDE[i as usize]);
|
||||||
c.put(-1, i, VERTICAL_SIDE[i as uint]);
|
c.put(-1, i, VERTICAL_SIDE[i as usize]);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(c.compute_light_side_penalty_score(), 168);
|
assert_eq!(c.compute_light_side_penalty_score(), 168);
|
||||||
|
@ -1821,14 +1824,14 @@ mod penalty_tests {
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//{{{ Select mask with lowest penalty score
|
//{{{ Select mask with lowest penalty score
|
||||||
|
|
||||||
static ALL_PATTERNS_QR: [MaskPattern, ..8] = [
|
static ALL_PATTERNS_QR: [MaskPattern; 8] = [
|
||||||
MaskPattern::Checkerboard, MaskPattern::HorizontalLines,
|
MaskPattern::Checkerboard, MaskPattern::HorizontalLines,
|
||||||
MaskPattern::VerticalLines, MaskPattern::DiagonalLines,
|
MaskPattern::VerticalLines, MaskPattern::DiagonalLines,
|
||||||
MaskPattern::LargeCheckerboard, MaskPattern::Fields,
|
MaskPattern::LargeCheckerboard, MaskPattern::Fields,
|
||||||
MaskPattern::Diamonds, MaskPattern::Meadow,
|
MaskPattern::Diamonds, MaskPattern::Meadow,
|
||||||
];
|
];
|
||||||
|
|
||||||
static ALL_PATTERNS_MICRO_QR: [MaskPattern, ..4] = [
|
static ALL_PATTERNS_MICRO_QR: [MaskPattern; 4] = [
|
||||||
MaskPattern::HorizontalLines, MaskPattern::LargeCheckerboard,
|
MaskPattern::HorizontalLines, MaskPattern::LargeCheckerboard,
|
||||||
MaskPattern::Diamonds, MaskPattern::Meadow,
|
MaskPattern::Diamonds, MaskPattern::Meadow,
|
||||||
];
|
];
|
||||||
|
|
23
src/ec.rs
23
src/ec.rs
|
@ -1,6 +1,7 @@
|
||||||
//! The `ec` module applies the Reed-Solomon error correction codes.
|
//! The `ec` module applies the Reed-Solomon error correction codes.
|
||||||
|
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use types::{QrResult, Version, EcLevel};
|
use types::{QrResult, Version, EcLevel};
|
||||||
|
|
||||||
|
@ -16,22 +17,22 @@ use types::{QrResult, Version, EcLevel};
|
||||||
/// (a[0] x<sup>m+n</sup> + a[1] x<sup>m+n-1</sup> + … + a[m] x<sup>n</sup>) in
|
/// (a[0] x<sup>m+n</sup> + a[1] x<sup>m+n-1</sup> + … + a[m] x<sup>n</sup>) in
|
||||||
/// GF(256), and then computes the polynomial modulus with a generator
|
/// GF(256), and then computes the polynomial modulus with a generator
|
||||||
/// polynomial of degree N.
|
/// polynomial of degree N.
|
||||||
pub fn create_error_correction_code(data: &[u8], ec_code_size: uint) -> Vec<u8> {
|
pub fn create_error_correction_code(data: &[u8], ec_code_size: usize) -> Vec<u8> {
|
||||||
let mut res = data.to_vec();
|
let mut res = data.to_vec();
|
||||||
res.extend(repeat(0).take(ec_code_size));
|
res.extend(repeat(0).take(ec_code_size));
|
||||||
|
|
||||||
let data_len = data.len();
|
let data_len = data.len();
|
||||||
let log_den = GENERATOR_POLYNOMIALS[ec_code_size];
|
let log_den = GENERATOR_POLYNOMIALS[ec_code_size];
|
||||||
|
|
||||||
for i in range(0, data_len) {
|
for i in (0 .. data_len) {
|
||||||
let lead_coeff = res[i] as uint;
|
let lead_coeff = res[i] as usize;
|
||||||
if lead_coeff == 0 {
|
if lead_coeff == 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let log_lead_coeff = LOG_TABLE[lead_coeff] as uint;
|
let log_lead_coeff = LOG_TABLE[lead_coeff] as usize;
|
||||||
for (u, v) in res.slice_from_mut(i+1).iter_mut().zip(log_den.iter()) {
|
for (u, v) in res.slice_from_mut(i+1).iter_mut().zip(log_den.iter()) {
|
||||||
*u ^= EXP_TABLE[((*v as uint + log_lead_coeff) % 255) as uint];
|
*u ^= EXP_TABLE[((*v as usize + log_lead_coeff) % 255) as usize];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,10 +73,10 @@ mod ec_tests {
|
||||||
///
|
///
|
||||||
/// The longest slice must be at the last of `blocks`, and `blocks` must not be
|
/// The longest slice must be at the last of `blocks`, and `blocks` must not be
|
||||||
/// empty.
|
/// empty.
|
||||||
fn interleave<T: Copy, V: Deref<[T]>>(blocks: &Vec<V>) -> Vec<T> {
|
fn interleave<T: Copy, V: Deref<Target=[T]>>(blocks: &Vec<V>) -> Vec<T> {
|
||||||
let last_block_len = blocks.last().unwrap().len();
|
let last_block_len = blocks.last().unwrap().len();
|
||||||
let mut res = Vec::with_capacity(last_block_len * blocks.len());
|
let mut res = Vec::with_capacity(last_block_len * blocks.len());
|
||||||
for i in range(0, last_block_len) {
|
for i in (0 .. last_block_len) {
|
||||||
for t in blocks.iter() {
|
for t in blocks.iter() {
|
||||||
if i < t.len() {
|
if i < t.len() {
|
||||||
res.push(t[i]);
|
res.push(t[i]);
|
||||||
|
@ -158,7 +159,7 @@ mod construct_codewords_test {
|
||||||
|
|
||||||
/// Computes the maximum allowed number of erratic modules can be introduced to
|
/// Computes the maximum allowed number of erratic modules can be introduced to
|
||||||
/// the QR code, before the data becomes truly corrupted.
|
/// the QR code, before the data becomes truly corrupted.
|
||||||
pub fn max_allowed_errors(version: Version, ec_level: EcLevel) -> QrResult<uint> {
|
pub fn max_allowed_errors(version: Version, ec_level: EcLevel) -> QrResult<usize> {
|
||||||
use Version::{Micro, Normal};
|
use Version::{Micro, Normal};
|
||||||
use EcLevel::{L, M};
|
use EcLevel::{L, M};
|
||||||
|
|
||||||
|
@ -244,7 +245,7 @@ static LOG_TABLE: &'static [u8] = b"\xff\x00\x01\x19\x02\x32\x1a\xc6\x03\xdf\x33
|
||||||
/// is the Reed-Solomon error correction code.
|
/// is the Reed-Solomon error correction code.
|
||||||
///
|
///
|
||||||
/// A partial list can be found from ISO/IEC 18004:2006 Annex A.
|
/// A partial list can be found from ISO/IEC 18004:2006 Annex A.
|
||||||
static GENERATOR_POLYNOMIALS: [&'static [u8], ..70] = [
|
static GENERATOR_POLYNOMIALS: [&'static [u8]; 70] = [
|
||||||
b"",
|
b"",
|
||||||
b"\x00",
|
b"\x00",
|
||||||
b"\x19\x01",
|
b"\x19\x01",
|
||||||
|
@ -325,7 +326,7 @@ static GENERATOR_POLYNOMIALS: [&'static [u8], ..70] = [
|
||||||
/// correction per block in each version.
|
/// correction per block in each version.
|
||||||
///
|
///
|
||||||
/// This is a copy of ISO/IEC 18004:2006, §6.5.1, Table 9.
|
/// This is a copy of ISO/IEC 18004:2006, §6.5.1, Table 9.
|
||||||
static EC_BYTES_PER_BLOCK: [[uint, ..4], ..44] = [
|
static EC_BYTES_PER_BLOCK: [[usize; 4]; 44] = [
|
||||||
// Normal versions.
|
// Normal versions.
|
||||||
[7, 10, 13, 17],
|
[7, 10, 13, 17],
|
||||||
[10, 16, 22, 28],
|
[10, 16, 22, 28],
|
||||||
|
@ -383,7 +384,7 @@ static EC_BYTES_PER_BLOCK: [[uint, ..4], ..44] = [
|
||||||
/// Every entry is a 4-tuple. Take `DATA_BYTES_PER_BLOCK[39][3] == (15, 20, 16, 61)`
|
/// Every entry is a 4-tuple. Take `DATA_BYTES_PER_BLOCK[39][3] == (15, 20, 16, 61)`
|
||||||
/// as an example, this means in version 40 with correction level H, there are
|
/// as an example, this means in version 40 with correction level H, there are
|
||||||
/// 20 blocks with 15 bytes in size, and 61 blocks with 16 bytes in size.
|
/// 20 blocks with 15 bytes in size, and 61 blocks with 16 bytes in size.
|
||||||
static DATA_BYTES_PER_BLOCK: [[(uint, uint, uint, uint), ..4], ..44] = [
|
static DATA_BYTES_PER_BLOCK: [[(usize, usize, usize, usize); 4]; 44] = [
|
||||||
// Normal versions.
|
// Normal versions.
|
||||||
[(19, 1, 0, 0), (16, 1, 0, 0), (13, 1, 0, 0), (9, 1, 0, 0)],
|
[(19, 1, 0, 0), (16, 1, 0, 0), (13, 1, 0, 0), (9, 1, 0, 0)],
|
||||||
[(34, 1, 0, 0), (28, 1, 0, 0), (22, 1, 0, 0), (16, 1, 0, 0)],
|
[(34, 1, 0, 0), (28, 1, 0, 0), (22, 1, 0, 0), (16, 1, 0, 0)],
|
||||||
|
|
35
src/lib.rs
35
src/lib.rs
|
@ -6,10 +6,10 @@
|
||||||
//!
|
//!
|
||||||
//! let code = QrCode::new(b"Some content here.");
|
//! let code = QrCode::new(b"Some content here.");
|
||||||
//! match code {
|
//! match code {
|
||||||
//! Err(err) => panic!("Failed to encode the QR code: {}", err),
|
//! Err(err) => panic!("Failed to encode the QR code: {:?}", err),
|
||||||
//! Ok(code) => {
|
//! Ok(code) => {
|
||||||
//! for y in range(0, code.width()) {
|
//! for y in (0 .. code.width()) {
|
||||||
//! for x in range(0, code.width()) {
|
//! for x in (0 .. code.width()) {
|
||||||
//! let color = if code[(x, y)] { "black" } else { "white" };
|
//! let color = if code[(x, y)] { "black" } else { "white" };
|
||||||
//! // render color at position (x, y)
|
//! // render color at position (x, y)
|
||||||
//! }
|
//! }
|
||||||
|
@ -21,8 +21,11 @@
|
||||||
#![unstable]
|
#![unstable]
|
||||||
#![feature(slicing_syntax)]
|
#![feature(slicing_syntax)]
|
||||||
|
|
||||||
|
#[allow(unstable)]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
|
use std::ops::Index;
|
||||||
|
|
||||||
pub use types::{QrResult, EcLevel, Version};
|
pub use types::{QrResult, EcLevel, Version};
|
||||||
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
@ -32,12 +35,12 @@ pub mod ec;
|
||||||
pub mod canvas;
|
pub mod canvas;
|
||||||
|
|
||||||
/// The encoded QR code symbol.
|
/// The encoded QR code symbol.
|
||||||
#[deriving(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct QrCode {
|
pub struct QrCode {
|
||||||
content: Vec<bool>,
|
content: Vec<bool>,
|
||||||
version: Version,
|
version: Version,
|
||||||
ec_level: EcLevel,
|
ec_level: EcLevel,
|
||||||
width: uint,
|
width: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QrCode {
|
impl QrCode {
|
||||||
|
@ -113,7 +116,7 @@ impl QrCode {
|
||||||
pub fn with_bits(bits: bits::Bits, ec_level: EcLevel) -> QrResult<QrCode> {
|
pub fn with_bits(bits: bits::Bits, ec_level: EcLevel) -> QrResult<QrCode> {
|
||||||
let version = bits.version();
|
let version = bits.version();
|
||||||
let data = bits.into_bytes();
|
let data = bits.into_bytes();
|
||||||
let (encoded_data, ec_data) = try!(ec::construct_codewords(data[], version, ec_level));
|
let (encoded_data, ec_data) = try!(ec::construct_codewords(&*data, version, ec_level));
|
||||||
let mut canvas = canvas::Canvas::new(version, ec_level);
|
let mut canvas = canvas::Canvas::new(version, ec_level);
|
||||||
canvas.draw_all_functional_patterns();
|
canvas.draw_all_functional_patterns();
|
||||||
canvas.draw_data(&*encoded_data, &*ec_data);
|
canvas.draw_data(&*encoded_data, &*ec_data);
|
||||||
|
@ -122,7 +125,7 @@ impl QrCode {
|
||||||
content: canvas.to_bools(),
|
content: canvas.to_bools(),
|
||||||
version: version,
|
version: version,
|
||||||
ec_level: ec_level,
|
ec_level: ec_level,
|
||||||
width: version.width() as uint,
|
width: version.width() as usize,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,20 +142,20 @@ impl QrCode {
|
||||||
/// Gets the number of modules per side, i.e. the width of this QR code.
|
/// Gets the number of modules per side, i.e. the width of this QR code.
|
||||||
///
|
///
|
||||||
/// The width here does not contain the quiet zone paddings.
|
/// The width here does not contain the quiet zone paddings.
|
||||||
pub fn width(&self) -> uint {
|
pub fn width(&self) -> usize {
|
||||||
self.width
|
self.width
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the maximum number of allowed erratic modules can be introduced
|
/// Gets the maximum number of allowed erratic modules can be introduced
|
||||||
/// before the data becomes corrupted. Note that errors should not be
|
/// before the data becomes corrupted. Note that errors should not be
|
||||||
/// introduced to functional modules.
|
/// introduced to functional modules.
|
||||||
pub fn max_allowed_errors(&self) -> uint {
|
pub fn max_allowed_errors(&self) -> usize {
|
||||||
ec::max_allowed_errors(self.version, self.ec_level).unwrap()
|
ec::max_allowed_errors(self.version, self.ec_level).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether a module at coordinate (x, y) is a functional module or
|
/// Checks whether a module at coordinate (x, y) is a functional module or
|
||||||
/// not.
|
/// not.
|
||||||
pub fn is_functional(&self, x: uint, y: uint) -> bool {
|
pub fn is_functional(&self, x: usize, y: usize) -> bool {
|
||||||
canvas::is_functional(self.version, self.version.width(), x as i16, y as i16)
|
canvas::is_functional(self.version, self.version.width(), x as i16, y as i16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,9 +165,9 @@ impl QrCode {
|
||||||
let width = self.width;
|
let width = self.width;
|
||||||
let mut k = 0;
|
let mut k = 0;
|
||||||
let mut res = String::with_capacity(width * (width + 1));
|
let mut res = String::with_capacity(width * (width + 1));
|
||||||
for _ in range(0, width) {
|
for _ in (0 .. width) {
|
||||||
res.push('\n');
|
res.push('\n');
|
||||||
for _ in range(0, width) {
|
for _ in (0 .. width) {
|
||||||
res.push(if self.content[k] { on_char } else { off_char });
|
res.push(if self.content[k] { on_char } else { off_char });
|
||||||
k += 1;
|
k += 1;
|
||||||
}
|
}
|
||||||
|
@ -185,10 +188,12 @@ impl QrCode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<(uint, uint), bool> for QrCode {
|
impl Index<(usize, usize)> for QrCode {
|
||||||
fn index(&self, &(x, y): &(uint, uint)) -> &bool {
|
type Output = bool;
|
||||||
|
|
||||||
|
fn index(&self, &(x, y): &(usize, usize)) -> &bool {
|
||||||
let index = y * self.width + x;
|
let index = y * self.width + x;
|
||||||
self.content.index(&index)
|
&self.content[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,22 +11,22 @@ use test::Bencher;
|
||||||
//{{{ Segment
|
//{{{ Segment
|
||||||
|
|
||||||
/// A segment of data committed to an encoding mode.
|
/// A segment of data committed to an encoding mode.
|
||||||
#[deriving(PartialEq, Eq, Show, Copy, Clone)]
|
#[derive(PartialEq, Eq, Show, Copy, Clone)]
|
||||||
pub struct Segment {
|
pub struct Segment {
|
||||||
/// The encoding mode of the segment of data.
|
/// The encoding mode of the segment of data.
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
|
|
||||||
/// The start index of the segment.
|
/// The start index of the segment.
|
||||||
pub begin: uint,
|
pub begin: usize,
|
||||||
|
|
||||||
/// The end index (exclusive) of the segment.
|
/// The end index (exclusive) of the segment.
|
||||||
pub end: uint,
|
pub end: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Segment {
|
impl Segment {
|
||||||
/// Compute the number of bits (including the size of the mode indicator and
|
/// Compute the number of bits (including the size of the mode indicator and
|
||||||
/// length bits) when this segment is encoded.
|
/// length bits) when this segment is encoded.
|
||||||
pub fn encoded_len(&self, version: Version) -> uint {
|
pub fn encoded_len(&self, version: Version) -> usize {
|
||||||
let byte_size = self.end - self.begin;
|
let byte_size = self.end - self.begin;
|
||||||
let chars_count = if self.mode == Mode::Kanji { byte_size / 2 } else { byte_size };
|
let chars_count = if self.mode == Mode::Kanji { byte_size / 2 } else { byte_size };
|
||||||
|
|
||||||
|
@ -54,12 +54,14 @@ impl Segment {
|
||||||
///
|
///
|
||||||
struct EcsIter<I> {
|
struct EcsIter<I> {
|
||||||
base: I,
|
base: I,
|
||||||
index: uint,
|
index: usize,
|
||||||
ended: bool,
|
ended: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I: Iterator<&'a u8>> Iterator<(uint, ExclCharSet)> for EcsIter<I> {
|
impl<'a, I: Iterator<Item=&'a u8>> Iterator for EcsIter<I> {
|
||||||
fn next(&mut self) -> Option<(uint, ExclCharSet)> {
|
type Item = (usize, ExclCharSet);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<(usize, ExclCharSet)> {
|
||||||
if self.ended {
|
if self.ended {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +84,7 @@ impl<'a, I: Iterator<&'a u8>> Iterator<(uint, ExclCharSet)> for EcsIter<I> {
|
||||||
pub struct Parser<'a> {
|
pub struct Parser<'a> {
|
||||||
ecs_iter: EcsIter<Iter<'a, u8>>,
|
ecs_iter: EcsIter<Iter<'a, u8>>,
|
||||||
state: State,
|
state: State,
|
||||||
begin: uint,
|
begin: usize,
|
||||||
pending_single_byte: bool,
|
pending_single_byte: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +110,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator<Segment> for Parser<'a> {
|
impl<'a> Iterator for Parser<'a> {
|
||||||
|
type Item = Segment;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Segment> {
|
fn next(&mut self) -> Option<Segment> {
|
||||||
if self.pending_single_byte {
|
if self.pending_single_byte {
|
||||||
self.pending_single_byte = false;
|
self.pending_single_byte = false;
|
||||||
|
@ -125,7 +129,7 @@ impl<'a> Iterator<Segment> for Parser<'a> {
|
||||||
None => { return None; },
|
None => { return None; },
|
||||||
Some(a) => a
|
Some(a) => a
|
||||||
};
|
};
|
||||||
let (next_state, action) = STATE_TRANSITION[self.state as uint + ecs as uint];
|
let (next_state, action) = STATE_TRANSITION[self.state as usize + ecs as usize];
|
||||||
self.state = next_state;
|
self.state = next_state;
|
||||||
|
|
||||||
let old_begin = self.begin;
|
let old_begin = self.begin;
|
||||||
|
@ -239,12 +243,12 @@ mod parse_tests {
|
||||||
pub struct Optimizer<I> {
|
pub struct Optimizer<I> {
|
||||||
parser: I,
|
parser: I,
|
||||||
last_segment: Segment,
|
last_segment: Segment,
|
||||||
last_segment_size: uint,
|
last_segment_size: usize,
|
||||||
version: Version,
|
version: Version,
|
||||||
ended: bool,
|
ended: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Iterator<Segment>> Optimizer<I> {
|
impl<I: Iterator<Item=Segment>> Optimizer<I> {
|
||||||
/// Optimize the segments by combining adjacent segments when possible.
|
/// Optimize the segments by combining adjacent segments when possible.
|
||||||
///
|
///
|
||||||
/// Currently this method uses a greedy algorithm by combining segments from
|
/// Currently this method uses a greedy algorithm by combining segments from
|
||||||
|
@ -277,7 +281,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Iterator<Segment>> Iterator<Segment> for Optimizer<I> {
|
impl<I: Iterator<Item=Segment>> Iterator for Optimizer<I> {
|
||||||
|
type Item = Segment;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Segment> {
|
fn next(&mut self) -> Option<Segment> {
|
||||||
if self.ended {
|
if self.ended {
|
||||||
return None;
|
return None;
|
||||||
|
@ -315,7 +321,7 @@ impl<I: Iterator<Segment>> Iterator<Segment> for Optimizer<I> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the total encoded length of all segments.
|
/// Computes the total encoded length of all segments.
|
||||||
pub fn total_encoded_len(segments: &[Segment], version: Version) -> uint {
|
pub fn total_encoded_len(segments: &[Segment], version: Version) -> usize {
|
||||||
use std::iter::AdditiveIterator;
|
use std::iter::AdditiveIterator;
|
||||||
segments.iter().map(|seg| seg.encoded_len(version)).sum()
|
segments.iter().map(|seg| seg.encoded_len(version)).sum()
|
||||||
}
|
}
|
||||||
|
@ -333,7 +339,7 @@ mod optimize_tests {
|
||||||
assert!(prev_len > new_len, "{} > {}", prev_len, new_len);
|
assert!(prev_len > new_len, "{} > {}", prev_len, new_len);
|
||||||
}
|
}
|
||||||
assert!(opt_segs == expected,
|
assert!(opt_segs == expected,
|
||||||
"Optimization gave something better: {} < {} ({})",
|
"Optimization gave something better: {} < {} ({:?})",
|
||||||
new_len, total_encoded_len(&*expected, version), opt_segs);
|
new_len, total_encoded_len(&*expected, version), opt_segs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +471,7 @@ fn bench_optimize(bencher: &mut Bencher) {
|
||||||
/// All values of `u8` can be split into 9 different character sets when
|
/// All values of `u8` can be split into 9 different character sets when
|
||||||
/// determining which encoding to use. This enum represents these groupings for
|
/// determining which encoding to use. This enum represents these groupings for
|
||||||
/// parsing purpose.
|
/// parsing purpose.
|
||||||
#[deriving(Copy)]
|
#[derive(Copy)]
|
||||||
enum ExclCharSet {
|
enum ExclCharSet {
|
||||||
/// The end of string.
|
/// The end of string.
|
||||||
End = 0,
|
End = 0,
|
||||||
|
@ -525,7 +531,7 @@ impl ExclCharSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The current parsing state.
|
/// The current parsing state.
|
||||||
#[deriving(Copy)]
|
#[derive(Copy)]
|
||||||
enum State {
|
enum State {
|
||||||
/// Just initialized.
|
/// Just initialized.
|
||||||
Init = 0,
|
Init = 0,
|
||||||
|
@ -552,7 +558,7 @@ enum State {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What should the parser do after a state transition.
|
/// What should the parser do after a state transition.
|
||||||
#[deriving(Copy)]
|
#[derive(Copy)]
|
||||||
enum Action {
|
enum Action {
|
||||||
/// The parser should do nothing.
|
/// The parser should do nothing.
|
||||||
Idle,
|
Idle,
|
||||||
|
@ -574,7 +580,7 @@ enum Action {
|
||||||
KanjiAndSingleByte,
|
KanjiAndSingleByte,
|
||||||
}
|
}
|
||||||
|
|
||||||
static STATE_TRANSITION: [(State, Action), ..70] = [
|
static STATE_TRANSITION: [(State, Action); 70] = [
|
||||||
// STATE_TRANSITION[current_state + next_character] == (next_state, what_to_do)
|
// STATE_TRANSITION[current_state + next_character] == (next_state, what_to_do)
|
||||||
|
|
||||||
// Init state:
|
// Init state:
|
||||||
|
|
47
src/types.rs
47
src/types.rs
|
@ -1,13 +1,14 @@
|
||||||
#![unstable]
|
#![unstable]
|
||||||
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use std::cmp::{PartialOrd, Ordering};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//{{{ QrResult
|
//{{{ QrResult
|
||||||
|
|
||||||
/// `QrError` encodes the error encountered when generating a QR code.
|
/// `QrError` encodes the error encountered when generating a QR code.
|
||||||
#[unstable]
|
#[unstable]
|
||||||
#[deriving(Show, PartialEq, Eq, Copy, Clone)]
|
#[derive(Show, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum QrError {
|
pub enum QrError {
|
||||||
/// The data is too long to encode into a QR code for the given version.
|
/// The data is too long to encode into a QR code for the given version.
|
||||||
DataTooLong,
|
DataTooLong,
|
||||||
|
@ -37,7 +38,7 @@ pub type QrResult<T> = Result<T, QrError>;
|
||||||
|
|
||||||
/// The error correction level. It allows the original information be recovered
|
/// The error correction level. It allows the original information be recovered
|
||||||
/// even if parts of the code is damaged.
|
/// even if parts of the code is damaged.
|
||||||
#[deriving(Show, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)]
|
#[derive(Show, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)]
|
||||||
#[unstable]
|
#[unstable]
|
||||||
pub enum EcLevel {
|
pub enum EcLevel {
|
||||||
/// Low error correction. Allows up to 7% of wrong blocks.
|
/// Low error correction. Allows up to 7% of wrong blocks.
|
||||||
|
@ -64,7 +65,7 @@ pub enum EcLevel {
|
||||||
/// The smallest version is `Version::Normal(1)` of size 21×21, and the largest
|
/// The smallest version is `Version::Normal(1)` of size 21×21, and the largest
|
||||||
/// is `Version::Normal(40)` of size 177×177.
|
/// is `Version::Normal(40)` of size 177×177.
|
||||||
#[unstable]
|
#[unstable]
|
||||||
#[deriving(Show, PartialEq, Eq, Copy, Clone)]
|
#[derive(Show, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum Version {
|
pub enum Version {
|
||||||
/// A normal QR code version. The parameter should be between 1 and 40.
|
/// A normal QR code version. The parameter should be between 1 and 40.
|
||||||
Normal(i16),
|
Normal(i16),
|
||||||
|
@ -94,13 +95,13 @@ impl Version {
|
||||||
///
|
///
|
||||||
/// If the entry compares equal to the default value of T, this method
|
/// If the entry compares equal to the default value of T, this method
|
||||||
/// returns `Err(QrError::InvalidVersion)`.
|
/// returns `Err(QrError::InvalidVersion)`.
|
||||||
pub fn fetch<T>(&self, ec_level: EcLevel, table: &[[T, ..4]]) -> QrResult<T>
|
pub fn fetch<T>(&self, ec_level: EcLevel, table: &[[T; 4]]) -> QrResult<T>
|
||||||
where T: PartialEq + Default + Copy
|
where T: PartialEq + Default + Copy
|
||||||
{
|
{
|
||||||
match *self {
|
match *self {
|
||||||
Version::Normal(v @ 1...40) => Ok(table[v as uint - 1][ec_level as uint]),
|
Version::Normal(v @ 1...40) => Ok(table[v as usize - 1][ec_level as usize]),
|
||||||
Version::Micro(v @ 1...4) => {
|
Version::Micro(v @ 1...4) => {
|
||||||
let obj = table[v as uint + 39][ec_level as uint];
|
let obj = table[v as usize + 39][ec_level as usize];
|
||||||
if obj != Default::default() {
|
if obj != Default::default() {
|
||||||
Ok(obj)
|
Ok(obj)
|
||||||
} else {
|
} else {
|
||||||
|
@ -113,9 +114,9 @@ impl Version {
|
||||||
|
|
||||||
/// The number of bits needed to encode the mode indicator.
|
/// The number of bits needed to encode the mode indicator.
|
||||||
#[unstable]
|
#[unstable]
|
||||||
pub fn mode_bits_count(&self) -> uint {
|
pub fn mode_bits_count(&self) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
Version::Micro(a) => (a - 1) as uint,
|
Version::Micro(a) => (a - 1) as usize,
|
||||||
_ => 4,
|
_ => 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +138,7 @@ impl Version {
|
||||||
|
|
||||||
/// The mode indicator, which specifies the character set of the encoded data.
|
/// The mode indicator, which specifies the character set of the encoded data.
|
||||||
#[unstable]
|
#[unstable]
|
||||||
#[deriving(Show, PartialEq, Eq, Copy, Clone)]
|
#[derive(Show, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
/// The data contains only characters 0 to 9.
|
/// The data contains only characters 0 to 9.
|
||||||
Numeric,
|
Numeric,
|
||||||
|
@ -163,10 +164,10 @@ impl Mode {
|
||||||
/// This method will return `Err(QrError::UnsupportedCharacterSet)` if the
|
/// This method will return `Err(QrError::UnsupportedCharacterSet)` if the
|
||||||
/// mode is not supported in the given version.
|
/// mode is not supported in the given version.
|
||||||
#[unstable]
|
#[unstable]
|
||||||
pub fn length_bits_count(&self, version: Version) -> uint {
|
pub fn length_bits_count(&self, version: Version) -> usize {
|
||||||
match version {
|
match version {
|
||||||
Version::Micro(a) => {
|
Version::Micro(a) => {
|
||||||
let a = a as uint;
|
let a = a as usize;
|
||||||
match *self {
|
match *self {
|
||||||
Mode::Numeric => 2 + a,
|
Mode::Numeric => 2 + a,
|
||||||
Mode::Alphanumeric | Mode::Byte => 1 + a,
|
Mode::Alphanumeric | Mode::Byte => 1 + a,
|
||||||
|
@ -203,7 +204,7 @@ impl Mode {
|
||||||
/// Note that in Kanji mode, the `raw_data_len` is the number of Kanjis,
|
/// Note that in Kanji mode, the `raw_data_len` is the number of Kanjis,
|
||||||
/// i.e. half the total size of bytes.
|
/// i.e. half the total size of bytes.
|
||||||
#[unstable]
|
#[unstable]
|
||||||
pub fn data_bits_count(&self, raw_data_len: uint) -> uint {
|
pub fn data_bits_count(&self, raw_data_len: usize) -> usize {
|
||||||
match *self {
|
match *self {
|
||||||
Mode::Numeric => (raw_data_len * 10 + 2) / 3,
|
Mode::Numeric => (raw_data_len * 10 + 2) / 3,
|
||||||
Mode::Alphanumeric => (raw_data_len * 11 + 1) / 2,
|
Mode::Alphanumeric => (raw_data_len * 11 + 1) / 2,
|
||||||
|
@ -224,8 +225,8 @@ impl Mode {
|
||||||
///
|
///
|
||||||
pub fn max(&self, other: Mode) -> Mode {
|
pub fn max(&self, other: Mode) -> Mode {
|
||||||
match self.partial_cmp(&other) {
|
match self.partial_cmp(&other) {
|
||||||
Some(Less) | Some(Equal) => other,
|
Some(Ordering::Less) | Some(Ordering::Equal) => other,
|
||||||
Some(Greater) => *self,
|
Some(Ordering::Greater) => *self,
|
||||||
None => Mode::Byte,
|
None => Mode::Byte,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,15 +237,15 @@ impl PartialOrd for Mode {
|
||||||
/// a superset of all characters supported by `a`.
|
/// a superset of all characters supported by `a`.
|
||||||
fn partial_cmp(&self, other: &Mode) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Mode) -> Option<Ordering> {
|
||||||
match (*self, *other) {
|
match (*self, *other) {
|
||||||
(Mode::Numeric, Mode::Alphanumeric) => Some(Less),
|
(Mode::Numeric, Mode::Alphanumeric) => Some(Ordering::Less),
|
||||||
(Mode::Alphanumeric, Mode::Numeric) => Some(Greater),
|
(Mode::Alphanumeric, Mode::Numeric) => Some(Ordering::Greater),
|
||||||
(Mode::Numeric, Mode::Byte) => Some(Less),
|
(Mode::Numeric, Mode::Byte) => Some(Ordering::Less),
|
||||||
(Mode::Byte, Mode::Numeric) => Some(Greater),
|
(Mode::Byte, Mode::Numeric) => Some(Ordering::Greater),
|
||||||
(Mode::Alphanumeric, Mode::Byte) => Some(Less),
|
(Mode::Alphanumeric, Mode::Byte) => Some(Ordering::Less),
|
||||||
(Mode::Byte, Mode::Alphanumeric) => Some(Greater),
|
(Mode::Byte, Mode::Alphanumeric) => Some(Ordering::Greater),
|
||||||
(Mode::Kanji, Mode::Byte) => Some(Less),
|
(Mode::Kanji, Mode::Byte) => Some(Ordering::Less),
|
||||||
(Mode::Byte, Mode::Kanji) => Some(Greater),
|
(Mode::Byte, Mode::Kanji) => Some(Ordering::Greater),
|
||||||
(a, b) if a == b => Some(Equal),
|
(a, b) if a == b => Some(Ordering::Equal),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue