spcsv/
lib.rs

1use futures::future::join_all;
2use std::env::current_dir;
3use std::process::exit;
4use file_manager::File;
5use std::sync::Arc;
6use std::io::Write;
7
8pub mod reader;
9pub mod shared;
10pub mod file_manager;
11pub mod args;
12pub mod misc;
13
14use crate::reader::BufReader;
15use crate::args::Args;
16use crate::misc::*;
17use shared::*;
18
19#[tokio::main]
20pub async fn app(args: Option<Args>) {
21    let args: Args = match args {
22        Some(a) => a,
23        None => Args::load(),
24    };
25
26    let extra = if args.remaining_in_last { 0 } else { 1 };
27    let file: File = File::new(&args.file, !args.not_signed_file).unwrap();
28    let buf_reader: MShared = MShared::n(BufReader::open(file.file_path.as_str()).unwrap());
29
30    let (each, remain) = lines_per_file(&file, args.number_of_files).unwrap_or_else(|| {
31        eprintln!(
32            "Can't split {} lines within {} files",
33            file.lines() - file.header(),
34            args.number_of_files
35        );
36        exit(1);
37    });
38
39    fs_extra::dir::create(get_target_directory(&file), true).unwrap();
40
41    let headers = buf_reader.get_headers(&file);
42    let paths = gen_paths(&file, extra + args.number_of_files);
43    let shared = Arc::new(IShared { paths, headers });
44
45    let mut handlers = vec![];
46    for i in 0..=args.number_of_files - extra {
47        let buf_reader_clone = Arc::clone(&buf_reader);
48        let shared = Arc::clone(&shared);
49
50        handlers.push(tokio::task::spawn(async move {
51            let text;
52            let remaining_text;
53            {
54                let mut reader = &mut *buf_reader_clone.lock().unwrap();
55                text = read_n_lines(&mut reader, each);
56                remaining_text = if i == args.number_of_files - extra && remain > 0 {
57                    Some(read_n_lines(&mut reader, remain))
58                } else {
59                    None
60                };
61            }
62
63            let mut f = std::fs::File::create(&shared.paths[i]).expect("Unable to create file");
64
65            f.write_all(shared.headers.as_bytes())
66                .expect("Unable to write data");
67            f.write_all(text.as_bytes()).expect("Unable to write data");
68            if args.verbose {
69                println!("Wrote {} rows to {}", each, &shared.paths[i]);
70            }
71
72            if i == args.number_of_files - extra && remain > 0 {
73                if args.remaining_in_last {
74                    f.write_all(remaining_text.unwrap().as_bytes())
75                        .expect("Unable to write data");
76                    if args.verbose {
77                        println!("Wrote {} remaining rows to {}", remain, &shared.paths[i]);
78                    }
79                } else {
80                    let mut f =
81                        std::fs::File::create(&shared.paths[i + 1])
82                            .expect("Unable to create file");
83
84                    f.write_all(shared.headers.as_bytes())
85                        .expect("Unable to write data");
86                    f.write_all(remaining_text.unwrap().as_bytes())
87                        .expect("Unable to write data");
88                    if args.verbose {
89                        println!(
90                            "Wrote {} remaining rows to {}",
91                            remain,
92                            &shared.paths[i + 1]
93                        );
94                    }
95                }
96            }
97        }));
98    }
99
100    join_all(handlers).await;
101}