rustup for beta.
This commit is contained in:
parent
9f2adaad82
commit
6ebf629ba4
|
@ -2,9 +2,13 @@
|
||||||
name = "qrcode"
|
name = "qrcode"
|
||||||
description = "QR code encoder in Rust"
|
description = "QR code encoder in Rust"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
authors = ["kennytm <kennytm@gmail.com>"]
|
authors = ["kennytm <kennytm@gmail.com>"]
|
||||||
keywords = ["qrcode"]
|
keywords = ["qrcode"]
|
||||||
repository = "https://github.com/kennytm/qrcode-rust"
|
repository = "https://github.com/kennytm/qrcode-rust"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
documentation = "http://www.rust-ci.org/kennytm/qrcode-rust/doc/qrcode/index.html"
|
documentation = "http://www.rust-ci.org/kennytm/qrcode-rust/doc/qrcode/index.html"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
num = "*"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
//! The `bits` module encodes binary data into raw bits used in a QR code.
|
//! The `bits` module encodes binary data into raw bits used in a QR code.
|
||||||
|
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::iter::iterate;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
@ -143,7 +142,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.
|
||||||
#[derive(Copy)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum ExtendedMode {
|
pub enum ExtendedMode {
|
||||||
/// ECI mode indicator, to introduce an ECI designator.
|
/// ECI mode indicator, to introduce an ECI designator.
|
||||||
Eci,
|
Eci,
|
||||||
|
@ -676,10 +675,12 @@ impl Bits {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.len() < data_length {
|
if self.len() < data_length {
|
||||||
|
const PADDING_BYTES: &'static [u8] = &[0b11101100, 0b00010001];
|
||||||
|
|
||||||
self.bit_offset = 0;
|
self.bit_offset = 0;
|
||||||
let data_bytes_length = data_length / 8;
|
let data_bytes_length = data_length / 8;
|
||||||
let padding_bytes_count = data_bytes_length - self.data.len();
|
let padding_bytes_count = data_bytes_length - self.data.len();
|
||||||
let padding = iterate(0b11101100, |a| a ^ 0b11111101).take(padding_bytes_count);
|
let padding = PADDING_BYTES.iter().cloned().cycle().take(padding_bytes_count);
|
||||||
self.data.extend(padding);
|
self.data.extend(padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,19 @@
|
||||||
//! c.apply_mask(MaskPattern::Checkerboard);
|
//! c.apply_mask(MaskPattern::Checkerboard);
|
||||||
//! let bools = c.to_bools();
|
//! let bools = c.to_bools();
|
||||||
|
|
||||||
use std::iter::{range_inclusive, repeat};
|
use std::iter::repeat;
|
||||||
use std::iter::order::equals;
|
|
||||||
use std::num::Int;
|
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
|
use num::traits::PrimInt;
|
||||||
|
use std::ops::Range;
|
||||||
|
|
||||||
use types::{Version, EcLevel};
|
use types::{Version, EcLevel};
|
||||||
|
|
||||||
|
// TODO remove this after it is decided whether we want `p ... q` or
|
||||||
|
// `(p .. q).inclusive()`
|
||||||
|
fn range_inclusive<N: PrimInt>(from: N, to: N) -> Range<N> {
|
||||||
|
from .. (to + N::one())
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//{{{ Modules
|
//{{{ Modules
|
||||||
|
|
||||||
|
@ -621,10 +627,10 @@ impl Canvas {
|
||||||
/// `off_color`. The coordinates will be extracted from the `coords`
|
/// `off_color`. The coordinates will be extracted from the `coords`
|
||||||
/// iterator. It will start from the most significant bits first, so
|
/// iterator. It will start from the most significant bits first, so
|
||||||
/// *trailing* zeros will be ignored.
|
/// *trailing* zeros will be ignored.
|
||||||
fn draw_number<N: Int>(&mut self, number: N,
|
fn draw_number<N: PrimInt>(&mut self, number: N,
|
||||||
on_color: Module, off_color: Module,
|
on_color: Module, off_color: Module,
|
||||||
coords: &[(i16, i16)]) {
|
coords: &[(i16, i16)]) {
|
||||||
let zero: N = Int::zero();
|
let zero: N = N::zero();
|
||||||
let mut mask: N = !(!zero >> 1);
|
let mut mask: N = !(!zero >> 1);
|
||||||
for &(x, y) in coords {
|
for &(x, y) in coords {
|
||||||
let color = if (mask & number) == zero { off_color } else { on_color };
|
let color = if (mask & number) == zero { off_color } else { on_color };
|
||||||
|
@ -887,8 +893,6 @@ impl Canvas {
|
||||||
/// Gets whether the module at the given coordinates represents a functional
|
/// Gets whether the module at the given coordinates represents a functional
|
||||||
/// module.
|
/// module.
|
||||||
pub fn is_functional(version: Version, width: i16, x: i16, y: i16) -> bool {
|
pub fn is_functional(version: Version, width: i16, x: i16, y: i16) -> bool {
|
||||||
use std::num::SignedInt;
|
|
||||||
|
|
||||||
debug_assert!(width == version.width());
|
debug_assert!(width == version.width());
|
||||||
|
|
||||||
let x = if x < 0 { x + width } else { x };
|
let x = if x < 0 { x + width } else { x };
|
||||||
|
@ -1372,7 +1376,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.
|
||||||
#[derive(Debug, Copy)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
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,
|
||||||
|
@ -1649,6 +1653,13 @@ impl Canvas {
|
||||||
Module::Dark, Module::Light, Module::Dark,
|
Module::Dark, Module::Light, Module::Dark,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// TODO remove this after `equals()` is stable.
|
||||||
|
fn equals<T, U>(left: T, right: U) -> bool
|
||||||
|
where T: Iterator, U: Iterator, T::Item: PartialEq<U::Item>
|
||||||
|
{
|
||||||
|
left.zip(right).all(|(p, q)| p == q)
|
||||||
|
}
|
||||||
|
|
||||||
let mut total_score = 0;
|
let mut total_score = 0;
|
||||||
|
|
||||||
for i in 0 .. self.width {
|
for i in 0 .. self.width {
|
||||||
|
@ -1845,11 +1856,23 @@ impl Canvas {
|
||||||
Version::Micro(_) => ALL_PATTERNS_MICRO_QR.iter(),
|
Version::Micro(_) => ALL_PATTERNS_MICRO_QR.iter(),
|
||||||
};
|
};
|
||||||
|
|
||||||
patterns.map(|ptn| {
|
let mut patterns = patterns.map(|ptn| {
|
||||||
let mut c = self.clone();
|
let mut c = self.clone();
|
||||||
c.apply_mask(*ptn);
|
c.apply_mask(*ptn);
|
||||||
c
|
c
|
||||||
}).min_by(|c| c.compute_total_penalty_scores()).unwrap()
|
});
|
||||||
|
|
||||||
|
// TODO revert to `min_by` after it is stable.
|
||||||
|
let mut best_pattern = patterns.next().unwrap();
|
||||||
|
let mut best_pattern_score = best_pattern.compute_total_penalty_scores();
|
||||||
|
for c in patterns {
|
||||||
|
let score = c.compute_total_penalty_scores();
|
||||||
|
if score < best_pattern_score {
|
||||||
|
best_pattern = c;
|
||||||
|
best_pattern_score = score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
best_pattern
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the modules into a vector of booleans.
|
/// Convert the modules into a vector of booleans.
|
||||||
|
|
|
@ -19,9 +19,11 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
#![unstable]
|
#![unstable]
|
||||||
#![feature(test, core)] // Unstable libraries
|
#![cfg_attr(test, feature(test))] // Unstable libraries
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
extern crate num;
|
||||||
|
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
|
||||||
|
|
|
@ -322,8 +322,8 @@ impl<I: Iterator<Item=Segment>> Iterator 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) -> usize {
|
pub fn total_encoded_len(segments: &[Segment], version: Version) -> usize {
|
||||||
use std::iter::AdditiveIterator;
|
// TODO revert to `.map().sum()` after `sum()` is stable.
|
||||||
segments.iter().map(|seg| seg.encoded_len(version)).sum()
|
segments.iter().fold(0, |acc, seg| acc + seg.encoded_len(version))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -471,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.
|
||||||
#[derive(Copy)]
|
#[derive(Copy, Clone)]
|
||||||
enum ExclCharSet {
|
enum ExclCharSet {
|
||||||
/// The end of string.
|
/// The end of string.
|
||||||
End = 0,
|
End = 0,
|
||||||
|
@ -531,7 +531,7 @@ impl ExclCharSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The current parsing state.
|
/// The current parsing state.
|
||||||
#[derive(Copy)]
|
#[derive(Copy, Clone)]
|
||||||
enum State {
|
enum State {
|
||||||
/// Just initialized.
|
/// Just initialized.
|
||||||
Init = 0,
|
Init = 0,
|
||||||
|
@ -558,7 +558,7 @@ enum State {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What should the parser do after a state transition.
|
/// What should the parser do after a state transition.
|
||||||
#[derive(Copy)]
|
#[derive(Copy, Clone)]
|
||||||
enum Action {
|
enum Action {
|
||||||
/// The parser should do nothing.
|
/// The parser should do nothing.
|
||||||
Idle,
|
Idle,
|
||||||
|
|
Loading…
Reference in a new issue