1#![feature(const_trait_impl)]
7#![feature(const_default)]
8
9mod continuations;
11mod problem;
12mod section;
13#[cfg(test)]
14mod tests;
15
16use std::{
18 env::args,
19 fs::File,
20 path::PathBuf,
21 sync::LazyLock,
22 time::Instant
23};
24
25use core::fmt::{
27 Debug,
28 Display
29};
30
31use libutils_cage::Cage;
33
34use continuations::{
36 ActionRequired,
37 FileDescriptor
38};
39
40use libutils_issue::{
42 Issue,
43 Severity
44};
45
46use libutils_console::{
48 Console,
49 Argument,
50 Synchronization,
51 Descriptor
52};
53
54use section::Section;
56
57use problem::Problem;
59
60
61static ARGUMENTS: LazyLock<Vec<Argument>> = LazyLock::new(|| args().map(Argument::from).collect());
67static LAYOUT: Cage<Vec<Section>> = Cage::default();
68static OUTPUT: Cage<String> = Cage::default();
69
70pub struct Terminal;
72
73impl Console for Terminal {
75 fn arguments<'valid>(&'valid self) -> &'valid [Argument] {return ARGUMENTS.as_slice()}
76 fn open(&self, filename: &str) -> Result<impl Descriptor, Issue> {match File::open(PathBuf::from(filename)) {
77 Ok(file) => Ok(FileDescriptor {
78 file: file
79 }),
80 Err(error) => Err(Issue {
81 name: "Failed to open file",
82 description: Some(error.to_string()),
83 severity: Severity::Error
84 })
85 }}
86 fn problem(&self, issue: Issue, chain: &[&'static str]) -> impl Synchronization {
87 LAYOUT.write(|layout| layout.push(Section::Problem(Problem {
88 chain: Vec::from(chain),
89 issue: issue,
90 _at: Instant::now()
91 })));
92 return ActionRequired;
93 }
94 fn print(&self, value: impl Display) -> impl Synchronization {
95 LAYOUT.write(|layout| layout.push(Section::Display(value.to_string())));
96 return ActionRequired;
97 }
98 fn debug(&self, value: impl Debug) -> impl Synchronization {
99 LAYOUT.write(|layout| layout.push(Section::Debug(format!("{value:#?}"))));
100 return ActionRequired;
101 }
102}