diff options
Diffstat (limited to 'src/deck.rs')
-rw-r--r-- | src/deck.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/deck.rs b/src/deck.rs new file mode 100644 index 0000000..384ce19 --- /dev/null +++ b/src/deck.rs @@ -0,0 +1,59 @@ +use crate::{model::deck::Entry, util::serialization}; +use anyhow::{Result, Error}; +use std::fs::File; +use std::io::{prelude::*, BufReader}; +use std::fmt; + +#[derive(Debug, Clone)] +struct ParseError { + line: usize, + message: String, +} + +impl fmt::Display for ParseError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} (parsing line {})", self.message, self.line) + } +} + +impl std::error::Error for ParseError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + None + } +} + + +pub fn read() -> Result<Vec<Entry>> { + let file = File::open("deck")?; + let reader = BufReader::new(file); + let mut entries: Vec<Entry> = Vec::new(); + + for (index, line) in reader.lines().enumerate() { + let line = line?; + let line = line.trim(); + + if !line.starts_with("#") && !line.is_empty() { + if !line.starts_with("-") { + return Err(Error::from(ParseError { line: index + 1, message: "an entry should starts with “-”.".to_string() })) + } else { + let translation = line[1..].trim().split(":").collect::<Vec<&str>>(); + if translation.len() != 2 { + return Err(Error::from(ParseError { line: index + 1, message: "an entry should contain two parts separated by “:”.".to_string() })) + } else { + let t1 = translation[0].trim(); + let t2 = translation[1].trim(); + if t1.is_empty() || t2.is_empty() { + return Err(Error::from(ParseError { line: index + 1, message: "an entry should contain two parts separated by “:”.".to_string() })) + } else { + entries.push(Entry { + part_1: serialization::line_to_words(&t1.to_string()), + part_2: serialization::line_to_words(&t2.to_string()), + }) + } + } + } + } + } + + Ok(entries) +} |