From 4a62372fd3b24e9ef12a84d3aaeb4fdd1cd9c764 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Mon, 6 May 2024 00:58:17 -0400 Subject: [PATCH] Extract several components into crates --- editor-challenge/src/main.rs | 119 +++------------------------------- editor-challenge/src/state.rs | 42 ++++++++++++ editor-challenge/src/types.rs | 77 ++++++++++++++++++++++ 3 files changed, 127 insertions(+), 111 deletions(-) create mode 100644 editor-challenge/src/state.rs create mode 100644 editor-challenge/src/types.rs diff --git a/editor-challenge/src/main.rs b/editor-challenge/src/main.rs index 640d096..4631cb0 100644 --- a/editor-challenge/src/main.rs +++ b/editor-challenge/src/main.rs @@ -1,12 +1,14 @@ +mod state; +mod types; + use crossterm::{ event::{self, KeyCode, KeyEvent, KeyModifiers}, terminal::{disable_raw_mode, enable_raw_mode}, }; +use state::AppState; use std::{ env, - fs::File, - io::{self, BufRead, BufReader, Read}, - path::PathBuf, + io, sync::mpsc, thread, time::{Duration, Instant}, @@ -23,112 +25,6 @@ const TITLE: &str = "Text Editor Challenge"; const COPYRIGHT: &str = "(c) Savanni D'Gerinel - all rights reserved"; const TICK_RATE_MS: u64 = 200; -#[derive(Default)] -struct Document { - rows: Vec -} - -impl Document { - fn contents(&self) -> String { - self.rows.join("\n") - } - - fn row_length(&self, idx: usize) -> usize { - self.rows[idx].len() - } - - fn row_count(&self) -> usize { - self.rows.len() - } -} - -#[derive(Default)] -struct AppState { - path: Option, - cursor: Cursor, - contents: Document, // Obviously this is bad, but it's also only temporary. -} - -impl AppState { - fn open(path: PathBuf) -> Self { - let mut file = File::open(path.clone()).unwrap(); - let mut reader = BufReader::new(file); - let contents = reader - .lines() - .collect::, std::io::Error>>() - .unwrap(); - - Self { - path: Some(path), - cursor: Default::default(), - contents: Document{ rows: contents }, - } - } - - fn cursor_up(&mut self) { - self.cursor.cursor_up(&self.contents); - } - - fn cursor_down(&mut self) { - self.cursor.cursor_down(&self.contents); - } - - fn cursor_right(&mut self) { - self.cursor.cursor_right(&self.contents); - } - - fn cursor_left(&mut self) { - self.cursor.cursor_left(); - } -} - -#[derive(Default)] -struct Cursor { - row: usize, - column: usize, - desired_column: usize, -} - -impl Cursor { - fn cursor_up(&mut self, doc: &Document) { - if self.row > 0 { - self.row -= 1; - } - self.correct_columns(doc); - } - - fn cursor_down(&mut self, doc: &Document) { - if self.row < doc.row_count() - 1 { - self.row += 1; - } - self.correct_columns(doc); - } - - fn correct_columns(&mut self, doc: &Document) { - let row_len = doc.row_length(self.row); - if self.desired_column < row_len { - self.column = self.desired_column; - } else { - self.column = row_len; - } - } - - fn cursor_right(&mut self, doc: &Document) { - if self.column < doc.row_length(self.row) { - self.column += 1; - } - self.desired_column = self.column; - } - - fn cursor_left(&mut self) { - if self.column > 0 { - self.column -= 1; - } - self.desired_column = self.column; - } - -} - fn render(app_state: &AppState, terminal: &mut Terminal) -> Result<(), anyhow::Error> where T: tui::backend::Backend, @@ -183,8 +79,9 @@ where rect.render_widget(contents, chunks[1]); // TODO: keeping track of the index of the top row and subtract that from the cursor row. - let row = app_state.cursor.row as u16; - let column = app_state.cursor.column as u16; + let (row, column) = app_state.cursor.addr(); + let row = row as u16; + let column = column as u16; rect.set_cursor(chunks[1].x + column, chunks[1].y + row); })?; Ok(()) diff --git a/editor-challenge/src/state.rs b/editor-challenge/src/state.rs new file mode 100644 index 0000000..3c3c46f --- /dev/null +++ b/editor-challenge/src/state.rs @@ -0,0 +1,42 @@ +use crate::types::{Cursor, Document}; +use std::{fs::File, io::{BufRead, BufReader}, path::PathBuf}; + +#[derive(Default)] +pub struct AppState { + pub path: Option, + pub cursor: Cursor, + pub contents: Document, // Obviously this is bad, but it's also only temporary. +} + +impl AppState { + pub fn open(path: PathBuf) -> Self { + let file = File::open(path.clone()).unwrap(); + let reader = BufReader::new(file); + let contents = reader + .lines() + .collect::, std::io::Error>>() + .unwrap(); + + Self { + path: Some(path), + cursor: Default::default(), + contents: Document::new(contents), + } + } + + pub fn cursor_up(&mut self) { + self.cursor.cursor_up(&self.contents); + } + + pub fn cursor_down(&mut self) { + self.cursor.cursor_down(&self.contents); + } + + pub fn cursor_right(&mut self) { + self.cursor.cursor_right(&self.contents); + } + + pub fn cursor_left(&mut self) { + self.cursor.cursor_left(); + } +} diff --git a/editor-challenge/src/types.rs b/editor-challenge/src/types.rs new file mode 100644 index 0000000..2d52271 --- /dev/null +++ b/editor-challenge/src/types.rs @@ -0,0 +1,77 @@ +#[derive(Default)] +pub struct Document { + rows: Vec +} + +impl Document { + pub fn new(contents: Vec) -> Self { + Self{ + rows: contents + } + } + + pub fn contents(&self) -> String { + self.rows.join("\n") + } + + pub fn row_length(&self, idx: usize) -> usize { + self.rows[idx].len() + } + + pub fn row_count(&self) -> usize { + self.rows.len() + } +} + +#[derive(Default)] +pub struct Cursor { + row: usize, + column: usize, + desired_column: usize, +} + +impl Cursor { + pub fn addr(&self) -> (usize, usize) { + (self.row, self.column) + } + + pub fn cursor_up(&mut self, doc: &Document) { + if self.row > 0 { + self.row -= 1; + } + self.correct_columns(doc); + } + + pub fn cursor_down(&mut self, doc: &Document) { + if self.row < doc.row_count() - 1 { + self.row += 1; + } + self.correct_columns(doc); + } + + pub fn correct_columns(&mut self, doc: &Document) { + let row_len = doc.row_length(self.row); + if self.desired_column < row_len { + self.column = self.desired_column; + } else { + self.column = row_len; + } + } + + pub fn cursor_right(&mut self, doc: &Document) { + if self.column < doc.row_length(self.row) { + self.column += 1; + } + self.desired_column = self.column; + } + + pub fn cursor_left(&mut self) { + if self.column > 0 { + self.column -= 1; + } + self.desired_column = self.column; + } + +} + +