summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..eda1c01
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,62 @@
+extern crate clap;
+extern crate rand;
+
+use clap::{Arg, App};
+use std::collections::vec_deque::VecDeque;
+use std::io::{self, BufRead};
+use std::result::Result;
+
+fn some<R: rand::Rng, T: Iterator<Item = Result<String, io::Error>>>(
+ r: &mut R,
+ n: usize,
+ lines: T,
+) -> Result<VecDeque<String>, io::Error> {
+ let mut result: VecDeque<String> = VecDeque::with_capacity(n);
+ fn push(v: &mut VecDeque<String>, n: usize, x: String) {
+ v.push_back(x);
+ if v.len() > n {
+ v.pop_front();
+ }
+ };
+
+ for (i, line) in lines.enumerate() {
+ let line = line?;
+ if result.len() < n {
+ push(&mut result, n, line);
+ } else if r.gen_range(0, i) < n {
+ let victim = r.gen_range(0, n);
+ result.remove(victim);
+ push(&mut result, n, line);
+ }
+ }
+ return Ok(result);
+}
+
+fn main() {
+ let matches = App::new("some")
+ .version("0.1")
+ .author("Kjetil Ørbekk <kj@orbekk.com>")
+ .arg(
+ Arg::with_name("lines")
+ .short("n")
+ .value_name("NUM")
+ .help("Number of lines to print")
+ .takes_value(true),
+ )
+ .get_matches();
+ let num_lines = matches
+ .value_of("lines")
+ .unwrap_or("10")
+ .parse::<usize>()
+ .expect("number of lines to print");
+ let stdin = io::stdin();
+ let lines = some(&mut rand::thread_rng(), num_lines, stdin.lock().lines());
+ match lines {
+ Ok(lines) => {
+ for line in lines {
+ println!("{}", line);
+ }
+ }
+ Err(e) => println!("Error: {}", e),
+ }
+}