1use alloc::{string::String, vec::Vec};
2
3use crate::{
4 c_str::CStr,
5 fs::File,
6 header::fcntl,
7 io::{self, BufRead, BufReader},
8};
9
10pub enum Separator {
11 Character(char),
12 Whitespace,
13}
14
15pub struct Db<R: BufRead> {
16 reader: R,
17 separator: Separator,
18}
19
20impl<R: BufRead> Db<R> {
21 pub fn new(reader: R, separator: Separator) -> Self {
22 Db { reader, separator }
23 }
24
25 pub fn read(&mut self) -> io::Result<Option<Vec<String>>> {
26 let mut line = String::new();
27 if self.reader.read_line(&mut line)? == 0 {
28 return Ok(None);
29 }
30
31 let vec = if let Some(not_comment) = line.trim().split('#').next() {
32 match self.separator {
33 Separator::Character(c) => not_comment.split(c).map(String::from).collect(),
34 Separator::Whitespace => not_comment.split_whitespace().map(String::from).collect(),
35 }
36 } else {
37 Vec::new()
38 };
39
40 Ok(Some(vec))
41 }
42}
43
44pub type FileDb = Db<BufReader<File>>;
45
46impl FileDb {
47 pub fn open(path: CStr, separator: Separator) -> io::Result<Self> {
48 let file = File::open(path, fcntl::O_RDONLY | fcntl::O_CLOEXEC)?;
49 Ok(Db::new(BufReader::new(file), separator))
50 }
51}