Go hog wild

This commit is contained in:
qm3ster 2022-03-01 23:20:24 +02:00
parent 1d82f60465
commit ea346f1142
9 changed files with 34 additions and 31 deletions

View file

@ -2,8 +2,8 @@
name = "qrcode" name = "qrcode"
description = "QR code encoder in Rust" description = "QR code encoder in Rust"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.12.0" version = "0.13.0"
edition = "2018" edition = "2021"
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

@ -101,7 +101,7 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
fn to_debug_str(&self) -> String { fn to_debug_str(&self) -> String {
let width = self.width; let width = self.width;
let mut res = String::with_capacity((width * (width + 1)) as usize); let mut res = String::with_capacity((width * (width + 1)).as_usize());
for y in 0..width { for y in 0..width {
res.push('\n'); res.push('\n');
for x in 0..width { for x in 0..width {
@ -1765,7 +1765,7 @@ impl Canvas {
Box::new(|k| self.get(i, k).into()) Box::new(|k| self.get(i, k).into())
}; };
if (j..(j + 7)).map(&*get).ne(PATTERN.iter().cloned()) { if (j..(j + 7)).map(&*get).ne(PATTERN.iter().copied()) {
continue; continue;
} }
@ -1829,6 +1829,7 @@ impl Canvas {
#[cfg(test)] #[cfg(test)]
mod penalty_tests { mod penalty_tests {
use crate::canvas::{Canvas, MaskPattern}; use crate::canvas::{Canvas, MaskPattern};
use crate::cast::As;
use crate::types::{Color, EcLevel, Version}; use crate::types::{Color, EcLevel, Version};
fn create_test_canvas() -> Canvas { fn create_test_canvas() -> Canvas {
@ -1941,8 +1942,8 @@ mod penalty_tests {
let mut c = Canvas::new(Version::Micro(4), EcLevel::Q); let mut c = Canvas::new(Version::Micro(4), EcLevel::Q);
for i in 0_i16..17 { for i in 0_i16..17 {
c.put(i, -1, HORIZONTAL_SIDE[i as usize]); c.put(i, -1, HORIZONTAL_SIDE[i.as_usize()]);
c.put(-1, i, VERTICAL_SIDE[i as usize]); c.put(-1, i, VERTICAL_SIDE[i.as_usize()]);
} }
assert_eq!(c.compute_light_side_penalty_score(), 168); assert_eq!(c.compute_light_side_penalty_score(), 168);
@ -1970,6 +1971,7 @@ static ALL_PATTERNS_MICRO_QR: [MaskPattern; 4] =
impl Canvas { impl Canvas {
/// Construct a new canvas and apply the best masking that gives the lowest /// Construct a new canvas and apply the best masking that gives the lowest
/// penalty score. /// penalty score.
#[must_use]
pub fn apply_best_mask(&self) -> Self { pub fn apply_best_mask(&self) -> Self {
match self.version { match self.version {
Version::Normal(_) => ALL_PATTERNS_QR.iter(), Version::Normal(_) => ALL_PATTERNS_QR.iter(),

View file

@ -30,7 +30,6 @@
#![deny(warnings, clippy::pedantic)] #![deny(warnings, clippy::pedantic)]
#![allow( #![allow(
clippy::must_use_candidate, // This is just annoying. clippy::must_use_candidate, // This is just annoying.
clippy::use_self, // Rust 1.33 doesn't support Self::EnumVariant, let's try again in 1.37.
)] )]
#![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.

View file

@ -1,3 +1,4 @@
#![allow(clippy::unicode_not_nfc)]
//! 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 crate::types::{Mode, Version};
use std::slice::Iter; use std::slice::Iter;
@ -339,7 +340,7 @@ mod optimize_tests {
use crate::optimize::{total_encoded_len, Optimizer, Segment}; use crate::optimize::{total_encoded_len, Optimizer, Segment};
use crate::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: &[Segment], expected: &[Segment], version: Version) {
let prev_len = total_encoded_len(&*given, version); let prev_len = total_encoded_len(&*given, version);
let opt_segs = Optimizer::new(given.iter().copied(), version).collect::<Vec<_>>(); let opt_segs = Optimizer::new(given.iter().copied(), version).collect::<Vec<_>>();
let new_len = total_encoded_len(&*opt_segs, version); let new_len = total_encoded_len(&*opt_segs, version);
@ -358,15 +359,12 @@ mod optimize_tests {
#[test] #[test]
fn test_example_1() { fn test_example_1() {
test_optimization_result( test_optimization_result(
vec![ &[
Segment { mode: Mode::Alphanumeric, begin: 0, end: 3 }, Segment { mode: Mode::Alphanumeric, begin: 0, end: 3 },
Segment { mode: Mode::Numeric, begin: 3, end: 6 }, Segment { mode: Mode::Numeric, begin: 3, end: 6 },
Segment { mode: Mode::Byte, begin: 6, end: 10 }, Segment { mode: Mode::Byte, begin: 6, end: 10 },
], ],
vec![ &[Segment { mode: Mode::Alphanumeric, begin: 0, end: 6 }, Segment { mode: Mode::Byte, begin: 6, end: 10 }],
Segment { mode: Mode::Alphanumeric, begin: 0, end: 6 },
Segment { mode: Mode::Byte, begin: 6, end: 10 },
],
Version::Normal(1), Version::Normal(1),
); );
} }
@ -374,14 +372,14 @@ mod optimize_tests {
#[test] #[test]
fn test_example_2() { fn test_example_2() {
test_optimization_result( test_optimization_result(
vec![ &[
Segment { mode: Mode::Numeric, begin: 0, end: 29 }, Segment { mode: Mode::Numeric, begin: 0, end: 29 },
Segment { mode: Mode::Alphanumeric, begin: 29, end: 30 }, Segment { mode: Mode::Alphanumeric, begin: 29, end: 30 },
Segment { mode: Mode::Numeric, begin: 30, end: 32 }, Segment { mode: Mode::Numeric, begin: 30, end: 32 },
Segment { mode: Mode::Alphanumeric, begin: 32, end: 35 }, Segment { mode: Mode::Alphanumeric, begin: 32, end: 35 },
Segment { mode: Mode::Numeric, begin: 35, end: 38 }, Segment { mode: Mode::Numeric, begin: 35, end: 38 },
], ],
vec![ &[
Segment { mode: Mode::Numeric, begin: 0, end: 29 }, Segment { mode: Mode::Numeric, begin: 0, end: 29 },
Segment { mode: Mode::Alphanumeric, begin: 29, end: 38 }, Segment { mode: Mode::Alphanumeric, begin: 29, end: 38 },
], ],
@ -392,13 +390,13 @@ mod optimize_tests {
#[test] #[test]
fn test_example_3() { fn test_example_3() {
test_optimization_result( test_optimization_result(
vec![ &[
Segment { mode: Mode::Kanji, begin: 0, end: 4 }, Segment { mode: Mode::Kanji, begin: 0, end: 4 },
Segment { mode: Mode::Alphanumeric, begin: 4, end: 5 }, Segment { mode: Mode::Alphanumeric, begin: 4, end: 5 },
Segment { mode: Mode::Byte, begin: 5, end: 6 }, Segment { mode: Mode::Byte, begin: 5, end: 6 },
Segment { mode: Mode::Kanji, begin: 6, end: 8 }, Segment { mode: Mode::Kanji, begin: 6, end: 8 },
], ],
vec![Segment { mode: Mode::Byte, begin: 0, end: 8 }], &[Segment { mode: Mode::Byte, begin: 0, end: 8 }],
Version::Normal(1), Version::Normal(1),
); );
} }
@ -406,8 +404,8 @@ mod optimize_tests {
#[test] #[test]
fn test_example_4() { fn test_example_4() {
test_optimization_result( test_optimization_result(
vec![Segment { mode: Mode::Kanji, begin: 0, end: 10 }, Segment { mode: Mode::Byte, begin: 10, end: 11 }], &[Segment { mode: Mode::Kanji, begin: 0, end: 10 }, Segment { mode: Mode::Byte, begin: 10, end: 11 }],
vec![Segment { mode: Mode::Kanji, begin: 0, end: 10 }, Segment { mode: Mode::Byte, begin: 10, end: 11 }], &[Segment { mode: Mode::Kanji, begin: 0, end: 10 }, Segment { mode: Mode::Byte, begin: 10, end: 11 }],
Version::Normal(1), Version::Normal(1),
); );
} }
@ -415,11 +413,11 @@ mod optimize_tests {
#[test] #[test]
fn test_annex_j_guideline_1a() { fn test_annex_j_guideline_1a() {
test_optimization_result( test_optimization_result(
vec![ &[
Segment { mode: Mode::Numeric, begin: 0, end: 3 }, Segment { mode: Mode::Numeric, begin: 0, end: 3 },
Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 }, Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 },
], ],
vec![ &[
Segment { mode: Mode::Numeric, begin: 0, end: 3 }, Segment { mode: Mode::Numeric, begin: 0, end: 3 },
Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 }, Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 },
], ],
@ -430,11 +428,11 @@ mod optimize_tests {
#[test] #[test]
fn test_annex_j_guideline_1b() { fn test_annex_j_guideline_1b() {
test_optimization_result( test_optimization_result(
vec![ &[
Segment { mode: Mode::Numeric, begin: 0, end: 2 }, Segment { mode: Mode::Numeric, begin: 0, end: 2 },
Segment { mode: Mode::Alphanumeric, begin: 2, end: 4 }, Segment { mode: Mode::Alphanumeric, begin: 2, end: 4 },
], ],
vec![Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }], &[Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }],
Version::Micro(2), Version::Micro(2),
); );
} }
@ -442,11 +440,11 @@ mod optimize_tests {
#[test] #[test]
fn test_annex_j_guideline_1c() { fn test_annex_j_guideline_1c() {
test_optimization_result( test_optimization_result(
vec![ &[
Segment { mode: Mode::Numeric, begin: 0, end: 3 }, Segment { mode: Mode::Numeric, begin: 0, end: 3 },
Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 }, Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 },
], ],
vec![Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }], &[Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }],
Version::Micro(3), Version::Micro(3),
); );
} }

View file

@ -72,6 +72,9 @@ pub struct Renderer<'a, P: Pixel> {
impl<'a, P: Pixel> Renderer<'a, P> { impl<'a, P: Pixel> Renderer<'a, P> {
/// Creates a new renderer. /// Creates a new renderer.
///
/// # Panics
/// panics if content is not `modules_count` squared big
pub fn new(content: &'a [Color], modules_count: usize, quiet_zone: u32) -> Renderer<'a, P> { pub fn new(content: &'a [Color], modules_count: usize, quiet_zone: u32) -> Renderer<'a, P> {
assert!(modules_count * modules_count == content.len()); assert!(modules_count * modules_count == content.len());
Renderer { Renderer {

View file

@ -20,7 +20,7 @@ impl Element for char {
} }
fn append_to_string(self, string: &mut String) { fn append_to_string(self, string: &mut String) {
string.push(self) string.push(self);
} }
} }
@ -34,7 +34,7 @@ impl<'a> Element for &'a str {
} }
fn append_to_string(self, string: &mut String) { fn append_to_string(self, string: &mut String) {
string.push_str(self) string.push_str(self);
} }
} }

View file

@ -10,7 +10,7 @@
//! 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;
@ -62,7 +62,7 @@ impl<'a> RenderCanvas for Canvas<'a> {
} }
fn draw_dark_pixel(&mut self, x: u32, y: u32) { fn draw_dark_pixel(&mut self, x: u32, y: u32) {
self.draw_dark_rect(x, y, 1, 1) self.draw_dark_rect(x, y, 1, 1);
} }
fn draw_dark_rect(&mut self, left: u32, top: u32, width: u32, height: u32) { fn draw_dark_rect(&mut self, left: u32, top: u32, width: u32, height: u32) {

View file

@ -111,7 +111,7 @@ fn integration_render_utf8_1x2() {
+ " ▀███▄ ▀▀ █ ██ \n" + " ▀███▄ ▀▀ █ ██ \n"
+ " ▀▀▀ ▀ ▀▀ ▀ ▀ \n" + " ▀▀▀ ▀ ▀▀ ▀ ▀ \n"
+ " " + " "
) );
} }
#[test] #[test]

View file

@ -173,7 +173,7 @@ impl Version {
pub fn mode_bits_count(self) -> usize { pub fn mode_bits_count(self) -> usize {
match self { match self {
Version::Micro(a) => (a - 1).as_usize(), Version::Micro(a) => (a - 1).as_usize(),
_ => 4, Version::Normal(_) => 4,
} }
} }
@ -273,6 +273,7 @@ impl Mode {
/// assert!(a <= c); /// assert!(a <= c);
/// assert!(b <= c); /// assert!(b <= c);
/// ///
#[must_use]
pub fn max(self, other: Self) -> Self { pub fn max(self, other: Self) -> Self {
match self.partial_cmp(&other) { match self.partial_cmp(&other) {
Some(Ordering::Less | Ordering::Equal) => other, Some(Ordering::Less | Ordering::Equal) => other,