aboutsummaryrefslogtreecommitdiff
path: root/src/deck.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/deck.rs')
-rw-r--r--src/deck.rs73
1 files changed, 25 insertions, 48 deletions
diff --git a/src/deck.rs b/src/deck.rs
index 4491d9b..3fff77f 100644
--- a/src/deck.rs
+++ b/src/deck.rs
@@ -1,4 +1,5 @@
-use crate::{model::Line, util::serialization};
+use crate::model::Line;
+use crate::parser;
use anyhow::{Error, Result};
use std::fmt;
use std::fs::File;
@@ -7,13 +8,17 @@ use std::path::Path;
#[derive(Debug, Clone)]
struct ParseError {
- line: usize,
- message: String,
+ line: String,
+ line_number: usize,
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Line {}: {}", self.line, self.message)
+ write!(
+ f,
+ "Error parsing line {}:\n\n{}",
+ self.line_number, self.line
+ )
}
}
@@ -40,39 +45,12 @@ pub fn read_file(path: &str) -> Result<Vec<Line>> {
}
fn read_line(index: usize, line: &str) -> Result<Option<Line>> {
- let line = line.trim();
-
- if line.starts_with('#') || line.is_empty() {
- Ok(None)
- } else if !line.starts_with('-') {
- Err(Error::from(ParseError {
- line: index + 1,
- message: "an entry should starts with “-”.".to_string(),
- }))
- } else {
- let without_minus = line.split('-').skip(1).collect::<Vec<&str>>().join("-");
- let without_comment = without_minus.split('#').collect::<Vec<&str>>()[0].trim();
- let translation = without_comment.split(':').collect::<Vec<&str>>();
- if translation.len() != 2 {
- 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() {
- Err(Error::from(ParseError {
- line: index + 1,
- message: "an entry should contain two parts separated by “:”.".to_string(),
- }))
- } else {
- Ok(Some(Line {
- part_1: serialization::line_to_words(t1),
- part_2: serialization::line_to_words(t2),
- }))
- }
- }
+ match parser::parse_line(line) {
+ Ok(("", line)) => Ok(line),
+ _ => Err(Error::from(ParseError {
+ line_number: index + 1,
+ line: line.to_string(),
+ })),
}
}
@@ -98,12 +76,11 @@ pub mod tests {
#[test]
fn errors() {
- is_error("A : a");
- is_error("- A");
- is_error("- A -> a");
- is_error("- A : B : C");
- is_error("- : ");
- is_error("- A : a\n-")
+ is_error("A");
+ is_error("A -> a");
+ is_error("A : B : C");
+ is_error(":");
+ is_error("A : a\n-")
}
#[test]
@@ -117,19 +94,19 @@ pub mod tests {
#[test]
fn card() {
- check("- A : a", &[(&["A"], &["a"])]);
+ check("A : a", &[(&["A"], &["a"])]);
}
#[test]
fn cards() {
- check("- A : a\n- B : b", &[(&["A"], &["a"]), (&["B"], &["b"])]);
+ check("A : a\nB : b", &[(&["A"], &["a"]), (&["B"], &["b"])]);
}
#[test]
fn alternatives() {
- check("- A : a1 | a2", &[(&["A"], &["a1", "a2"])]);
- check("- A1 | A2 : a", &[(&["A1", "A2"], &["a"])]);
- check("- A1 | A2 : a1 | a2", &[(&["A1", "A2"], &["a1", "a2"])]);
+ check("A : a1 | a2", &[(&["A"], &["a1", "a2"])]);
+ check("A1 | A2 : a", &[(&["A1", "A2"], &["a"])]);
+ check("A1 | A2 : a1 | a2", &[(&["A1", "A2"], &["a1", "a2"])]);
}
fn is_error(content: &str) {