Skip to main content

relibc/
db.rs

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}