1use std::io;
2
3use io::Write;
4
5#[derive(PartialEq, Eq, PartialOrd, Ord)]
6pub struct Candidate {
7 score: u32,
8 content: String,
9}
10
11pub fn lines2candidates<I, F>(
12 lines: I,
13 target: String,
14 tgt2score: F,
15) -> impl Iterator<Item = Result<Candidate, io::Error>>
16where
17 I: Iterator<Item = Result<String, io::Error>>,
18 F: Fn(&str, String) -> Result<Candidate, io::Error>,
19{
20 lines.map(move |rline| {
21 let line: String = rline?;
22 let cand: Candidate = tgt2score(&target, line)?;
23 Ok(cand)
24 })
25}
26
27pub fn zip2score(tgt: &str, line: String) -> Result<Candidate, io::Error> {
28 let tc = tgt.chars();
29 let lc = line.chars();
30 let zipped = tc.zip(lc);
31 let filtered = zipped.filter(|pair| {
32 let (t, l) = pair;
33 t.eq(l)
34 });
35 let cnt: usize = filtered.count();
36 let score: u32 = cnt.try_into().ok().unwrap_or(u32::MAX);
37 Ok(Candidate {
38 score,
39 content: line,
40 })
41}
42
43pub fn lines2candidates_zip2score<I>(
44 lines: I,
45 target: String,
46) -> impl Iterator<Item = Result<Candidate, io::Error>>
47where
48 I: Iterator<Item = Result<String, io::Error>>,
49{
50 lines2candidates(lines, target, zip2score)
51}
52
53pub struct Ltsv {
54 pub sep1: String,
55 pub sep2: String,
56}
57
58impl Default for Ltsv {
59 fn default() -> Self {
60 Self {
61 sep1: ":".into(),
62 sep2: "\t".into(),
63 }
64 }
65}
66
67impl Ltsv {
68 pub fn into_candidate_writer<W>(
69 self,
70 mut wtr: W,
71 ) -> impl FnMut(&Candidate) -> Result<(), io::Error>
72 where
73 W: Write,
74 {
75 move |c: &Candidate| {
76 let score: u32 = c.score;
77 let line: &str = &c.content;
78 let csep: &str = &self.sep1;
79 let tsep: &str = &self.sep2;
80 writeln!(&mut wtr, "score{csep}{score}{tsep}line{csep}{line}")
81 }
82 }
83}
84
85pub fn candidates2writer<I, W>(ic: I, mut cwtr: W) -> impl FnOnce() -> Result<(), io::Error>
86where
87 I: Iterator<Item = Result<Candidate, io::Error>>,
88 W: FnMut(&Candidate) -> Result<(), io::Error>,
89{
90 move || {
91 for rc in ic {
92 let c: Candidate = rc?;
93 cwtr(&c)?;
94 }
95 Ok(())
96 }
97}