1#![feature(const_trait_impl)]
7#![feature(const_default)]
8
9mod action;
11mod item;
12mod problem;
13#[cfg(test)]
14mod tests;
15
16use std::{
18 env::args,
19 sync::LazyLock,
20 fs::read_to_string,
21 path::PathBuf
22};
23
24use core::fmt::{
26 Display,
27 Debug
28};
29
30use libutils_cage::Cage;
32
33use libutils_threat::Threat;
35
36use action::Action;
38
39use libutils_issue::{
41 Issue,
42 Severity
43};
44
45use libutils_console::{
47 Console,
48 Argument,
49 Handle
50};
51
52use item::Item;
54
55
56pub static TERMINAL: Terminal = Terminal {
62 arguments: LazyLock::new(|| args().map(Argument::from).collect()),
63 layout: Cage::default(),
64 output: Cage::default()
65};
66
67pub struct Terminal {
69 arguments: LazyLock<Vec<Argument>>,
70 layout: Cage<Vec<Item>>,
71 output: Cage<String>
72}
73
74impl Console for Terminal {
76 #[inline]
77 fn arguments<'valid>(&'valid self) -> &'valid [Argument] {return self.arguments.as_slice()}
78 #[inline]
79 fn read(&self, filename: &str) -> Result<String, Issue> {return read_to_string(PathBuf::from(filename)).map_err(|error| Issue {
80 name: "Failed to read file",
81 description: Some(error.to_string()),
82 severity: Severity::Error
83 })}
84 #[inline]
85 fn problem(&self, threat: Threat) -> impl Handle {
86 self.layout.write(|layout| layout.push(Item::Problem(threat.into())));
87 return Action;
88 }
89 #[inline]
90 fn print<Type: Display>(&self, value: Type) -> impl Handle {
91 self.layout.write(|layout| layout.push(Item::String(value.to_string())));
92 return Action;
93 }
94 #[inline]
95 fn debug<Type: Debug>(&self, value: Type) -> impl Handle {
96 self.layout.write(|layout| layout.push(Item::String(format!("{value:#?}"))));
97 return Action;
98 }
99}