-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpipeline.rs
78 lines (62 loc) · 1.73 KB
/
pipeline.rs
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
use std::{
path::PathBuf,
sync::mpsc,
};
use anyhow::{Context, Result};
use threadpool::ThreadPool;
use crate::module::{Module, ModuleParser};
#[derive(Debug)]
pub struct Item {
pub source_path: PathBuf,
pub module: Module,
}
#[derive(Debug)]
pub struct Pipeline {
pool: ThreadPool,
tx: mpsc::Sender<Item>,
rx: mpsc::Receiver<Item>,
}
impl Pipeline {
pub fn new() -> Self {
let name = "agda-index-module-worker".into();
let pool = threadpool::Builder::new().thread_name(name).build();
let (tx, rx) = mpsc::channel();
Self { pool, tx, rx }
}
pub fn process_module(&self, source_path: PathBuf) {
let tx = self.tx.clone();
self.pool.execute(move || {
if let Err(err) = process_module(source_path, tx) {
eprintln!("Failed to process module: {err}")
}
});
}
pub fn consume(self) -> Output {
Output { rx: self.rx }
}
}
fn process_module(source_path: PathBuf, result: mpsc::Sender<Item>) -> Result<()> {
let parser = ModuleParser::new();
let content = std::fs::read_to_string(&source_path)
.with_context(|| format!("Failed to read module file at {}", source_path.display()))?;
let module = parser
.parse_module(&content)
.with_context(|| format!("Failed to parse module {}", source_path.display()))?;
result
.send(Item {
source_path,
module,
})
.context("Failed to send result")?;
Ok(())
}
pub struct Output {
rx: mpsc::Receiver<Item>,
}
impl IntoIterator for Output {
type Item = Item;
type IntoIter = mpsc::IntoIter<Item>;
fn into_iter(self) -> Self::IntoIter {
self.rx.into_iter()
}
}