1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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(())
}
}
|