rustup for beta.

This commit is contained in:
kennytm 2015-04-05 16:18:28 +08:00
parent 9f2adaad82
commit 6ebf629ba4
5 changed files with 52 additions and 22 deletions

View file

@ -2,9 +2,13 @@
name = "qrcode"
description = "QR code encoder in Rust"
license = "Apache-2.0"
version = "0.1.3"
version = "0.1.4"
authors = ["kennytm <kennytm@gmail.com>"]
keywords = ["qrcode"]
repository = "https://github.com/kennytm/qrcode-rust"
readme = "README.md"
documentation = "http://www.rust-ci.org/kennytm/qrcode-rust/doc/qrcode/index.html"
[dependencies]
num = "*"

View file

@ -3,7 +3,6 @@
//! The `bits` module encodes binary data into raw bits used in a QR code.
use std::cmp::min;
use std::iter::iterate;
#[cfg(test)]
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
/// beyond those bearing data.
#[derive(Copy)]
#[derive(Copy, Clone)]
pub enum ExtendedMode {
/// ECI mode indicator, to introduce an ECI designator.
Eci,
@ -676,10 +675,12 @@ impl Bits {
}
if self.len() < data_length {
const PADDING_BYTES: &'static [u8] = &[0b11101100, 0b00010001];
self.bit_offset = 0;
let data_bytes_length = data_length / 8;
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);
}

View file

@ -9,13 +9,19 @@
//! c.apply_mask(MaskPattern::Checkerboard);
//! let bools = c.to_bools();
use std::iter::{range_inclusive, repeat};
use std::iter::order::equals;
use std::num::Int;
use std::iter::repeat;
use std::cmp::max;
use num::traits::PrimInt;
use std::ops::Range;
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
@ -621,10 +627,10 @@ impl Canvas {
/// `off_color`. The coordinates will be extracted from the `coords`
/// iterator. It will start from the most significant bits first, so
/// *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,
coords: &[(i16, i16)]) {
let zero: N = Int::zero();
let zero: N = N::zero();
let mut mask: N = !(!zero >> 1);
for &(x, y) in coords {
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
/// module.
pub fn is_functional(version: Version, width: i16, x: i16, y: i16) -> bool {
use std::num::SignedInt;
debug_assert!(width == version.width());
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
/// pattern number, we name them according to their shape instead of the number.
#[derive(Debug, Copy)]
#[derive(Debug, Copy, Clone)]
pub enum MaskPattern {
/// QR code pattern 000: `(x + y) % 2 == 0`.
Checkerboard = 0b000,
@ -1649,6 +1653,13 @@ impl Canvas {
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;
for i in 0 .. self.width {
@ -1845,11 +1856,23 @@ impl Canvas {
Version::Micro(_) => ALL_PATTERNS_MICRO_QR.iter(),
};
patterns.map(|ptn| {
let mut patterns = patterns.map(|ptn| {
let mut c = self.clone();
c.apply_mask(*ptn);
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.

View file

@ -19,9 +19,11 @@
//!
#![unstable]
#![feature(test, core)] // Unstable libraries
#![cfg_attr(test, feature(test))] // Unstable libraries
#[cfg(test)]
extern crate test;
extern crate num;
use std::ops::Index;

View file

@ -322,8 +322,8 @@ impl<I: Iterator<Item=Segment>> Iterator for Optimizer<I> {
/// Computes the total encoded length of all segments.
pub fn total_encoded_len(segments: &[Segment], version: Version) -> usize {
use std::iter::AdditiveIterator;
segments.iter().map(|seg| seg.encoded_len(version)).sum()
// TODO revert to `.map().sum()` after `sum()` is stable.
segments.iter().fold(0, |acc, seg| acc + seg.encoded_len(version))
}
#[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
/// determining which encoding to use. This enum represents these groupings for
/// parsing purpose.
#[derive(Copy)]
#[derive(Copy, Clone)]
enum ExclCharSet {
/// The end of string.
End = 0,
@ -531,7 +531,7 @@ impl ExclCharSet {
}
/// The current parsing state.
#[derive(Copy)]
#[derive(Copy, Clone)]
enum State {
/// Just initialized.
Init = 0,
@ -558,7 +558,7 @@ enum State {
}
/// What should the parser do after a state transition.
#[derive(Copy)]
#[derive(Copy, Clone)]
enum Action {
/// The parser should do nothing.
Idle,