1use std::env;
2use thiserror::Error;
3
4use crate::document::{DocError, Document};
5use crate::input::{Input, InputError};
6use crate::log::Log;
7use crate::screen::Screen;
8use crate::terminal::{TermError, Terminal};
9
10#[derive(Error, Debug)]
11pub enum PhantomError {
12 #[error("Terminal Err: {0}")]
13 Terminal(TermError), #[error("Document Err: {0}")]
15 Document(DocError),
16 #[error("Input Err: {0}")]
17 Input(InputError),
18}
19impl From<TermError> for PhantomError {
20 fn from(err: TermError) -> PhantomError {
21 PhantomError::Terminal(err)
22 }
23}
24impl From<DocError> for PhantomError {
25 fn from(err: DocError) -> PhantomError {
26 PhantomError::Document(err)
27 }
28}
29impl From<InputError> for PhantomError {
30 fn from(err: InputError) -> PhantomError {
31 PhantomError::Input(err)
32 }
33}
34
35pub type PResult<T> = std::result::Result<T, PhantomError>;
36
37pub struct Phantom {
38 term: Terminal,
39 documents: Vec<Document>,
40 input: Input,
41 log: Log,
42 screen: Screen,
43}
44
45impl Phantom {
46 pub fn new() -> PResult<Self> {
48 let args: Vec<String> = env::args().collect();
49
50 let mut doc_vec: Vec<Document> = Vec::new();
51 doc_vec.push(if let Some(file_name) = args.get(1) {
52 Document::open(file_name)?
53 } else {
54 Document::new()
55 });
56
57 Ok(Self {
58 term: Terminal::new()?,
59 documents: doc_vec,
60 input: Input::new(),
61 log: Log::new(),
62 screen: Screen::new(),
63 })
64 }
65
66 pub fn run(&mut self) -> PResult<()> {
68 loop {
69 self.refresh()?;
71 self.input.input_handler(&mut self.term)?;
72 }
73 }
74
75 fn refresh(&mut self) -> PResult<()> {
77 self.term.cursor_hide()?;
78
79 Ok(())
80 }
81
82 fn clear_screen(&mut self) -> PResult<()> {
83 Ok(self.term.clear_screen()?.cursor_position(0, 0)?.flush()?)
84 }
85}