Change some long method signatures to use where. Adapt lifetime elision.

And removed a huge unused code segment.
This commit is contained in:
kennytm 2014-09-12 17:18:04 +08:00
parent 84f1fed203
commit eacaaab721
5 changed files with 13 additions and 399 deletions

View file

@ -140,7 +140,7 @@ impl Canvas {
/// Obtains a mutable module at the given coordinates. For convenience, /// Obtains a mutable module at the given coordinates. For convenience,
/// negative coordinates will wrap around. /// negative coordinates will wrap around.
pub fn get_mut<'a>(&'a mut self, x: i16, y: i16) -> &'a mut Module { pub fn get_mut(&mut self, x: i16, y: i16) -> &mut Module {
let index = self.coords_to_index(x, y); let index = self.coords_to_index(x, y);
self.modules.get_mut(index) self.modules.get_mut(index)
} }
@ -959,7 +959,7 @@ impl DataModuleIter {
} }
} }
impl<'a> Iterator<(i16, i16)> for DataModuleIter { impl Iterator<(i16, i16)> for DataModuleIter {
fn next(&mut self) -> Option<(i16, i16)> { fn next(&mut self) -> Option<(i16, i16)> {
let adjusted_ref_col = if self.x <= self.timing_pattern_column { let adjusted_ref_col = if self.x <= self.timing_pattern_column {
self.x + 1 self.x + 1
@ -1163,9 +1163,9 @@ mod data_iter_tests {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//{{{ Data placement //{{{ Data placement
fn draw_codewords<'a, I: Iterator<&'a mut Module>>(codewords: &[u8], fn draw_codewords<'a, I>(codewords: &[u8], is_half_codeword_at_end: bool, modules: &mut I)
is_half_codeword_at_end: bool, where I: Iterator<&'a mut Module>
modules: &mut I) { {
let length = codewords.len(); let length = codewords.len();
let last_word = if is_half_codeword_at_end { length-1 } else { length }; let last_word = if is_half_codeword_at_end { length-1 } else { length };
for (i, b) in codewords.iter().enumerate() { for (i, b) in codewords.iter().enumerate() {
@ -1737,390 +1737,3 @@ impl Canvas {
//}}} //}}}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/*
static ALL_PATTERNS: [MaskPattern, ..8] = [Pattern0, Pattern1, Pattern2, Pattern3, Pattern4, Pattern5, Pattern6, Pattern7];
fn apply_mask(canvas: &mut Canvas, ec_level: ErrorCorrectionLevel, pattern: MaskPattern) {
draw_format_info_patterns(canvas, ec_level, pattern);
let width = canvas.width();
for y in range(0, width) {
for x in range(0, width) {
if should_mask(pattern, x, y) {
let mut color = canvas.index_mut(&(x, y));
*color = match *color {
DataWhite => DataBlack,
DataBlack => DataWhite,
other => other,
};
}
}
}
}
fn is_black(color: ModuleState) -> bool {
match color {
Black | DataBlack => true,
Empty | White | DataWhite => false,
}
}
fn evaluate_adjacent_penalty(canvas: &Canvas, is_horizontal: bool) -> uint {
let mut score = 0u;
let width = canvas.width();
let mut prev_is_black = false;
let mut consec_length = 1u;
for x in range(0, width) {
for y in range(0, width) {
let coords = if is_horizontal { (y, x) } else { (x, y) };
let cur_is_black = is_black((*canvas)[coords]);
if y != 0 && prev_is_black == cur_is_black {
consec_length += 1;
} else {
if consec_length >= 5 {
score += consec_length - 2;
}
consec_length = 1;
}
prev_is_black = cur_is_black;
}
}
if consec_length >= 5 {
score += consec_length - 2;
}
score
}
fn evaluate_block_penalty(canvas: &Canvas) -> uint {
let mut score = 0u;
let width = canvas.width();
for x in range(0, width-1) {
for y in range(0, width-1) {
let color0 = is_black((*canvas)[(x, y)]);
let color1 = is_black((*canvas)[(x+1, y)]);
let color2 = is_black((*canvas)[(x, y+1)]);
let color3 = is_black((*canvas)[(x+1, y+1)]);
if color0 == color1 && color1 == color2 && color2 == color3 {
score += 3;
}
}
}
score
}
fn evaluate_finder_penalty(canvas: &Canvas, is_horizontal: bool) -> uint {
use std::iter::order::eq;
let mut score = 0u;
let width = canvas.width();
for x in range(0, width) {
for y in range(0, width-6) {
let colors = range(y, y+7)
.map(|r| if is_horizontal { (r, x) } else { (x, r) })
.map(|coords| is_black((*canvas)[coords]));
if eq(colors, [true, false, true, true, true, false, true].iter().map(|&b| b)) {
score += 40;
}
}
}
score
}
fn evaluate_proportion_penalty(canvas: &Canvas) -> uint {
let black_modules = canvas.modules.iter().filter(|&&m| is_black(m)).count();
let width = canvas.width;
let total_modules = width * width;
let ratio = black_modules * 200 / total_modules;
if ratio >= 100 { ratio - 100 } else { 100 - ratio }
}
fn apply_best_mask(canvas: &Canvas, ec_level: ErrorCorrectionLevel) -> Canvas {
ALL_PATTERNS.iter().map(|&pattern| {
let mut canvas_copy = canvas.clone();
apply_mask(&mut canvas_copy, ec_level, pattern);
canvas_copy
}).min_by(|c| {
use std::io::stdio::stdout;
let s1 = evaluate_adjacent_penalty(c, true);
let s2 = evaluate_adjacent_penalty(c, false);
let s3 = evaluate_block_penalty(c);
let s4 = evaluate_finder_penalty(c, true);
let s5 = evaluate_finder_penalty(c, false);
let s6 = evaluate_proportion_penalty(c);
stdout().write_line(format!("{} + {} + {} + {} + {} + {}", s1, s2, s3, s4, s5, s6).as_slice());
s1 + s2 + s3 + s4 + s5 + s6
}).unwrap()
}
#[cfg(test)]
mod tests {
use collections::{bitv, Bitv};
use canvas::{Canvas, Empty, Black, White, DataBlack, DataWhite,
draw_finder_patterns, draw_alignment_patterns,
draw_timing_patterns, draw_version_info_patterns,
draw_format_info_patterns, Pattern4, Pattern0, apply_mask,
draw_all_functional_patterns, evaluate_adjacent_penalty,
evaluate_block_penalty, evaluate_finder_penalty,
evaluate_proportion_penalty, apply_best_mask};
use ec::{L, Q};
#[test]
fn test_draw_format_info_patterns() {
let mut c = Canvas::new(1);
draw_format_info_patterns(&mut c, L, Pattern4);
assert_eq!(c.to_debug_str().as_slice(), "\n\
????????#????????????\n\
????????#????????????\n\
????????#????????????\n\
????????#????????????\n\
???????? ????????????\n\
????????#????????????\n\
?????????????????????\n\
???????? ????????????\n\
## ##? ???? # ####\n\
?????????????????????\n\
?????????????????????\n\
?????????????????????\n\
?????????????????????\n\
?????????????????????\n\
???????? ????????????\n\
????????#????????????\n\
????????#????????????\n\
???????? ????????????\n\
???????? ????????????\n\
????????#????????????\n\
????????#????????????");
}
#[test]
fn test_draw_all_functional_patterns() {
let mut c = Canvas::new(2);
draw_all_functional_patterns(&mut c);
assert_eq!(c.to_debug_str().as_slice(), "\n\
####### ???????? #######\n\
# # ???????? # #\n\
# ### # ???????? # ### #\n\
# ### # ???????? # ### #\n\
# ### # ???????? # ### #\n\
# # ???????? # #\n\
####### # # # # # #######\n\
\x20 ???????? \n\
\x20 # ???????? \n\
?????? ??????????????????\n\
??????#??????????????????\n\
?????? ??????????????????\n\
??????#??????????????????\n\
?????? ??????????????????\n\
??????#??????????????????\n\
?????? ??????????????????\n\
??????#?????????#####????\n\
\x20 #???????# #????\n\
####### ???????# # #????\n\
# # ???????# #????\n\
# ### # ???????#####????\n\
# ### # ????????????????\n\
# ### # ????????????????\n\
# # ????????????????\n\
####### ????????????????");
}
#[test]
fn test_empty_modules_increase() {
use canvas::DataModuleIter;
let res: Vec<uint> = DataModuleIter::new(17).collect();
assert_eq!(res, vec![
0,17,1,18,2,19,3,20,4,21,5,22,6,23,7,24,8,25,9,26,10,27,11,28,12,29,
13,30,14,31,15,32,16,33,50,67,49,66,48,65,47,64,46,63,45,62,44,61,
43,60,42,59,41,58,40,57,39,56,38,55,37,54,36,53,35,52,34,51,68,85,
69,86,70,87,71,88,72,89,73,90,74,91,75,92,76,93,77,94,78,95,79,96,
80,97,81,98,82,99,83,100,84,101,118,135,117,134,116,133,115,132,114,
131,113,130,112,129,111,128,110,127,109,126,108,125,107,124,106,123,
105,122,104,121,103,120,102,119,136,153,137,154,138,155,139,156,140,
157,141,158,142,159,143,160,144,161,145,162,146,163,147,164,148,165,
149,166,150,167,151,168,152,169,203,220,202,219,201,218,200,217,199,
216,198,215,197,214,196,213,195,212,194,211,193,210,192,209,191,208,
190,207,189,206,188,205,187,204,221,238,222,239,223,240,224,241,225,
242,226,243,227,244,228,245,229,246,230,247,231,248,232,249,233,250,
234,251,235,252,236,253,237,254,271,288,270,287,269,286,268,285,267,
284,266,283,265,282,264,281,263,280,262,279,261,278,260,277,259,276,
258,275,257,274,256,273,255,272
]);
}
#[test]
fn test_fill_in_modules() {
let mut c = Canvas::new(2);
draw_all_functional_patterns(&mut c);
c.fill_data_bits([true, false, false].iter().cycle().map(|&b| b));
assert_eq!(c.to_debug_str().as_slice(), "\n\
####### ..*...*. #######\n\
# # .*.*.*.* # #\n\
# ### # *...*... # ### #\n\
# ### # ..*...*. # ### #\n\
# ### # .*.*.*.* # ### #\n\
# # *...*... # #\n\
####### # # # # # #######\n\
\x20 ..*...*. \n\
\x20 # .*.*.*.* \n\
..*.*. .**...*...*..**..*\n\
.*.*..#....*...*.........\n\
*....* *..*.*.*.*.**..**.\n\
..*.*.#.**...*...*..**..*\n\
.*.*.. ....*...*.........\n\
*....*#*..*.*.*.*.**..**.\n\
..*.*. .**...*...*..**..*\n\
.*.*..#....*...*#####....\n\
\x20 #.*.*.*.# #.**.\n\
####### *...*..# # #*..*\n\
# # ..*...*# #....\n\
# ### # .*.*.*.#####.**.\n\
# ### # *...*..*....*..*\n\
# ### # ..*......**.....\n\
# # .*.*.**.*..*.**.\n\
####### *...*..*....*..*");
}
#[test]
fn test_apply_mask() {
let mut c = Canvas::new(1);
draw_all_functional_patterns(&mut c);
c.fill_data_bits(Bitv::new().iter());
apply_mask(&mut c, L, Pattern0);
assert_eq!(c.to_debug_str().as_slice(), "\n\
####### .*.* #######\n\
# # *.*. # #\n\
# ### # #.*.* # ### #\n\
# ### # *.*. # ### #\n\
# ### # .*.* # ### #\n\
# # *.*. # #\n\
####### # # # #######\n\
\x20 #*.*. \n\
### #####.*.*## # \n\
.*.*.* *.*.*.*.*.*.*.\n\
*.*.*.#.*.*.*.*.*.*.*\n\
.*.*.* *.*.*.*.*.*.*.\n\
*.*.*.#.*.*.*.*.*.*.*\n\
\x20 #*.*.*.*.*.*.\n\
####### #.*.*.*.*.*.*\n\
# # #*.*.*.*.*.*.\n\
# ### # #.*.*.*.*.*.*\n\
# ### # *.*.*.*.*.*.\n\
# ### # #.*.*.*.*.*.*\n\
# # #*.*.*.*.*.*.\n\
####### #.*.*.*.*.*.*");
}
fn prepare_canvas_for_penalty_scoring() -> Canvas {
let mut c = Canvas::new(1);
let data = bitv::from_bytes(
b"\x20\x5b\x0b\x78\xd1\x72\xdc\x4d\x43\x40\xec\x11\x00\xa8\x48\x16\x52\xd9\x36\x9c\x00\x2e\x0f\xb4\x7a\x10");
draw_all_functional_patterns(&mut c);
c.fill_data_bits(data.iter());
apply_mask(&mut c, Q, Pattern0);
c
}
#[test]
fn check_penalty_canvas() {
let c = prepare_canvas_for_penalty_scoring();
assert_eq!(c.to_debug_str().as_slice(), "\n\
####### #*... #######\n\
# # #..*. # #\n\
# ### # #..** # ### #\n\
# ### # #.... # ### #\n\
# ### # #.*.. # ### #\n\
# # .*.. # #\n\
####### # # # #######\n\
\x20 #.... \n\
\x20## # ## ...* # #####\n\
.*.... .****....*...*\n\
..**.*#*.**...*.**...\n\
.**.** *..**.*.*.***.\n\
*...*.#.*.***.***.*.*\n\
\x20 #*.*..*...*.*\n\
####### #.*....*.**..\n\
# # *.**.**.*...\n\
# ### # #.*...*******\n\
# ### # *.*.*.*...*.\n\
# ### # #...****.*..*\n\
# # #.**.*...*.**\n\
####### ...****....*");
}
#[test]
fn test_penalty_score_adjacent() {
let c = prepare_canvas_for_penalty_scoring();
assert_eq!(evaluate_adjacent_penalty(&c, true), 88);
assert_eq!(evaluate_adjacent_penalty(&c, false), 92);
}
#[test]
fn test_penalty_score_block() {
let c = prepare_canvas_for_penalty_scoring();
assert_eq!(evaluate_block_penalty(&c), 90);
}
#[test]
fn test_penalty_score_finder() {
let c = prepare_canvas_for_penalty_scoring();
assert_eq!(evaluate_finder_penalty(&c, true), 480);
assert_eq!(evaluate_finder_penalty(&c, false), 440);
}
#[test]
fn test_penalty_score_proportion() {
let c = prepare_canvas_for_penalty_scoring();
assert_eq!(evaluate_proportion_penalty(&c), 2);
}
#[test]
fn test_best_mask() {
let mut c = Canvas::new(1);
let data = bitv::from_bytes(b"\x20\x5b\x0b\x78\xd1\x72\xdc\x4d\x43\x40\xec\x11\x00\xa8\x48\x16\x52\xd9\x36\x9c\x00\x2e\x0f\xb4\x7a\x10");
draw_all_functional_patterns(&mut c);
c.fill_data_bits(data.iter());
let c2 = apply_best_mask(&c, Q);
assert_eq!(c2.to_debug_str().as_slice(), "\n\
####### #*... #######\n\
# # #..*. # #\n\
# ### # #..** # ### #\n\
# ### # #.... # ### #\n\
# ### # #.*.. # ### #\n\
# # .*.. # #\n\
####### # # # #######\n\
\x20 #.... \n\
\x20## # ## ...* # #####\n\
.*.... .****....*...*\n\
..**.*#*.**...*.**...\n\
.**.** *..**.*.*.***.\n\
*...*.#.*.***.***.*.*\n\
\x20 #*.*..*...*.*\n\
####### #.*....*.**..\n\
# # *.**.**.*...\n\
# ### # #.*...*******\n\
# ### # *.*.*.*...*.\n\
# ### # #...****.*..*\n\
# # #.**.*...*.**\n\
####### ...****....*");
}
}
*/

View file

@ -102,8 +102,9 @@ impl<'a, T: Copy> InterleaveSupport<T> for &'a [T] {
/// ///
/// The longest slice must be at the last of `blocks`, and `blocks` must not be /// The longest slice must be at the last of `blocks`, and `blocks` must not be
/// empty. /// empty.
fn interleave<'a, 'b, T: Copy, fn interleave<T: Copy, V>(blocks: &Vec<V>) -> Vec<T>
V: InterleaveSupport<T> + Collection>(blocks: &Vec<V>) -> Vec<T> { where V: InterleaveSupport<T> + Collection
{
let last_block_len = blocks.last().unwrap().len(); let last_block_len = blocks.last().unwrap().len();
let mut res = Vec::with_capacity(last_block_len * blocks.len()); let mut res = Vec::with_capacity(last_block_len * blocks.len());
for i in range(0, last_block_len) { for i in range(0, last_block_len) {

View file

@ -165,7 +165,7 @@ impl QrCode {
} }
impl Index<(uint, uint), bool> for QrCode { impl Index<(uint, uint), bool> for QrCode {
fn index<'a>(&'a self, &(x, y): &(uint, uint)) -> &'a bool { fn index(&self, &(x, y): &(uint, uint)) -> &bool {
let index = y * self.width + x; let index = y * self.width + x;
self.content.index(&index) self.content.index(&index)
} }

View file

@ -98,7 +98,7 @@ impl<'a> Parser<'a> {
/// Segment { mode: Numeric, begin: 3, end: 6 }, /// Segment { mode: Numeric, begin: 3, end: 6 },
/// Segment { mode: Byte, begin: 6, end: 10 }]); /// Segment { mode: Byte, begin: 6, end: 10 }]);
/// ///
pub fn new(data: &'a [u8]) -> Parser { pub fn new(data: &[u8]) -> Parser {
Parser { Parser {
ecs_iter: EcsIter { base: data.iter(), index: 0, ended: false }, ecs_iter: EcsIter { base: data.iter(), index: 0, ended: false },
state: SInit, state: SInit,

View file

@ -95,9 +95,9 @@ impl Version {
/// ///
/// If the entry compares equal to the default value of T, this method /// If the entry compares equal to the default value of T, this method
/// returns `Err(InvalidVersion)`. /// returns `Err(InvalidVersion)`.
pub fn fetch<T: PartialEq + Default + Copy>(&self, pub fn fetch<T>(&self, ec_level: ErrorCorrectionLevel, table: &[[T, ..4]]) -> QrResult<T>
ec_level: ErrorCorrectionLevel, where T: PartialEq + Default + Copy
table: &[[T, ..4]]) -> QrResult<T> { {
match *self { match *self {
Version(v @ 1..40) => Ok(table[v as uint - 1][ec_level as uint]), Version(v @ 1..40) => Ok(table[v as uint - 1][ec_level as uint]),
MicroVersion(v @ 1..4) => { MicroVersion(v @ 1..4) => {