Skip to main content

libutils_terminal/
mod.rs

1//^
2//^ HEAD
3//^
4
5//> HEAD -> FEATURES
6#![feature(const_trait_impl)]
7#![feature(const_default)]
8
9//> HEAD -> MODULES
10mod continuations;
11mod problem;
12mod section;
13#[cfg(test)]
14mod tests;
15
16//> HEAD -> STD
17use std::{
18    env::args, 
19    sync::LazyLock,
20    fs::File,
21    path::PathBuf
22};
23
24//> HEAD -> CORE
25use core::fmt::{
26    Display,
27    Debug
28};
29
30//> HEAD -> CAGE
31use libutils_cage::Cage;
32
33//> HEAD -> PROBLEM
34use libutils_threat::Threat;
35
36//> HEAD -> CONTINUATIONS
37use continuations::{
38    ActionRequired,
39    FileDescriptor
40};
41
42//> HEAD -> ISSUE
43use libutils_issue::{
44    Issue,
45    Severity
46};
47
48//> HEAD -> CONSOLE
49use libutils_console::{
50    Console,
51    Argument,
52    Synchronization,
53    Descriptor
54};
55
56//> HEAD -> SECTION
57use section::Section;
58
59
60//^
61//^ TERMINAL
62//^
63
64//> TERMINAL -> INSTANCE
65pub static TERMINAL: Terminal = Terminal {
66    arguments: LazyLock::new(|| args().map(Argument::from).collect()),
67    layout: Cage::default(),
68    output: Cage::default()
69};
70
71//> TERMINAL -> STRUCT
72pub struct Terminal {
73    arguments: LazyLock<Vec<Argument>>,
74    layout: Cage<Vec<Section>>,
75    output: Cage<String>
76}
77
78//> TERMINAL -> IMPLEMENTATION
79impl Console for Terminal {
80    #[inline]
81    fn arguments<'valid>(&'valid self) -> &'valid [Argument] {return self.arguments.as_slice()}
82    #[inline]
83    fn open(&self, filename: &str) -> Result<impl Descriptor, Issue> {match File::open(PathBuf::from(filename)) {
84        Ok(file) => Ok(FileDescriptor {
85            file: file
86        }),
87        Err(error) => Err(Issue {
88            name: "Failed to open file",
89            description: Some(error.to_string()),
90            severity: Severity::Error
91        })
92    }}
93    #[inline]
94    fn problem(&self, threat: Threat) -> impl Synchronization {
95        self.layout.write(|layout| layout.push(Section::Problem(threat.into())));
96        return ActionRequired;
97    }
98    #[inline]
99    fn print(&self, value: impl Display) -> impl Synchronization {
100        self.layout.write(|layout| layout.push(Section::Display(value.to_string())));
101        return ActionRequired;
102    }
103    #[inline]
104    fn debug(&self, value: impl Debug) -> impl Synchronization {
105        self.layout.write(|layout| layout.push(Section::Debug(format!("{value:#?}"))));
106        return ActionRequired;
107    }
108}