Ако искаме да поправяме правопис със spell checker-а от домашно 3, ще ни трябва нещо, което да цикли по думите на някакъв текст и да ги замества с вероятните fix-ове. Това е може би малко смело, предвид че може spell checker-а да греши, но все пак ще пробваме да имплементираме нещо такова.
Първо, искаме да итерираме по думи:
/// Забележете, че полето `source` не е публично, но сме го сложили, за да се компилира празния код
/// -- итератора е свързан по lifetime с низа, с който се вика.
///
/// Свободни сте да добавите още полета, ако ви трябват (вероятно ще ви трябват).
///
pub struct WordIterator<'a> {
source: &'a str,
// ...
}
impl<'a> WordIterator<'a> {
pub fn new(source: &'a str) -> Self {
unimplemented!()
}
}
/// Този тип описва какъв вид текст връща итератора. Детайли по-долу.
///
#[derive(Debug, PartialEq)]
pub enum SegmentType {
Word,
NonWord,
}
/// Итератора ще връща двойка низ и типа на този низ -- дали е дума или не-дума. Целта е да
/// итерираме по целия низ, на части.
///
/// Символ, който е част от "дума" e всеки, за което `char::is_alphabetic` връща истина, плюс
/// апостроф (`'`) и тиренце (`-`). Всичко останало е не-дума.
///
impl<'a> Iterator for WordIterator<'a> {
type Item = (&'a str, SegmentType);
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}
Примерно използване на итератора може да изглежда така:
След като имаме този итератор, би трябвало да е сравнително лесно да имплементираме следната функция:
/// Итерираме през входа `input` и заместваме всички думи с резултата, който получаваме от
/// извикването на функцията. Частите, които са не-думи ги добавяме в крайния низ непромемени.
///
pub fn replace_words<F: Fn(&str) -> String>(input: &str, f: F) -> String {
unimplemented!()
}
Примерно извикване на тази функция:
let input = "foo, bar";
let bracketed = replace_words(input, |w| format!("({})", w));
assert_eq!(bracketed, "(foo), (bar)");
Compiling solution v0.1.0 (/tmp/d20200116-2173579-1a60f68/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.83s
Running target/debug/deps/solution-a73e64ec87929bd0
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... ok
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... ok
test solution_test::test_word_iterator_special_characters ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20200116-2173579-tvrugw/solution)
Finished test [unoptimized + debuginfo] target(s) in 2.36s
Running target/debug/deps/solution-a73e64ec87929bd0
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... ok
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... ok
test solution_test::test_word_iterator_special_characters ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20200116-2173579-9cm2qn/solution)
warning: unused import: `std::ptr::replace`
--> src/lib.rs:72:9
|
72 | use std::ptr::replace;
| ^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
Finished test [unoptimized + debuginfo] target(s) in 2.60s
Running target/debug/deps/solution-a73e64ec87929bd0
running 3 tests
test tests::test_iteration ... ok
test tests::test_replace_words ... ok
test tests::test_replace_words_unicode ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... ok
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... ok
test solution_test::test_word_iterator_special_characters ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20200116-2173579-6zf004/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.84s
Running target/debug/deps/solution-a73e64ec87929bd0
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... FAILED
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... FAILED
test solution_test::test_word_iterator_special_characters ... ok
failures:
---- solution_test::test_replace stdout ----
thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside 'Ч' (bytes 0..2) of `Честита нова година!`', src/libcore/str/mod.rs:2068:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
---- solution_test::test_word_iterator_cyrillic stdout ----
thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside 'а' (bytes 0..2) of `ала, бала, ница`', src/libcore/str/mod.rs:2068:5
failures:
solution_test::test_replace
solution_test::test_word_iterator_cyrillic
test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
error: test failed, to rerun pass '--test solution_test'
Compiling solution v0.1.0 (/tmp/d20200116-2173579-1huuf3k/solution)
Finished test [unoptimized + debuginfo] target(s) in 3.11s
Running target/debug/deps/solution-a73e64ec87929bd0
running 5 tests
test test_replace ... ok
test test_word_iter1 ... ok
test test_word_iter2 ... ok
test test_word_iter3 ... ok
test test_word_iter4 ... ok
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... FAILED
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... FAILED
test solution_test::test_word_iterator_special_characters ... ok
failures:
---- solution_test::test_replace stdout ----
thread 'main' panicked at 'byte index 7 is not a char boundary; it is inside 'т' (bytes 6..8) of `Честита нова година!`', src/libcore/str/mod.rs:2068:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
---- solution_test::test_word_iterator_cyrillic stdout ----
thread 'main' panicked at 'byte index 3 is not a char boundary; it is inside 'л' (bytes 2..4) of `ала, бала, ница`', src/libcore/str/mod.rs:2068:5
failures:
solution_test::test_replace
solution_test::test_word_iterator_cyrillic
test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
error: test failed, to rerun pass '--test solution_test'
Compiling solution v0.1.0 (/tmp/d20200116-2173579-j6vd77/solution)
warning: unused variable: `next_segment`
--> src/lib.rs:33:17
|
33 | let mut next_segment: Vec<char> = Vec::new();
| ^^^^^^^^^^^^ help: consider prefixing with an underscore: `_next_segment`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `start_index`
--> src/lib.rs:64:13
|
64 | let start_index: usize = self.current_position;
| ^^^^^^^^^^^ help: consider prefixing with an underscore: `_start_index`
warning: unused variable: `s`
--> src/lib.rs:68:13
|
68 | let s = self.source[byte_index_start..byte_index_end].to_string();
| ^ help: consider prefixing with an underscore: `_s`
warning: variable does not need to be mutable
--> src/lib.rs:27:13
|
27 | let mut chars: Vec<char> = self.source.chars().collect();
| ----^^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
warning: variable does not need to be mutable
--> src/lib.rs:33:13
|
33 | let mut next_segment: Vec<char> = Vec::new();
| ----^^^^^^^^^^^^
| |
| help: remove this `mut`
warning: variable does not need to be mutable
--> src/lib.rs:65:13
|
65 | let mut byte_index_start: usize = self.current_position_byte;
| ----^^^^^^^^^^^^^^^^
| |
| help: remove this `mut`
warning: unused variable: `next_segment`
--> src/lib.rs:33:17
|
33 | let mut next_segment: Vec<char> = Vec::new();
| ^^^^^^^^^^^^ help: consider prefixing with an underscore: `_next_segment`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `start_index`
--> src/lib.rs:64:13
|
64 | let start_index: usize = self.current_position;
| ^^^^^^^^^^^ help: consider prefixing with an underscore: `_start_index`
warning: unused variable: `s`
--> src/lib.rs:68:13
|
68 | let s = self.source[byte_index_start..byte_index_end].to_string();
| ^ help: consider prefixing with an underscore: `_s`
warning: variable does not need to be mutable
--> src/lib.rs:27:13
|
27 | let mut chars: Vec<char> = self.source.chars().collect();
| ----^^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
warning: variable does not need to be mutable
--> src/lib.rs:33:13
|
33 | let mut next_segment: Vec<char> = Vec::new();
| ----^^^^^^^^^^^^
| |
| help: remove this `mut`
warning: variable does not need to be mutable
--> src/lib.rs:65:13
|
65 | let mut byte_index_start: usize = self.current_position_byte;
| ----^^^^^^^^^^^^^^^^
| |
| help: remove this `mut`
Finished test [unoptimized + debuginfo] target(s) in 2.22s
Running target/debug/deps/solution-a73e64ec87929bd0
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... ok
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... ok
test solution_test::test_word_iterator_special_characters ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20200116-2173579-drbjw5/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.95s
Running target/debug/deps/solution-a73e64ec87929bd0
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... ok
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... ok
test solution_test::test_word_iterator_special_characters ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20200116-2173579-p2dyvw/solution)
warning: unused variable: `byte_index`
--> src/lib.rs:40:63
|
40 | let (index,_) = self.source.char_indices().find(|(byte_index, c)| Pred(*c)).unwrap_or((self.source.len(), '💜'));
| ^^^^^^^^^^ help: consider prefixing with an underscore: `_byte_index`
|
= note: `#[warn(unused_variables)]` on by default
warning: variable `Pred` should have a snake case name
--> src/lib.rs:33:17
|
33 | let Pred = if is_word(c) {
| ^^^^ help: convert the identifier to snake case: `pred`
|
= note: `#[warn(non_snake_case)]` on by default
warning: unused variable: `byte_index`
--> src/lib.rs:40:63
|
40 | let (index,_) = self.source.char_indices().find(|(byte_index, c)| Pred(*c)).unwrap_or((self.source.len(), '💜'));
| ^^^^^^^^^^ help: consider prefixing with an underscore: `_byte_index`
|
= note: `#[warn(unused_variables)]` on by default
warning: variable `Pred` should have a snake case name
--> src/lib.rs:33:17
|
33 | let Pred = if is_word(c) {
| ^^^^ help: convert the identifier to snake case: `pred`
|
= note: `#[warn(non_snake_case)]` on by default
Finished test [unoptimized + debuginfo] target(s) in 1.75s
Running target/debug/deps/solution-a73e64ec87929bd0
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... ok
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... ok
test solution_test::test_word_iterator_special_characters ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20200116-2173579-1nylbuc/solution)
warning: unused import: `std::env::current_exe`
--> src/lib.rs:1:5
|
1 | use std::env::current_exe;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused variable: `letters`
--> src/lib.rs:42:13
|
42 | let letters: Vec<char> = self.source.chars().collect();
| ^^^^^^^ help: consider prefixing with an underscore: `_letters`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused import: `std::env::current_exe`
--> src/lib.rs:1:5
|
1 | use std::env::current_exe;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused variable: `letters`
--> src/lib.rs:42:13
|
42 | let letters: Vec<char> = self.source.chars().collect();
| ^^^^^^^ help: consider prefixing with an underscore: `_letters`
|
= note: `#[warn(unused_variables)]` on by default
Finished test [unoptimized + debuginfo] target(s) in 2.59s
Running target/debug/deps/solution-a73e64ec87929bd0
running 6 tests
test tests::test_iterator ... ok
test tests::test_iterator_2 ... ok
test tests::test_iterator_cyrillic ... ok
test tests::test_replace_words ... ok
test tests::test_replace_words_advanced ... ok
test tests::test_replace_words_cyrillic ... ok
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... ok
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... ok
test solution_test::test_word_iterator_special_characters ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Compiling solution v0.1.0 (/tmp/d20200116-2173579-1jwqmuk/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.81s
Running target/debug/deps/solution-a73e64ec87929bd0
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... FAILED
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... FAILED
test solution_test::test_word_iterator_special_characters ... ok
failures:
---- solution_test::test_replace stdout ----
thread 'main' panicked at 'byte index 7 is not a char boundary; it is inside 'т' (bytes 6..8) of `Честита нова година!`', src/libcore/str/mod.rs:2068:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
---- solution_test::test_word_iterator_cyrillic stdout ----
thread 'main' panicked at 'byte index 3 is not a char boundary; it is inside 'л' (bytes 2..4) of `ала, бала, ница`', src/libcore/str/mod.rs:2068:5
failures:
solution_test::test_replace
solution_test::test_word_iterator_cyrillic
test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
error: test failed, to rerun pass '--test solution_test'
Compiling solution v0.1.0 (/tmp/d20200116-2173579-urxs5i/solution)
Finished test [unoptimized + debuginfo] target(s) in 1.85s
Running target/debug/deps/solution-a73e64ec87929bd0
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running target/debug/deps/solution_test-38971695424b36d5
running 4 tests
test solution_test::test_replace ... ok
test solution_test::test_word_iterator_ascii ... ok
test solution_test::test_word_iterator_cyrillic ... ok
test solution_test::test_word_iterator_special_characters ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests solution
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out