aboutsummaryrefslogtreecommitdiff
path: root/ops/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ops/src/lib.rs')
-rw-r--r--ops/src/lib.rs127
1 files changed, 127 insertions, 0 deletions
diff --git a/ops/src/lib.rs b/ops/src/lib.rs
new file mode 100644
index 0000000..8cd5607
--- /dev/null
+++ b/ops/src/lib.rs
@@ -0,0 +1,127 @@
+extern crate blist;
+extern crate ilc_base;
+
+mod ageset;
+pub mod freq;
+
+pub mod parse {
+ use ilc_base::{self, Context, Decode};
+ use std::io::BufRead;
+ pub fn parse(ctx: &Context, input: &mut BufRead, decoder: &mut Decode) -> ilc_base::Result<()> {
+ for e in decoder.decode(&ctx, input) {
+ try!(e);
+ }
+ Ok(())
+ }
+}
+
+pub mod convert {
+ use ilc_base::{self, Context, Decode, Encode};
+ use std::io::{BufRead, Write};
+
+ pub fn convert(ctx: &Context,
+ input: &mut BufRead,
+ decoder: &mut Decode,
+ output: &mut Write,
+ encoder: &Encode)
+ -> ilc_base::Result<()> {
+ for e in decoder.decode(&ctx, input) {
+ try!(encoder.encode(&ctx, output, &try!(e)));
+ }
+ Ok(())
+ }
+}
+
+pub mod seen {
+ use ilc_base::{self, Context, Decode, Encode, Event};
+ use std::io::{BufRead, Write};
+
+ pub fn seen(nick: &str,
+ ctx: &Context,
+ input: &mut BufRead,
+ decoder: &mut Decode,
+ output: &mut Write,
+ encoder: &Encode)
+ -> ilc_base::Result<()> {
+ let mut last: Option<Event> = None;
+ for e in decoder.decode(&ctx, input) {
+ let m: Event = try!(e);
+ if m.ty.involves(nick) &&
+ last.as_ref().map_or(true,
+ |last| m.time.as_timestamp() > last.time.as_timestamp()) {
+ last = Some(m)
+ }
+ }
+ if let Some(ref m) = last {
+ try!(encoder.encode(&ctx, output, m));
+ }
+ Ok(())
+ }
+}
+
+pub mod sort {
+ use ilc_base::{self, Context, Decode, Encode, Event};
+ use std::io::{BufRead, Write};
+
+ pub fn sort(ctx: &Context,
+ input: &mut BufRead,
+ decoder: &mut Decode,
+ output: &mut Write,
+ encoder: &Encode)
+ -> ilc_base::Result<()> {
+ let mut events: Vec<Event> = decoder.decode(&ctx, input)
+ .flat_map(Result::ok)
+ .collect();
+
+ events.sort_by(|a, b| a.time.cmp(&b.time));
+ for e in events {
+ try!(encoder.encode(&ctx, output, &e));
+ }
+ Ok(())
+ }
+}
+
+pub mod dedup {
+ use std::io::{BufRead, Write};
+ use std::hash::{Hash, Hasher};
+ use ageset::AgeSet;
+ use ilc_base::{self, Context, Decode, Encode, Event};
+
+ #[derive(Clone, Debug, PartialEq, Eq)]
+ pub struct NoTimeHash<'a>(pub Event<'a>);
+
+ impl<'a> Hash for NoTimeHash<'a> {
+ fn hash<H>(&self, state: &mut H)
+ where H: Hasher
+ {
+ self.0.ty.hash(state);
+ self.0.channel.hash(state);
+ }
+ }
+
+ pub fn dedup(ctx: &Context,
+ input: &mut BufRead,
+ decoder: &mut Decode,
+ output: &mut Write,
+ encoder: &Encode)
+ -> ilc_base::Result<()> {
+ let mut backlog = AgeSet::new();
+
+ for e in decoder.decode(&ctx, input) {
+ if let Ok(e) = e {
+ let newest_event = e.clone();
+ backlog.prune(move |a: &NoTimeHash| {
+ let age = newest_event.time.as_timestamp() - a.0.time.as_timestamp();
+ age > 5000
+ });
+ // write `e` if it's a new event
+ let n = NoTimeHash(e);
+ if !backlog.contains(&n) {
+ try!(encoder.encode(&ctx, output, &n.0));
+ backlog.push(n);
+ }
+ }
+ }
+ Ok(())
+ }
+}