Skip to main content

libutils_terminal/
mod.rs

1//^
2//^ HEAD
3//^
4
5//> HEAD -> FEATURES
6#![feature(default_field_values)]
7#![feature(const_trait_impl)]
8
9//> HEAD -> MODULES
10mod argument;
11mod console;
12mod layout;
13mod problem;
14#[cfg(test)]
15mod tests;
16
17//> HEAD -> STD
18use std::{
19    collections::HashMap as Map, 
20    env::{
21        args,
22        vars
23    }, 
24    io::{
25        Write, 
26        stderr
27    }, 
28    sync::LazyLock
29};
30
31//> HEAD -> CAGE
32use libutils_cage::Cage;
33
34//> HEAD -> PROBLEM
35use libutils_threat::Threat;
36
37//> HEAD -> DIFF
38use libutils_diff::Diff;
39
40//> HEAD -> LAYOUT
41use layout::Layout;
42
43//> HEAD -> CONSOLE
44pub use console::Console;
45
46//> HEAD -> ARGUMENT
47pub use argument::Argument;
48
49
50//^
51//^ TERMINAL
52//^
53
54//> TERMINAL -> INSTANCE
55pub static TERMINAL: Cage<Terminal> = Cage::new(Terminal {..});
56
57//> TERMINAL -> STRUCT
58pub struct Terminal {
59    layout: Layout = Layout {..},
60    arguments: LazyLock<Vec<Argument>> = LazyLock::new(|| args().map(Argument::from).collect()),
61    pub environment: LazyLock<Map<String, String>> = LazyLock::new(|| vars().collect()),
62    stderr: String = String::new()
63}
64
65//> TERMINAL -> IMPLEMENTATION
66impl Console for Terminal {
67    #[inline]
68    fn arguments(&self) -> &[Argument] {return self.arguments.as_slice()}
69    #[inline]
70    fn sync(&mut self) -> () {
71        let content = self.layout.view();
72        stderr().lock().write(<Diff as Into<Vec<u8>>>::into(Diff::new(self.stderr.as_bytes(), content.as_bytes())).as_ref()).unwrap();
73        self.stderr = content;
74    }
75    #[inline]
76    fn problem(&mut self, threat: Threat) -> () {self.layout.problems.push(threat.into())}
77}