My personal project and infrastructure archive
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
nomicon/apps/cassiopeia/src/format/ir.rs

63 lines
2.1 KiB

use crate::{format::LineCfg, Date, Time, TimeFile};
use std::collections::BTreeMap;
/// A set of IR parsed items that makes up a whole cass file
pub(crate) type IrStream = Vec<IrItem>;
/// Intermediate representation for parsing and generating files
///
/// The CASS IR is largely based on the output of the parser's
/// [`LineCfg`](crate::format::LineCfg), but with concrete types used
/// in the data layer (namely [`Date`][date] and [`Time`][time]),
/// while also keeping track of the line numbers to allow idempotent
/// file changes.
///
/// Something not yet implemented is comment pass-through (this needs
/// to happen in the parser first), but will likely be implemented in
/// a future version.
///
/// [date]: crate::Date
/// [time]: crate::Time
#[derive(Debug, Clone)]
pub(crate) struct IrItem {
pub(crate) tt: IrType,
pub(crate) lo: usize,
}
/// Disambiguate between different IR line types with their payload
#[derive(Debug, Clone)]
pub(crate) enum IrType {
/// A line with parsed header information
Header(BTreeMap<String, String>),
/// Start a session at a given timestapm
Start(Time),
/// Stop a session at a given timestamp
Stop(Time),
/// Invoice a block of previous work
Invoice(Date),
/// An item that gets ignored
Ignore,
}
/// Generate a stream of IR items from the raw parser output
pub(crate) fn generate_ir(buf: impl Iterator<Item = LineCfg>) -> IrStream {
buf.enumerate().fold(vec![], |mut buf, (lo, item)| {
#[cfg_attr(rustfmt, rustfmt_skip)]
buf.push(match item {
LineCfg::Header(map) => IrItem { tt: IrType::Header(map), lo },
LineCfg::Start(Some(time)) => IrItem { tt: IrType::Start(time.into()), lo },
LineCfg::Stop(Some(time)) => IrItem { tt: IrType::Stop(time.into()), lo },
LineCfg::Invoice(Some(date)) => IrItem { tt: IrType::Invoice(date.into()), lo },
LineCfg::Ignore => IrItem { tt: IrType::Ignore, lo },
_ => IrItem { tt: IrType::Ignore, lo },
});
buf
})
}
pub(crate) trait MakeIr {
/// Make a new IR line from an object
fn make_ir(&self) -> IrType;
}