summaryrefslogtreecommitdiff
path: root/meap/meap-code/ch2/ch2-introducing-vec.rs
diff options
context:
space:
mode:
Diffstat (limited to 'meap/meap-code/ch2/ch2-introducing-vec.rs')
-rwxr-xr-xmeap/meap-code/ch2/ch2-introducing-vec.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/meap/meap-code/ch2/ch2-introducing-vec.rs b/meap/meap-code/ch2/ch2-introducing-vec.rs
new file mode 100755
index 0000000..0a3cf4b
--- /dev/null
+++ b/meap/meap-code/ch2/ch2-introducing-vec.rs
@@ -0,0 +1,52 @@
+fn main() {
+ // PARAMETERS
+ let context_lines = 2;
+ let needle = "oo";
+ let haystack = "Every face, every shop,
+bedroom window, public-house, and
+dark square is a picture
+feverishly turned--in search of what?
+It is the same with books.
+What do we seek
+through millions of pages?";
+
+ // INITIALIZATION
+ let mut tags: Vec<usize> = Vec::new(); // <1> `tags` holds line numbers where matches occur
+ let mut ctx: Vec<Vec<(usize, String)>> = Vec::new(); // <2> `ctx` contains a vector per match to hold that match's context lines
+
+ // PASS 1
+ for (i, line) in haystack.lines().enumerate() { // <3> iterate through the lines, recording line numbers where matches are encountered
+ if line.contains(needle) {
+ tags.push(i);
+
+ let v = Vec::with_capacity(2*context_lines + 1); // <4> <5> `Vec::with_capacity(_n_)` reserves space for _n_ items
+ ctx.push(v);
+ }
+ }
+
+ if tags.len() == 0 { // <6> When there are no matches, exit early
+ return;
+ }
+
+ // PASS 2
+ for (i, line) in haystack.lines().enumerate() { // <7> For each tag, at every line, check to see if we are nearby a match. When we are, add that line to the relevant `Vec<T>` within `ctx`.
+ for (j, tag) in tags.iter().enumerate() {
+ let lower_bound = tag.saturating_sub(context_lines); // <8> `usize.saturating_sub()` returns 0, rather than underflowing
+ let upper_bound = tag + context_lines;
+
+ if (i >= lower_bound) && (i <= upper_bound) {
+ let line_as_string = String::from(line); // <9> Copy `line` into a new `String` and store that locally for each match
+ let local_ctx = (i, line_as_string);
+ ctx[j].push(local_ctx);
+ }
+ }
+ }
+
+ // OUTPUT
+ for local_ctx in ctx.iter() {
+ for &(i, ref line) in local_ctx.iter() { // <10> `ref line` informs the compiler that we wish to borrow this value, rather than move it. These two terms are explained fully later in later chapters.
+ let line_num = i + 1;
+ println!("{}: {}", line_num, line);
+ }
+ }
+}