From f186a7345dfc99347673f46e0daff0cb63ac8492 Mon Sep 17 00:00:00 2001 From: Kaiden Fey Date: Sun, 21 Feb 2021 14:56:11 +0100 Subject: k-office: initial code dump --- apps/koffice/libko/src/cass/format/mod.rs | 76 +++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 apps/koffice/libko/src/cass/format/mod.rs (limited to 'apps/koffice/libko/src/cass/format/mod.rs') 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.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 { + // 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 = 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::>(); + 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(()) +} -- cgit v1.2.3