aboutsummaryrefslogtreecommitdiff
path: root/apps/cassiopeia/src/format/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'apps/cassiopeia/src/format/mod.rs')
-rw-r--r--apps/cassiopeia/src/format/mod.rs59
1 files changed, 34 insertions, 25 deletions
diff --git a/apps/cassiopeia/src/format/mod.rs b/apps/cassiopeia/src/format/mod.rs
index 89f3a6ccb466..65c2264d6829 100644
--- a/apps/cassiopeia/src/format/mod.rs
+++ b/apps/cassiopeia/src/format/mod.rs
@@ -8,13 +8,17 @@ mod parser;
pub(crate) use lexer::{LineLexer, LineToken, Token};
pub(crate) use parser::LineCfg;
-use crate::TimeFile;
+use crate::{
+ error::{ParseError, ParseResult},
+ TimeFile,
+};
use ir::{IrItem, IrStream};
use std::{
fs::{File, OpenOptions},
io::{Read, Write},
};
+/// A crate internal representation of the IR stream and timefile
#[derive(Default)]
pub(crate) struct ParseOutput {
pub(crate) ir: IrStream,
@@ -22,46 +26,51 @@ pub(crate) struct ParseOutput {
}
impl ParseOutput {
- fn append(mut self, ir: IrItem) -> Self {
- self.tf.append(ir.clone());
+ fn append(mut self, ir: IrItem) -> ParseResult<Self> {
+ self.tf.append(ir.clone())?;
self.ir.push(ir);
- self
+ Ok(self)
}
}
/// Load a file from disk and parse it into a
/// [`TimeFile`](crate::TimeFile)
-pub(crate) fn load_file(path: &str) -> Option<ParseOutput> {
- let mut f = File::open(path).ok()?;
+pub(crate) fn load_file(path: &str) -> ParseResult<ParseOutput> {
+ // Load the raw file contents
+ let mut f = File::open(path)?;
let mut content = String::new();
- f.read_to_string(&mut content).ok()?;
+ f.read_to_string(&mut content)?;
+ // Split the file by lines - .cass is a line based format
let mut lines: Vec<String> = content.split("\n").map(|l| l.to_owned()).collect();
- Some(
- ir::generate_ir(
- lines
- .iter_mut()
- .map(|line| lexer::lex(line))
- .map(|lex| parser::parse(lex)),
- )
+ // Build an iterator over parsed lines
+ let parsed = lines
+ .iter_mut()
+ .map(|line| lexer::lex(line))
+ .map(|lex| parser::parse(lex));
+
+ // Generate the IR from parse output, then build the timefile
+ ir::generate_ir(parsed)
.into_iter()
- .fold(ParseOutput::default(), |output, ir| output.append(ir)),
- )
+ .fold(Ok(ParseOutput::default()), |out, ir| match out {
+ Ok(mut out) => out.append(ir),
+ e @ Err(_) => e,
+ })
}
/// Write a file with the updated IR stream
-pub(crate) fn write_file(path: &str, ir: &mut IrStream) -> Option<()> {
+pub(crate) fn write_file(path: &str, ir: &mut IrStream) -> ParseResult<()> {
ir::update_header(ir);
let mut lines = ir.into_iter().map(|ir| gen::line(ir)).collect::<Vec<_>>();
lines.insert(0, gen::head_comment());
- let mut f = OpenOptions::new()
- .write(true)
- .create(true)
- .truncate(true)
- .open(path)
- .ok()?;
- f.write_all(lines.join("\n").as_bytes()).ok()?;
- Some(())
+ // let mut f = OpenOptions::new()
+ // .write(true)
+ // .create(true)
+ // .truncate(true)
+ // .open(path)
+ // .ok()?;
+ // f.write_all(lines.join("\n").as_bytes()).ok()?;
+ Ok(())
}