Merge pull request #40 from kennytm/ed2018
Use 2018 edition (MSRV = 1.33.0).
This commit is contained in:
commit
bcecedf489
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
12
README.md
12
README.md
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
extern crate image;
|
|
||||||
extern crate qrcode;
|
|
||||||
|
|
||||||
use image::Luma;
|
use image::Luma;
|
||||||
use qrcode::QrCode;
|
use qrcode::QrCode;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
extern crate qrcode;
|
|
||||||
use qrcode::QrCode;
|
use qrcode::QrCode;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
extern crate qrcode;
|
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
|
68
src/bits.rs
68
src/bits.rs
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
25
src/ec.rs
25
src/ec.rs
|
@ -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",
|
||||||
|
|
42
src/lib.rs
42
src/lib.rs
|
@ -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() {
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
|
|
|
@ -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`.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
18
src/types.rs
18
src/types.rs
|
@ -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() {
|
||||||
|
|
Loading…
Reference in a new issue