Merge pull request #40 from kennytm/ed2018

Use 2018 edition (MSRV = 1.33.0).
This commit is contained in:
kennytm 2019-12-22 17:43:13 +08:00 committed by GitHub
commit bcecedf489
18 changed files with 148 additions and 193 deletions

View file

@ -15,7 +15,7 @@ addons:
matrix: matrix:
include: include:
- os: linux - os: linux
rust: 1.31.1 rust: 1.33.0
- os: linux - os: linux
rust: stable rust: stable
- os: osx - os: osx

View file

@ -1,8 +1,9 @@
[package] [package]
name = "qrcode" name = "qrcode"
description = "QR code encoder in Rust" description = "QR code encoder in Rust"
license = "MIT / Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.11.0" version = "0.11.1"
edition = "2018"
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"

View file

@ -4,7 +4,7 @@ qrcode-rust
[![Build status](https://travis-ci.org/kennytm/qrcode-rust.svg?branch=master)](https://travis-ci.org/kennytm/qrcode-rust) [![Build status](https://travis-ci.org/kennytm/qrcode-rust.svg?branch=master)](https://travis-ci.org/kennytm/qrcode-rust)
[![Coverage Status](https://coveralls.io/repos/github/kennytm/qrcode-rust/badge.svg?branch=coveralls)](https://coveralls.io/github/kennytm/qrcode-rust?branch=coveralls) [![Coverage Status](https://coveralls.io/repos/github/kennytm/qrcode-rust/badge.svg?branch=coveralls)](https://coveralls.io/github/kennytm/qrcode-rust?branch=coveralls)
[![crates.io](https://img.shields.io/crates/v/qrcode.svg)](https://crates.io/crates/qrcode) [![crates.io](https://img.shields.io/crates/v/qrcode.svg)](https://crates.io/crates/qrcode)
[![MIT / Apache 2.0](https://img.shields.io/badge/license-MIT%20%2f%20Apache%202.0-blue.svg)](./LICENSE-APACHE.txt) [![MIT OR Apache 2.0](https://img.shields.io/badge/license-MIT%20%2f%20Apache%202.0-blue.svg)](./LICENSE-APACHE.txt)
QR code and Micro QR code encoder in Rust. [Documentation](https://docs.rs/qrcode). QR code and Micro QR code encoder in Rust. [Documentation](https://docs.rs/qrcode).
@ -13,14 +13,14 @@ Cargo.toml
```toml ```toml
[dependencies] [dependencies]
qrcode = "0.8" qrcode = "0.11"
``` ```
The default settings will depend on the `image` crate. If you don't need image generation capability, disable the `default-features`: The default settings will depend on the `image` crate. If you don't need image generation capability, disable the `default-features`:
```toml ```toml
[dependencies] [dependencies]
qrcode = { version = "0.8", default-features = false } qrcode = { version = "0.11", default-features = false }
``` ```
Example Example
@ -29,9 +29,6 @@ Example
## Image generation ## Image generation
```rust ```rust
extern crate qrcode;
extern crate image;
use qrcode::QrCode; use qrcode::QrCode;
use image::Luma; use image::Luma;
@ -54,7 +51,6 @@ Generates this image:
## String generation ## String generation
```rust ```rust
extern crate qrcode;
use qrcode::QrCode; use qrcode::QrCode;
fn main() { fn main() {
@ -96,8 +92,6 @@ Generates this output:
## SVG generation ## SVG generation
```rust ```rust
extern crate qrcode;
use qrcode::{QrCode, Version, EcLevel}; use qrcode::{QrCode, Version, EcLevel};
use qrcode::render::svg; use qrcode::render::svg;

View file

@ -1,6 +1,3 @@
extern crate image;
extern crate qrcode;
use image::Luma; use image::Luma;
use qrcode::QrCode; use qrcode::QrCode;

View file

@ -1,4 +1,3 @@
extern crate qrcode;
use qrcode::QrCode; use qrcode::QrCode;
fn main() { fn main() {

View file

@ -1,5 +1,3 @@
extern crate qrcode;
use qrcode::render::svg; use qrcode::render::svg;
use qrcode::{EcLevel, QrCode, Version}; use qrcode::{EcLevel, QrCode, Version};

View file

@ -1,5 +1,3 @@
extern crate qrcode;
use std::env; use std::env;
pub fn main() { pub fn main() {

View file

@ -3,11 +3,11 @@
use std::cmp::min; use std::cmp::min;
#[cfg(feature = "bench")] #[cfg(feature = "bench")]
use test::{black_box, Bencher}; extern crate test;
use cast::{As, Truncate}; use crate::cast::{As, Truncate};
use optimize::{total_encoded_len, Optimizer, Parser, Segment}; use crate::optimize::{total_encoded_len, Optimizer, Parser, Segment};
use types::{EcLevel, Mode, QrError, QrResult, Version}; use crate::types::{EcLevel, Mode, QrError, QrResult, Version};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//{{{ Bits //{{{ Bits
@ -36,17 +36,17 @@ impl Bits {
let b = self.bit_offset + n; let b = self.bit_offset + n;
let last_index = self.data.len().wrapping_sub(1); let last_index = self.data.len().wrapping_sub(1);
match (self.bit_offset, b) { match (self.bit_offset, b) {
(0, 0...8) => { (0, 0..=8) => {
self.data.push((number << (8 - b)).truncate_as_u8()); self.data.push((number << (8 - b)).truncate_as_u8());
} }
(0, _) => { (0, _) => {
self.data.push((number >> (b - 8)).truncate_as_u8()); self.data.push((number >> (b - 8)).truncate_as_u8());
self.data.push((number << (16 - b)).truncate_as_u8()); self.data.push((number << (16 - b)).truncate_as_u8());
} }
(_, 0...8) => { (_, 0..=8) => {
self.data[last_index] |= (number << (8 - b)).truncate_as_u8(); self.data[last_index] |= (number << (8 - b)).truncate_as_u8();
} }
(_, 9...16) => { (_, 9..=16) => {
self.data[last_index] |= (number >> (b - 8)).truncate_as_u8(); self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
self.data.push((number << (16 - b)).truncate_as_u8()); self.data.push((number << (16 - b)).truncate_as_u8());
} }
@ -141,7 +141,7 @@ fn test_push_number() {
#[cfg(feature = "bench")] #[cfg(feature = "bench")]
#[bench] #[bench]
fn bench_push_splitted_bytes(bencher: &mut Bencher) { fn bench_push_splitted_bytes(bencher: &mut test::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);
@ -182,7 +182,7 @@ impl Bits {
/// If the mode is not supported in the provided version, this method /// If the mode is not supported in the provided version, this method
/// returns `Err(QrError::UnsupportedCharacterSet)`. /// returns `Err(QrError::UnsupportedCharacterSet)`.
pub fn push_mode_indicator(&mut self, mode: ExtendedMode) -> QrResult<()> { pub fn push_mode_indicator(&mut self, mode: ExtendedMode) -> QrResult<()> {
#[cfg_attr(feature = "cargo-clippy", allow(match_same_arms))] #[allow(clippy::match_same_arms)]
let number = match (self.version, mode) { let number = match (self.version, mode) {
(Version::Micro(1), ExtendedMode::Data(Mode::Numeric)) => return Ok(()), (Version::Micro(1), ExtendedMode::Data(Mode::Numeric)) => return Ok(()),
(Version::Micro(_), ExtendedMode::Data(Mode::Numeric)) => 0, (Version::Micro(_), ExtendedMode::Data(Mode::Numeric)) => 0,
@ -226,7 +226,7 @@ impl Bits {
/// ///
/// ///
/// The full list of ECI designator values can be found from /// The full list of ECI designator values can be found from
/// http://strokescribe.com/en/ECI.html. Some example values are: /// <http://strokescribe.com/en/ECI.html>. Some example values are:
/// ///
/// ECI # | Character set /// ECI # | Character set
/// ------|------------------------------------- /// ------|-------------------------------------
@ -248,14 +248,14 @@ impl Bits {
self.reserve(12); // assume the common case that eci_designator <= 127. self.reserve(12); // assume the common case that eci_designator <= 127.
self.push_mode_indicator(ExtendedMode::Eci)?; self.push_mode_indicator(ExtendedMode::Eci)?;
match eci_designator { match eci_designator {
0...127 => { 0..=127 => {
self.push_number(8, eci_designator.as_u16()); self.push_number(8, eci_designator.as_u16());
} }
128...16383 => { 128..=16383 => {
self.push_number(2, 0b10); self.push_number(2, 0b10);
self.push_number(14, eci_designator.as_u16()); self.push_number(14, eci_designator.as_u16());
} }
16384...999_999 => { 16384..=999_999 => {
self.push_number(3, 0b110); self.push_number(3, 0b110);
self.push_number(5, (eci_designator >> 16).as_u16()); self.push_number(5, (eci_designator >> 16).as_u16());
self.push_number(16, (eci_designator & 0xffff).as_u16()); self.push_number(16, (eci_designator & 0xffff).as_u16());
@ -268,8 +268,8 @@ impl Bits {
#[cfg(test)] #[cfg(test)]
mod eci_tests { mod eci_tests {
use bits::Bits; use crate::bits::Bits;
use types::{QrError, Version}; use crate::types::{QrError, Version};
#[test] #[test]
fn test_9() { fn test_9() {
@ -334,8 +334,8 @@ impl Bits {
#[cfg(test)] #[cfg(test)]
mod numeric_tests { mod numeric_tests {
use bits::Bits; use crate::bits::Bits;
use types::{QrError, Version}; use crate::types::{QrError, Version};
#[test] #[test]
fn test_iso_18004_2006_example_1() { fn test_iso_18004_2006_example_1() {
@ -405,8 +405,8 @@ mod numeric_tests {
#[inline] #[inline]
fn alphanumeric_digit(character: u8) -> u16 { fn alphanumeric_digit(character: u8) -> u16 {
match character { match character {
b'0'...b'9' => u16::from(character - b'0'), b'0'..=b'9' => u16::from(character - b'0'),
b'A'...b'Z' => u16::from(character - b'A') + 10, b'A'..=b'Z' => u16::from(character - b'A') + 10,
b' ' => 36, b' ' => 36,
b'$' => 37, b'$' => 37,
b'%' => 38, b'%' => 38,
@ -438,8 +438,8 @@ impl Bits {
#[cfg(test)] #[cfg(test)]
mod alphanumeric_tests { mod alphanumeric_tests {
use bits::Bits; use crate::bits::Bits;
use types::{QrError, Version}; use crate::types::{QrError, Version};
#[test] #[test]
fn test_iso_18004_2006_example() { fn test_iso_18004_2006_example() {
@ -481,8 +481,8 @@ impl Bits {
#[cfg(test)] #[cfg(test)]
mod byte_tests { mod byte_tests {
use bits::Bits; use crate::bits::Bits;
use types::{QrError, Version}; use crate::types::{QrError, Version};
#[test] #[test]
fn test() { fn test() {
@ -541,8 +541,8 @@ impl Bits {
#[cfg(test)] #[cfg(test)]
mod kanji_tests { mod kanji_tests {
use bits::Bits; use crate::bits::Bits;
use types::{QrError, Version}; use crate::types::{QrError, Version};
#[test] #[test]
fn test_iso_18004_example() { fn test_iso_18004_example() {
@ -707,8 +707,8 @@ impl Bits {
#[cfg(test)] #[cfg(test)]
mod finish_tests { mod finish_tests {
use bits::Bits; use crate::bits::Bits;
use types::{EcLevel, QrError, Version}; use crate::types::{EcLevel, QrError, Version};
#[test] #[test]
fn test_hello_world() { fn test_hello_world() {
@ -795,8 +795,8 @@ impl Bits {
#[cfg(test)] #[cfg(test)]
mod encode_tests { mod encode_tests {
use bits::Bits; use crate::bits::Bits;
use types::{EcLevel, QrError, QrResult, Version}; use crate::types::{EcLevel, QrError, QrResult, Version};
fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult<Vec<u8>> { fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult<Vec<u8>> {
let mut bits = Bits::new(version); let mut bits = Bits::new(version);
@ -859,7 +859,7 @@ 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.
fn find_min_version(length: usize, ec_level: EcLevel) -> Version { fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
let mut base = 0usize; let mut base = 0_usize;
let mut size = 39; let mut size = 39;
while size > 1 { while size > 1 {
let half = size / 2; let half = size / 2;
@ -877,8 +877,8 @@ fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
#[cfg(test)] #[cfg(test)]
mod encode_auto_tests { mod encode_auto_tests {
use bits::{encode_auto, find_min_version}; use crate::bits::{encode_auto, find_min_version};
use types::{EcLevel, Version}; use crate::types::{EcLevel, Version};
#[test] #[test]
fn test_find_min_version() { fn test_find_min_version() {
@ -912,7 +912,9 @@ mod encode_auto_tests {
#[cfg(feature = "bench")] #[cfg(feature = "bench")]
#[bench] #[bench]
fn bench_find_min_version(bencher: &mut Bencher) { fn bench_find_min_version(bencher: &mut test::Bencher) {
use test::black_box;
bencher.iter(|| { bencher.iter(|| {
black_box(find_min_version(60, EcLevel::L)); black_box(find_min_version(60, EcLevel::L));
black_box(find_min_version(200, EcLevel::L)); black_box(find_min_version(200, EcLevel::L));

View file

@ -11,8 +11,8 @@
use std::cmp::max; use std::cmp::max;
use cast::As; use crate::cast::As;
use types::{Color, EcLevel, Version}; use crate::types::{Color, EcLevel, Version};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//{{{ Modules //{{{ Modules
@ -144,8 +144,8 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
mod basic_canvas_tests { mod basic_canvas_tests {
use canvas::{Canvas, Module}; use crate::canvas::{Canvas, Module};
use types::{Color, EcLevel, Version}; use crate::types::{Color, EcLevel, Version};
#[test] #[test]
fn test_index() { fn test_index() {
@ -221,7 +221,7 @@ impl Canvas {
self.put( self.put(
x + i, x + i,
y + j, y + j,
#[cfg_attr(feature = "cargo-clippy", allow(match_same_arms))] #[allow(clippy::match_same_arms)]
match (i, j) { match (i, j) {
(4, _) | (_, 4) | (-4, _) | (_, -4) => Color::Light, (4, _) | (_, 4) | (-4, _) | (_, -4) => Color::Light,
(3, _) | (_, 3) | (-3, _) | (_, -3) => Color::Dark, (3, _) | (_, 3) | (-3, _) | (_, -3) => Color::Dark,
@ -253,8 +253,8 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
mod finder_pattern_tests { mod finder_pattern_tests {
use canvas::Canvas; use crate::canvas::Canvas;
use types::{EcLevel, Version}; use crate::types::{EcLevel, Version};
#[test] #[test]
fn test_qr() { fn test_qr() {
@ -340,7 +340,7 @@ impl Canvas {
fn draw_alignment_patterns(&mut self) { fn draw_alignment_patterns(&mut self) {
match self.version { match self.version {
Version::Micro(_) | Version::Normal(1) => {} Version::Micro(_) | Version::Normal(1) => {}
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 - 7).as_usize()]; let positions = ALIGNMENT_PATTERN_POSITIONS[(a - 7).as_usize()];
for x in positions.iter() { for x in positions.iter() {
@ -355,8 +355,8 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
mod alignment_pattern_tests { mod alignment_pattern_tests {
use canvas::Canvas; use crate::canvas::Canvas;
use types::{EcLevel, Version}; use crate::types::{EcLevel, Version};
#[test] #[test]
fn test_draw_alignment_patterns_1() { fn test_draw_alignment_patterns_1() {
@ -490,7 +490,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: [&[i16]; 34] = [
&[6, 22, 38], &[6, 22, 38],
&[6, 24, 42], &[6, 24, 42],
&[6, 26, 46], &[6, 26, 46],
@ -576,8 +576,8 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
mod timing_pattern_tests { mod timing_pattern_tests {
use canvas::Canvas; use crate::canvas::Canvas;
use types::{EcLevel, Version}; use crate::types::{EcLevel, Version};
#[test] #[test]
fn test_draw_timing_patterns_qr() { fn test_draw_timing_patterns_qr() {
@ -675,9 +675,7 @@ impl Canvas {
/// Draws the version information patterns. /// Draws the version information patterns.
fn draw_version_info_patterns(&mut self) { fn draw_version_info_patterns(&mut self) {
match self.version { match self.version {
Version::Micro(_) | Version::Normal(1...6) => { Version::Micro(_) | Version::Normal(1..=6) => {}
return;
}
Version::Normal(a) => { Version::Normal(a) => {
let version_info = VERSION_INFOS[(a - 7).as_usize()]; let version_info = VERSION_INFOS[(a - 7).as_usize()];
self.draw_number(version_info, 18, Color::Dark, Color::Light, &VERSION_INFO_COORDS_BL); self.draw_number(version_info, 18, Color::Dark, Color::Light, &VERSION_INFO_COORDS_BL);
@ -689,8 +687,8 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
mod draw_version_info_tests { mod draw_version_info_tests {
use canvas::Canvas; use crate::canvas::Canvas;
use types::{Color, EcLevel, Version}; use crate::types::{Color, EcLevel, Version};
#[test] #[test]
fn test_draw_number() { fn test_draw_number() {
@ -1017,8 +1015,8 @@ pub fn is_functional(version: Version, width: i16, x: i16, y: i16) -> bool {
#[cfg(test)] #[cfg(test)]
mod all_functional_patterns_tests { mod all_functional_patterns_tests {
use canvas::{is_functional, Canvas}; use crate::canvas::{is_functional, Canvas};
use types::{EcLevel, Version}; use crate::types::{EcLevel, Version};
#[test] #[test]
fn test_all_functional_patterns_qr() { fn test_all_functional_patterns_qr() {
@ -1186,10 +1184,10 @@ impl Iterator for DataModuleIter {
} }
#[cfg(test)] #[cfg(test)]
#[cfg_attr(rustfmt, rustfmt_skip)] // skip to prevent file becoming too long. #[rustfmt::skip] // skip to prevent file becoming too long.
mod data_iter_tests { mod data_iter_tests {
use canvas::DataModuleIter; use crate::canvas::DataModuleIter;
use types::Version; use crate::types::Version;
#[test] #[test]
fn test_qr() { fn test_qr() {
@ -1393,8 +1391,8 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
mod draw_codewords_test { mod draw_codewords_test {
use canvas::Canvas; use crate::canvas::Canvas;
use types::{EcLevel, Version}; use crate::types::{EcLevel, Version};
#[test] #[test]
fn test_micro_qr_1() { fn test_micro_qr_1() {
@ -1586,8 +1584,8 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
mod mask_tests { mod mask_tests {
use canvas::{Canvas, MaskPattern}; use crate::canvas::{Canvas, MaskPattern};
use types::{EcLevel, Version}; use crate::types::{EcLevel, Version};
#[test] #[test]
fn test_apply_mask_qr() { fn test_apply_mask_qr() {
@ -1762,7 +1760,7 @@ impl Canvas {
for i in 0..self.width { for i in 0..self.width {
for j in 0..self.width - 6 { for j in 0..self.width - 6 {
// TODO a ref to a closure should be enough? // TODO a ref to a closure should be enough?
let get: Box<Fn(i16) -> Color> = if is_horizontal { let get: Box<dyn Fn(i16) -> Color> = if is_horizontal {
Box::new(|k| self.get(k, i).into()) Box::new(|k| self.get(k, i).into())
} else { } else {
Box::new(|k| self.get(i, k).into()) Box::new(|k| self.get(i, k).into())
@ -1831,8 +1829,8 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
mod penalty_tests { mod penalty_tests {
use canvas::{Canvas, MaskPattern}; use crate::canvas::{Canvas, MaskPattern};
use types::{Color, EcLevel, Version}; use crate::types::{Color, EcLevel, Version};
fn create_test_canvas() -> Canvas { fn create_test_canvas() -> Canvas {
let mut c = Canvas::new(Version::Normal(1), EcLevel::Q); let mut c = Canvas::new(Version::Normal(1), EcLevel::Q);

View file

@ -8,7 +8,7 @@ pub trait Truncate {
} }
impl Truncate for u16 { impl Truncate for u16 {
#[cfg_attr(feature = "cargo-clippy", allow(cast_possible_truncation))] #[allow(clippy::cast_possible_truncation)]
fn truncate_as_u8(self) -> u8 { fn truncate_as_u8(self) -> u8 {
(self & 0xff) as u8 (self & 0xff) as u8
} }
@ -63,7 +63,6 @@ macro_rules! impl_as {
} }
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
#[cfg_attr(feature = "cargo-clippy", allow(cast_possible_truncation))]
impl As for $ty { impl As for $ty {
fn as_u16(self) -> u16 { fn as_u16(self) -> u16 {
self as u16 self as u16

View file

@ -2,7 +2,7 @@
use std::ops::Deref; use std::ops::Deref;
use types::{EcLevel, QrResult, Version}; use crate::types::{EcLevel, QrResult, Version};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//{{{ Error correction primitive //{{{ Error correction primitive
@ -24,7 +24,6 @@ pub fn create_error_correction_code(data: &[u8], ec_code_size: usize) -> Vec<u8>
res.resize(ec_code_size + data_len, 0); res.resize(ec_code_size + data_len, 0);
// rust-lang-nursery/rust-clippy#2213 // rust-lang-nursery/rust-clippy#2213
#[cfg_attr(feature = "cargo-clippy", allow(needless_range_loop))]
for i in 0..data_len { for i in 0..data_len {
let lead_coeff = res[i] as usize; let lead_coeff = res[i] as usize;
if lead_coeff == 0 { if lead_coeff == 0 {
@ -42,7 +41,7 @@ pub fn create_error_correction_code(data: &[u8], ec_code_size: usize) -> Vec<u8>
#[cfg(test)] #[cfg(test)]
mod ec_tests { mod ec_tests {
use ec::create_error_correction_code; use crate::ec::create_error_correction_code;
#[test] #[test]
fn test_poly_mod_1() { fn test_poly_mod_1() {
@ -127,8 +126,8 @@ pub fn construct_codewords(rawbits: &[u8], version: Version, ec_level: EcLevel)
#[cfg(test)] #[cfg(test)]
mod construct_codewords_test { mod construct_codewords_test {
use ec::construct_codewords; use crate::ec::construct_codewords;
use types::{EcLevel, Version}; use crate::types::{EcLevel, Version};
#[test] #[test]
fn test_add_ec_simple() { fn test_add_ec_simple() {
@ -164,8 +163,8 @@ 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<usize> { pub fn max_allowed_errors(version: Version, ec_level: EcLevel) -> QrResult<usize> {
use EcLevel::{L, M}; use crate::EcLevel::{L, M};
use Version::{Micro, Normal}; use crate::Version::{Micro, Normal};
let p = match (version, ec_level) { let p = match (version, ec_level) {
(Micro(2), L) | (Normal(1), L) => 3, (Micro(2), L) | (Normal(1), L) => 3,
@ -183,8 +182,8 @@ pub fn max_allowed_errors(version: Version, ec_level: EcLevel) -> QrResult<usize
#[cfg(test)] #[cfg(test)]
mod max_allowed_errors_test { mod max_allowed_errors_test {
use ec::max_allowed_errors; use crate::ec::max_allowed_errors;
use types::{EcLevel, Version}; use crate::types::{EcLevel, Version};
#[test] #[test]
fn test_low_versions() { fn test_low_versions() {
@ -235,7 +234,7 @@ mod max_allowed_errors_test {
//{{{ Precomputed tables for GF(256). //{{{ Precomputed tables for GF(256).
/// `EXP_TABLE` encodes the value of 2<sup>n</sup> in the Galois Field GF(256). /// `EXP_TABLE` encodes the value of 2<sup>n</sup> in the Galois Field GF(256).
static EXP_TABLE: &'static [u8] = b"\ static EXP_TABLE: &[u8] = b"\
\x01\x02\x04\x08\x10\x20\x40\x80\x1d\x3a\x74\xe8\xcd\x87\x13\x26\ \x01\x02\x04\x08\x10\x20\x40\x80\x1d\x3a\x74\xe8\xcd\x87\x13\x26\
\x4c\x98\x2d\x5a\xb4\x75\xea\xc9\x8f\x03\x06\x0c\x18\x30\x60\xc0\ \x4c\x98\x2d\x5a\xb4\x75\xea\xc9\x8f\x03\x06\x0c\x18\x30\x60\xc0\
\x9d\x27\x4e\x9c\x25\x4a\x94\x35\x6a\xd4\xb5\x77\xee\xc1\x9f\x23\ \x9d\x27\x4e\x9c\x25\x4a\x94\x35\x6a\xd4\xb5\x77\xee\xc1\x9f\x23\
@ -254,7 +253,7 @@ static EXP_TABLE: &'static [u8] = b"\
\x2c\x58\xb0\x7d\xfa\xe9\xcf\x83\x1b\x36\x6c\xd8\xad\x47\x8e\x01"; \x2c\x58\xb0\x7d\xfa\xe9\xcf\x83\x1b\x36\x6c\xd8\xad\x47\x8e\x01";
/// `LOG_TABLE` is the inverse function of `EXP_TABLE`. /// `LOG_TABLE` is the inverse function of `EXP_TABLE`.
static LOG_TABLE: &'static [u8] = b"\ static LOG_TABLE: &[u8] = b"\
\xff\x00\x01\x19\x02\x32\x1a\xc6\x03\xdf\x33\xee\x1b\x68\xc7\x4b\ \xff\x00\x01\x19\x02\x32\x1a\xc6\x03\xdf\x33\xee\x1b\x68\xc7\x4b\
\x04\x64\xe0\x0e\x34\x8d\xef\x81\x1c\xc1\x69\xf8\xc8\x08\x4c\x71\ \x04\x64\xe0\x0e\x34\x8d\xef\x81\x1c\xc1\x69\xf8\xc8\x08\x4c\x71\
\x05\x8a\x65\x2f\xe1\x24\x0f\x21\x35\x93\x8e\xda\xf0\x12\x82\x45\ \x05\x8a\x65\x2f\xe1\x24\x0f\x21\x35\x93\x8e\xda\xf0\x12\x82\x45\
@ -281,9 +280,9 @@ static LOG_TABLE: &'static [u8] = b"\
/// 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.
#[cfg_attr(rustfmt, rustfmt_skip)] #[rustfmt::skip]
// ^ this attribute is currently useless, see rust-lang-nursery/rustfmt#1080 and 1298 // ^ this attribute is currently useless, see rust-lang-nursery/rustfmt#1080 and 1298
static GENERATOR_POLYNOMIALS: [&'static [u8]; 70] = [ static GENERATOR_POLYNOMIALS: [&[u8]; 70] = [
b"", b"",
b"\x00", b"\x00",
b"\x19\x01", b"\x19\x01",

View file

@ -4,13 +4,9 @@
//! //!
#![cfg_attr(feature = "image", doc = "```rust")] #![cfg_attr(feature = "image", doc = "```rust")]
#![cfg_attr(not(feature = "image"), doc = "```ignore")] #![cfg_attr(not(feature = "image"), doc = "```ignore")]
//! extern crate qrcode;
//! extern crate image;
//!
//! use qrcode::QrCode; //! use qrcode::QrCode;
//! use image::Luma; //! use image::Luma;
//! //!
//! fn main() {
//! // Encode some data into bits. //! // Encode some data into bits.
//! let code = QrCode::new(b"01234567").unwrap(); //! let code = QrCode::new(b"01234567").unwrap();
//! //!
@ -26,27 +22,16 @@
//! .dark_color('#') //! .dark_color('#')
//! .build(); //! .build();
//! println!("{}", string); //! println!("{}", string);
//! }
//! ``` //! ```
#![cfg_attr(feature = "bench", feature(test, external_doc))] // Unstable libraries #![cfg_attr(feature = "bench", feature(test, external_doc))] // Unstable libraries
#![cfg_attr(feature = "cargo-clippy", deny(warnings, clippy_pedantic))] #![deny(warnings, clippy::pedantic)]
#![cfg_attr( #![allow(
feature = "cargo-clippy", clippy::must_use_candidate, // This is just annoying.
allow( clippy::use_self, // Rust 1.33 doesn't support Self::EnumVariant, let's try again in 1.37.
indexing_slicing,
write_literal, // see https://github.com/rust-lang-nursery/rust-clippy/issues/2976
)
)] )]
#![cfg_attr(feature = "bench", doc(include = "../README.md"))] #![cfg_attr(feature = "bench", doc(include = "../README.md"))]
// ^ make sure we can test our README.md. // ^ make sure we can test our README.md.
#![cfg_attr(feature = "cargo-clippy", allow())]
extern crate checked_int_cast;
#[cfg(feature = "image")]
extern crate image;
#[cfg(feature = "bench")]
extern crate test;
use std::ops::Index; use std::ops::Index;
@ -58,11 +43,11 @@ pub mod optimize;
pub mod render; pub mod render;
pub mod types; pub mod types;
pub use types::{Color, EcLevel, QrResult, Version}; pub use crate::types::{Color, EcLevel, QrResult, Version};
use cast::As; use crate::cast::As;
use crate::render::{Pixel, Renderer};
use checked_int_cast::CheckedIntCast; use checked_int_cast::CheckedIntCast;
use render::{Pixel, Renderer};
/// The encoded QR code symbol. /// The encoded QR code symbol.
#[derive(Clone)] #[derive(Clone)]
@ -224,11 +209,8 @@ impl QrCode {
/// ///
#[cfg_attr(feature = "image", doc = " ```rust")] #[cfg_attr(feature = "image", doc = " ```rust")]
#[cfg_attr(not(feature = "image"), doc = " ```ignore")] #[cfg_attr(not(feature = "image"), doc = " ```ignore")]
/// # extern crate image;
/// # extern crate qrcode;
/// # use qrcode::QrCode; /// # use qrcode::QrCode;
/// # use image::Rgb; /// # use image::Rgb;
/// # fn main() {
/// ///
/// let image = QrCode::new(b"hello").unwrap() /// let image = QrCode::new(b"hello").unwrap()
/// .render() /// .render()
@ -237,8 +219,6 @@ impl QrCode {
/// .quiet_zone(false) // disable quiet zone (white border) /// .quiet_zone(false) // disable quiet zone (white border)
/// .min_dimensions(300, 300) // sets minimum image size /// .min_dimensions(300, 300) // sets minimum image size
/// .build(); /// .build();
///
/// # }
/// ``` /// ```
/// ///
/// Note: the `image` crate itself also provides method to rotate the image, /// Note: the `image` crate itself also provides method to rotate the image,
@ -260,7 +240,7 @@ impl Index<(usize, usize)> for QrCode {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use {EcLevel, QrCode, Version}; use crate::{EcLevel, QrCode, Version};
#[test] #[test]
fn test_annex_i_qr() { fn test_annex_i_qr() {
@ -318,8 +298,8 @@ mod tests {
#[cfg(all(test, feature = "image"))] #[cfg(all(test, feature = "image"))]
mod image_tests { mod image_tests {
use crate::{EcLevel, QrCode, Version};
use image::{load_from_memory, Luma, Rgb}; use image::{load_from_memory, Luma, Rgb};
use {EcLevel, QrCode, Version};
#[test] #[test]
fn test_annex_i_qr_as_image() { fn test_annex_i_qr_as_image() {
@ -347,8 +327,8 @@ mod image_tests {
#[cfg(all(test, feature = "svg"))] #[cfg(all(test, feature = "svg"))]
mod svg_tests { mod svg_tests {
use render::svg::Color as SvgColor; use crate::render::svg::Color as SvgColor;
use {EcLevel, QrCode, Version}; use crate::{EcLevel, QrCode, Version};
#[test] #[test]
fn test_annex_i_qr_as_svg() { fn test_annex_i_qr_as_svg() {

View file

@ -1,9 +1,9 @@
//! Find the optimal data mode sequence to encode a piece of data. //! Find the optimal data mode sequence to encode a piece of data.
use crate::types::{Mode, Version};
use std::slice::Iter; use std::slice::Iter;
use types::{Mode, Version};
#[cfg(feature = "bench")] #[cfg(feature = "bench")]
use test::Bencher; extern crate test;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//{{{ Segment //{{{ Segment
@ -153,8 +153,8 @@ impl<'a> Iterator for Parser<'a> {
#[cfg(test)] #[cfg(test)]
mod parse_tests { mod parse_tests {
use optimize::{Parser, Segment}; use crate::optimize::{Parser, Segment};
use types::Mode; use crate::types::Mode;
fn parse(data: &[u8]) -> Vec<Segment> { fn parse(data: &[u8]) -> Vec<Segment> {
Parser::new(data).collect() Parser::new(data).collect()
@ -249,7 +249,6 @@ mod parse_tests {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//{{{ Optimizer //{{{ Optimizer
#[cfg_attr(feature = "cargo-clippy", allow(stutter))] // rust-lang-nursery/rust-clippy#2212 ಠ_ಠ
pub struct Optimizer<I> { pub struct Optimizer<I> {
parser: I, parser: I,
last_segment: Segment, last_segment: Segment,
@ -337,8 +336,8 @@ pub fn total_encoded_len(segments: &[Segment], version: Version) -> usize {
#[cfg(test)] #[cfg(test)]
mod optimize_tests { mod optimize_tests {
use optimize::{total_encoded_len, Optimizer, Segment}; use crate::optimize::{total_encoded_len, Optimizer, Segment};
use types::{Mode, Version}; use crate::types::{Mode, Version};
fn test_optimization_result(given: Vec<Segment>, expected: Vec<Segment>, version: Version) { fn test_optimization_result(given: Vec<Segment>, expected: Vec<Segment>, version: Version) {
let prev_len = total_encoded_len(&*given, version); let prev_len = total_encoded_len(&*given, version);
@ -455,8 +454,8 @@ mod optimize_tests {
#[cfg(feature = "bench")] #[cfg(feature = "bench")]
#[bench] #[bench]
fn bench_optimize(bencher: &mut Bencher) { fn bench_optimize(bencher: &mut test::Bencher) {
use types::Version; use crate::types::Version;
let data = b"QR\x83R\x81[\x83h\x81i\x83L\x83\x85\x81[\x83A\x81[\x83\x8b\x83R\x81[\x83h\x81j\ let data = b"QR\x83R\x81[\x83h\x81i\x83L\x83\x85\x81[\x83A\x81[\x83\x8b\x83R\x81[\x83h\x81j\
\x82\xc6\x82\xcd\x81A1994\x94N\x82\xc9\x83f\x83\x93\x83\\\x81[\x82\xcc\x8aJ\ \x82\xc6\x82\xcd\x81A1994\x94N\x82\xc9\x83f\x83\x93\x83\\\x81[\x82\xcc\x8aJ\
@ -532,14 +531,14 @@ impl ExclCharSet {
/// Determines which character set a byte is in. /// Determines which character set a byte is in.
fn from_u8(c: u8) -> Self { fn from_u8(c: u8) -> Self {
match c { match c {
0x20 | 0x24 | 0x25 | 0x2a | 0x2b | 0x2d...0x2f | 0x3a => ExclCharSet::Symbol, 0x20 | 0x24 | 0x25 | 0x2a | 0x2b | 0x2d..=0x2f | 0x3a => ExclCharSet::Symbol,
0x30...0x39 => ExclCharSet::Numeric, 0x30..=0x39 => ExclCharSet::Numeric,
0x41...0x5a => ExclCharSet::Alpha, 0x41..=0x5a => ExclCharSet::Alpha,
0x81...0x9f => ExclCharSet::KanjiHi1, 0x81..=0x9f => ExclCharSet::KanjiHi1,
0xe0...0xea => ExclCharSet::KanjiHi2, 0xe0..=0xea => ExclCharSet::KanjiHi2,
0xeb => ExclCharSet::KanjiHi3, 0xeb => ExclCharSet::KanjiHi3,
0x40 | 0x5b...0x7e | 0x80 | 0xa0...0xbf => ExclCharSet::KanjiLo1, 0x40 | 0x5b..=0x7e | 0x80 | 0xa0..=0xbf => ExclCharSet::KanjiLo1,
0xc0...0xdf | 0xec...0xfc => ExclCharSet::KanjiLo2, 0xc0..=0xdf | 0xec..=0xfc => ExclCharSet::KanjiLo2,
_ => ExclCharSet::Byte, _ => ExclCharSet::Byte,
} }
} }

View file

@ -1,7 +1,7 @@
#![cfg(feature="image")] #![cfg(feature="image")]
use render::{Canvas, Pixel}; use crate::render::{Canvas, Pixel};
use types::Color; use crate::types::Color;
use image::{ImageBuffer, Luma, LumaA, Pixel as ImagePixel, Primitive, Rgb, Rgba}; use image::{ImageBuffer, Luma, LumaA, Pixel as ImagePixel, Primitive, Rgb, Rgba};
@ -44,9 +44,9 @@ impl<P: ImagePixel + 'static> Canvas for (P, ImageBuffer<P, Vec<P::Subpixel>>) {
#[cfg(test)] #[cfg(test)]
mod render_tests { mod render_tests {
use crate::render::Renderer;
use crate::types::Color;
use image::{Luma, Rgba}; use image::{Luma, Rgba};
use render::Renderer;
use types::Color;
#[test] #[test]
fn test_render_luma8_unsized() { fn test_render_luma8_unsized() {
@ -70,7 +70,7 @@ mod render_tests {
.module_dimensions(1, 1) .module_dimensions(1, 1)
.build(); .build();
#[cfg_attr(rustfmt, rustfmt_skip)] #[rustfmt::skip]
let expected = [ let expected = [
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 0, 0, 255, 255, 255, 0, 0, 255,
@ -87,7 +87,7 @@ mod render_tests {
.module_dimensions(1, 1) .module_dimensions(1, 1)
.build(); .build();
#[cfg_attr(rustfmt, rustfmt_skip)] #[rustfmt::skip]
let expected: &[u8] = &[ let expected: &[u8] = &[
255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255,
255,255,255,255, 255,255,255,255, 0, 0, 0,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 0, 0, 0,255, 255,255,255,255,
@ -104,7 +104,7 @@ mod render_tests {
.min_dimensions(10, 10) .min_dimensions(10, 10)
.build(); .build();
#[cfg_attr(rustfmt, rustfmt_skip)] #[rustfmt::skip]
let expected: &[u8] = &[ let expected: &[u8] = &[
255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255,
255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255,
@ -133,7 +133,7 @@ mod render_tests {
.max_dimensions(10, 5) .max_dimensions(10, 5)
.build(); .build();
#[cfg_attr(rustfmt, rustfmt_skip)] #[rustfmt::skip]
let expected: &[u8] = &[ let expected: &[u8] = &[
255,255, 255,255, 255,255, 255,255, 255,255, 255,255, 255,255, 255,255,

View file

@ -1,8 +1,8 @@
//! Render a QR code into image. //! Render a QR code into image.
use cast::As; use crate::cast::As;
use crate::types::Color;
use std::cmp::max; use std::cmp::max;
use types::Color;
pub mod image; pub mod image;
pub mod string; pub mod string;
@ -58,7 +58,6 @@ pub trait Canvas: Sized {
/// A QR code renderer. This is a builder type which converts a bool-vector into /// A QR code renderer. This is a builder type which converts a bool-vector into
/// an image. /// an image.
#[cfg_attr(feature = "cargo-clippy", allow(stutter))] // rust-lang-nursery/rust-clippy#2212 ಠ_ಠ
pub struct Renderer<'a, P: Pixel> { pub struct Renderer<'a, P: Pixel> {
content: &'a [Color], content: &'a [Color],
modules_count: u32, // <- we call it `modules_count` here to avoid ambiguity of `width`. modules_count: u32, // <- we call it `modules_count` here to avoid ambiguity of `width`.

View file

@ -1,8 +1,8 @@
//! String rendering support. //! String rendering support.
use cast::As; use crate::cast::As;
use render::{Canvas as RenderCanvas, Pixel}; use crate::render::{Canvas as RenderCanvas, Pixel};
use types::Color; use crate::types::Color;
pub trait Element: Copy { pub trait Element: Copy {
fn default_color(color: Color) -> Self; fn default_color(color: Color) -> Self;
@ -99,7 +99,7 @@ impl<P: Element> RenderCanvas for Canvas<P> {
#[test] #[test]
fn test_render_to_string() { fn test_render_to_string() {
use render::Renderer; use crate::render::Renderer;
let colors = &[Color::Dark, Color::Light, Color::Light, Color::Dark]; let colors = &[Color::Dark, Color::Light, Color::Light, Color::Dark];
let image: String = Renderer::<char>::new(colors, 2, 1).build(); let image: String = Renderer::<char>::new(colors, 2, 1).build();

View file

@ -3,24 +3,20 @@
//! # Example //! # Example
//! //!
//! ``` //! ```
//! extern crate qrcode;
//!
//! use qrcode::QrCode; //! use qrcode::QrCode;
//! use qrcode::render::svg; //! use qrcode::render::svg;
//! //!
//! fn main() {
//! let code = QrCode::new(b"Hello").unwrap(); //! let code = QrCode::new(b"Hello").unwrap();
//! let svg_xml = code.render::<svg::Color>().build(); //! let svg_xml = code.render::<svg::Color>().build();
//! println!("{}", svg_xml); //! println!("{}", svg_xml);
//! }
#![cfg(feature="svg")] #![cfg(feature="svg")]
use std::fmt::Write; use std::fmt::Write;
use std::marker::PhantomData; use std::marker::PhantomData;
use render::{Canvas as RenderCanvas, Pixel}; use crate::render::{Canvas as RenderCanvas, Pixel};
use types::Color as ModuleColor; use crate::types::Color as ModuleColor;
/// An SVG color. /// An SVG color.
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]

View file

@ -1,4 +1,4 @@
use cast::As; use crate::cast::As;
use std::cmp::{Ordering, PartialOrd}; use std::cmp::{Ordering, PartialOrd};
use std::default::Default; use std::default::Default;
use std::fmt::{Display, Error, Formatter}; use std::fmt::{Display, Error, Formatter};
@ -41,11 +41,7 @@ impl Display for QrError {
} }
} }
impl ::std::error::Error for QrError { impl ::std::error::Error for QrError {}
fn description(&self) -> &'static str {
"QrError"
}
}
/// `QrResult` is a convenient alias for a QR code generation result. /// `QrResult` is a convenient alias for a QR code generation result.
pub type QrResult<T> = Result<T, QrError>; pub type QrResult<T> = Result<T, QrError>;
@ -157,10 +153,10 @@ impl Version {
T: PartialEq + Default + Copy, T: PartialEq + Default + Copy,
{ {
match self { match self {
Version::Normal(v @ 1...40) => { Version::Normal(v @ 1..=40) => {
return Ok(table[(v - 1).as_usize()][ec_level as usize]); return Ok(table[(v - 1).as_usize()][ec_level as usize]);
} }
Version::Micro(v @ 1...4) => { Version::Micro(v @ 1..=4) => {
let obj = table[(v + 39).as_usize()][ec_level as usize]; let obj = table[(v + 39).as_usize()][ec_level as usize];
if obj != T::default() { if obj != T::default() {
return Ok(obj); return Ok(obj);
@ -228,12 +224,12 @@ impl Mode {
Mode::Kanji => a, Mode::Kanji => a,
} }
} }
Version::Normal(1...9) => match self { Version::Normal(1..=9) => match self {
Mode::Numeric => 10, Mode::Numeric => 10,
Mode::Alphanumeric => 9, Mode::Alphanumeric => 9,
Mode::Byte | Mode::Kanji => 8, Mode::Byte | Mode::Kanji => 8,
}, },
Version::Normal(10...26) => match self { Version::Normal(10..=26) => match self {
Mode::Numeric => 12, Mode::Numeric => 12,
Mode::Alphanumeric => 11, Mode::Alphanumeric => 11,
Mode::Byte => 16, Mode::Byte => 16,
@ -305,7 +301,7 @@ impl PartialOrd for Mode {
#[cfg(test)] #[cfg(test)]
mod mode_tests { mod mode_tests {
use types::Mode::{Alphanumeric, Byte, Kanji, Numeric}; use crate::types::Mode::{Alphanumeric, Byte, Kanji, Numeric};
#[test] #[test]
fn test_mode_order() { fn test_mode_order() {