#![feature(const_trait_impl)]
#![feature(const_default)]
mod continuations;
mod problem;
mod section;
#[cfg(test)]
mod tests;
use std::{
env::args,
sync::LazyLock,
fs::File,
path::PathBuf
};
use core::fmt::{
Debug,
Display
};
use libutils_cage::Cage;
use libutils_threat::Threat;
use continuations::{
ActionRequired,
FileDescriptor
};
use libutils_issue::{
Issue,
Severity
};
use libutils_console::{
Console,
Argument,
Synchronization,
Descriptor
};
use section::Section;
pub static TERMINAL: Terminal = Terminal {
arguments: LazyLock::new(|| args().map(Argument::from).collect()),
layout: Cage::default(),
output: Cage::default()
};
pub struct Terminal {
arguments: LazyLock<Vec<Argument>>,
layout: Cage<Vec<Section>>,
output: Cage<String>
}
impl Console for Terminal {
fn arguments<'valid>(&'valid self) -> &'valid [Argument] {return self.arguments.as_slice()}
fn open(&self, filename: &str) -> Result<impl Descriptor, Issue> {match File::open(PathBuf::from(filename)) {
Ok(file) => Ok(FileDescriptor {
file: file
}),
Err(error) => Err(Issue {
name: "Failed to open file",
description: Some(error.to_string()),
severity: Severity::Error
})
}}
fn problem(&self, threat: Threat) -> impl Synchronization {
self.layout.write(|layout| layout.push(Section::Problem(threat.into())));
return ActionRequired;
}
fn print(&self, value: impl Display) -> impl Synchronization {
self.layout.write(|layout| layout.push(Section::Display(value.to_string())));
return ActionRequired;
}
fn debug(&self, value: impl Debug) -> impl Synchronization {
self.layout.write(|layout| layout.push(Section::Debug(format!("{value:#?}"))));
return ActionRequired;
}
}