uiuifree_text_data/
csv_tokenizer.rs1use std::error::Error;
2use std::sync::Mutex;
3
4use rayon::prelude::*;
5use uiuifree_normalize::{free_text, remove_html};
6
7pub struct CsvTokenizer {
8 path: String,
9 }
11
12impl CsvTokenizer {
13 pub fn new(path: &str) -> CsvTokenizer {
14 CsvTokenizer {
15 path: path.to_string()
16 }
20 }
21 pub fn trim_csv(input: &str, output: &str) {
22 match CsvTokenizer::new(input).execute(output) {
24 Ok(_) => {}
25 Err(e) => {
26 println!("{}", e)
27 }
28 };
29 }
30
31 pub fn headers(&self) -> Result<Vec<String>, Box<dyn Error>> {
36 let path = String::from(self.path.as_str());
37 let mut rdr = csv::Reader::from_path(path)?;
38
39 let mut res = Vec::new();
40 for i in rdr.headers()?.iter() {
41 res.push(i.to_string());
42 }
43 Ok(res)
44 }
45 pub fn records(&self) -> Result<Vec<Vec<String>>, Box<dyn Error>> {
46 let path = String::from(self.path.as_str());
47 let mut rdr = csv::Reader::from_path(path)?;
48
49 let mut rows: Vec<Vec<String>> = Vec::new();
50 for result in rdr.records() {
51 let record = result?;
52 let mut row: Vec<String> = Vec::new();
53 for s in record.iter() {
54 row.push(s.to_string());
55 }
56 rows.push(row);
57 }
58 Ok(rows)
59 }
60
61 pub async fn process<F, T, U>(&mut self, callable: F) -> Result<Vec<U>, Box<dyn Error>>
62 where
63 F: Fn(Vec<String>) -> T,
64 T: std::future::Future<Output=U> + std::marker::Send + 'static,
65 U: std::marker::Send + 'static
66 {
67 let path = String::from(self.path.as_str());
68 let mut rdr = csv::ReaderBuilder::new().flexible(true).from_path(path)?;
69
70 let mut handles = vec![];
71 let mut response = vec![];
72
73 for result in rdr.records() {
74 let record = result?;
75 let mut row: Vec<String> = Vec::new();
76 for s in record.iter() {
77 row.push(free_text(s.to_string()));
78 }
81 handles.push(tokio::spawn(callable(row)));
82 }
83
84 for handle in handles {
85 response.push(handle.await.unwrap())
86 }
87
88 return Ok(response);
89 }
90 pub async fn process2<'a ,F, T, U>(&'a mut self, callable: F) -> Result<Vec<U>, Box<dyn Error>>
91 where
92 F: Fn(Vec<String>) -> T + std::marker::Sync + std::marker::Send +'a+ 'static + Copy,
93 T: std::future::Future<Output=U> + std::marker::Send + 'static,
94 U: std::marker::Send + 'static
95 {
96 let path = String::from(self.path.as_str());
97 let mut rdr = csv::ReaderBuilder::new().flexible(true).from_path(path)?;
98 let mut response = vec![];
99 let mut tmp_records = vec![];
100 for result in rdr.records() {
101 let record = result?;
102 let mut row: Vec<String> = Vec::new();
103 for s in record.iter() {
104 row.push(free_text(s.to_string()));
105 }
109 tmp_records.push(row)
110 }
111 let (tx,mut rx) = tokio::sync::mpsc::channel(tmp_records.len());
112 for row in tmp_records {
113 let tx = tx.clone();
114 tokio::spawn(
115 async move {
116 tx.send(callable(row).await).await.unwrap();
117 }
118 );
119 }
120 drop(tx);
121 while let Some(handle) = rx.recv().await {
122 response.push(handle)
123 }
124 return Ok(response);
125 }
126 pub fn execute(&self, out_path: &str) -> Result<(), Box<dyn Error>> {
127 let path = String::from(self.path.as_str());
128 let mut rdr = csv::Reader::from_path(path)?;
130 let mut w = csv::Writer::from_path(out_path)?;
131 let headers = rdr.headers()?;
132
133 w.write_record(headers)?;
134 let mut rows: Vec<Vec<String>> = Vec::new();
135
136 for record in rdr.records() {
137 if record.is_err() {
138 break;
139 }
140 let record = record.unwrap();
141 let mut row: Vec<String> = Vec::new();
142 for s in record.iter() {
143 row.push(s.to_string());
144 }
145 rows.push(row);
146 }
147
148 let vec: Mutex<Vec<Vec<String>>> = Mutex::new(Vec::new());
149 rows.par_iter_mut().for_each(|row| {
150 let mut new_rows = Vec::new();
151 for v in row {
152 new_rows.push(remove_html(free_text(v.to_string())))
153 }
156 vec.lock().unwrap().push(new_rows);
157 });
158 let rows = vec.lock().unwrap().to_vec();
159 for row in rows {
160 w.write_record(row)?;
161 }
162 Ok(())
163 }
164}
165
166
167