aboutsummaryrefslogtreecommitdiff
path: root/src/deck.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/deck.rs')
-rw-r--r--src/deck.rs59
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)
+}