aboutsummaryrefslogtreecommitdiff
path: root/apps/koffice/libko/src/cass/format/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'apps/koffice/libko/src/cass/format/mod.rs')
-rw-r--r--apps/koffice/libko/src/cass/format/mod.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/apps/koffice/libko/src/cass/format/mod.rs b/apps/koffice/libko/src/cass/format/mod.rs
new file mode 100644
index 000000000000..2983653898b6
--- /dev/null
+++ b/apps/koffice/libko/src/cass/format/mod.rs
@@ -0,0 +1,76 @@
+//! cassiopeia file format
+
+mod gen;
+pub(crate) mod ir;
+mod lexer;
+mod parser;
+
+pub(crate) use lexer::{LineLexer, LineToken, Token};
+pub(crate) use parser::LineCfg;
+
+use crate::{
+ cass::error::{ParseError, ParseResult},
+ cass::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,
+ pub(crate) tf: TimeFile,
+}
+
+impl ParseOutput {
+ fn append(mut self, ir: IrItem) -> ParseResult<Self> {
+ self.tf.append(ir.clone())?;
+ self.ir.push(ir);
+ Ok(self)
+ }
+}
+
+/// Load a file from disk and parse it into a
+/// [`TimeFile`](crate::TimeFile)
+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)?;
+
+ // 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();
+
+ // 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(Ok(ParseOutput::default()), |out, ir| match out {
+ Ok(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) -> 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()?;
+ Ok(())
+}