Skip to content

Commit af5568a

Browse files
author
Noam Lewis
committed
modules helpppp
1 parent ee8ba3f commit af5568a

File tree

3 files changed

+173
-178
lines changed

3 files changed

+173
-178
lines changed

src/chunks.rs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
use std::slice::{RSplit, Split};
2+
3+
use crate::LoadedLine;
4+
5+
pub struct Chunk<'a> {
6+
file_offset: u64,
7+
is_modified: bool,
8+
data: &'a [char],
9+
}
10+
11+
impl Chunk<'_> {
12+
pub fn from_disk(file_offset: u64, data: &[char]) -> Chunk {
13+
Chunk {
14+
file_offset,
15+
is_modified: false,
16+
data,
17+
}
18+
}
19+
20+
pub fn lines_iter(&self) -> ChunkLinesIter {
21+
ChunkLinesIter {
22+
chunk: self,
23+
forward: self.data.split(Box::new(|c: &char| *c == '\n')),
24+
back: self.data.rsplit(Box::new(|c: &char| *c == '\n')),
25+
}
26+
}
27+
}
28+
29+
pub struct ChunkLinesIter<'a> {
30+
chunk: &'a Chunk<'a>,
31+
forward: Split<'a, char, Box<dyn FnMut(&char) -> bool>>,
32+
back: RSplit<'a, char, Box<dyn FnMut(&char) -> bool>>,
33+
}
34+
35+
impl<'a> Iterator for ChunkLinesIter<'a> {
36+
type Item = LoadedLine;
37+
38+
fn next(&mut self) -> Option<Self::Item> {
39+
let line = self.forward.next();
40+
return line.map(LoadedLine::new);
41+
}
42+
}
43+
44+
impl<'a> DoubleEndedIterator for ChunkLinesIter<'a> {
45+
fn next_back(&mut self) -> Option<Self::Item> {
46+
let line = self.back.next();
47+
return line.map(LoadedLine::new);
48+
}
49+
}
50+
51+
#[cfg(test)]
52+
mod tests {
53+
54+
use chunks::Chunk;
55+
56+
#[test]
57+
fn test_chunk_lines_iter() {
58+
let data: Vec<char> = "line1\nline2\nline3\n".chars().collect();
59+
let chunk = Chunk::from_disk(0, &data);
60+
let mut iter = chunk.lines_iter();
61+
62+
assert_eq!(
63+
iter.next().unwrap().chars_iter().collect::<String>(),
64+
"line1"
65+
);
66+
assert_eq!(
67+
iter.next().unwrap().chars_iter().collect::<String>(),
68+
"line2"
69+
);
70+
assert_eq!(
71+
iter.next().unwrap().chars_iter().collect::<String>(),
72+
"line3"
73+
);
74+
75+
assert_eq!(iter.next().unwrap().chars_iter().collect::<String>(), "");
76+
assert!(iter.next().is_none());
77+
}
78+
79+
#[test]
80+
fn test_chunk_lines_iter_empty() {
81+
let data: Vec<char> = "".chars().collect();
82+
let chunk = Chunk::from_disk(0, &data);
83+
let mut iter = chunk.lines_iter();
84+
85+
assert_eq!(iter.next().unwrap().chars_iter().collect::<String>(), "");
86+
assert!(iter.next().is_none());
87+
}
88+
89+
#[test]
90+
fn test_chunk_lines_iter_no_newline() {
91+
let data: Vec<char> = "line1".chars().collect();
92+
let chunk = Chunk::from_disk(0, &data);
93+
let mut iter = chunk.lines_iter();
94+
95+
assert_eq!(
96+
iter.next().unwrap().chars_iter().collect::<String>(),
97+
"line1"
98+
);
99+
assert!(iter.next().is_none());
100+
}
101+
102+
#[test]
103+
fn test_chunk_lines_iter_double_ended() {
104+
let data: Vec<char> = "line1\nline2\nline3\n".chars().collect();
105+
let chunk = Chunk::from_disk(0, &data);
106+
let mut iter = chunk.lines_iter();
107+
108+
assert_eq!(
109+
iter.next_back().unwrap().chars_iter().collect::<String>(),
110+
""
111+
);
112+
assert_eq!(
113+
iter.next_back().unwrap().chars_iter().collect::<String>(),
114+
"line3"
115+
);
116+
assert_eq!(
117+
iter.next_back().unwrap().chars_iter().collect::<String>(),
118+
"line2"
119+
);
120+
assert_eq!(
121+
iter.next_back().unwrap().chars_iter().collect::<String>(),
122+
"line1"
123+
);
124+
assert!(iter.next_back().is_none());
125+
}
126+
}

src/lines.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
pub struct LoadedLine {
2+
chars: Vec<char>,
3+
}
4+
5+
impl LoadedLine {
6+
pub fn empty() -> LoadedLine {
7+
LoadedLine { chars: vec![] }
8+
}
9+
pub fn new(chars: &[char]) -> LoadedLine {
10+
LoadedLine {
11+
chars: Vec::from(chars),
12+
}
13+
}
14+
pub fn from_vec(chars: Vec<char>) -> LoadedLine {
15+
LoadedLine { chars: chars }
16+
}
17+
pub fn len(&self) -> usize {
18+
self.chars.len()
19+
}
20+
pub fn push(&mut self, c: char) {
21+
self.chars.push(c);
22+
}
23+
pub fn insert(&mut self, index: usize, c: char) {
24+
self.chars.insert(index, c);
25+
}
26+
pub fn remove(&mut self, index: usize) {
27+
self.chars.remove(index);
28+
}
29+
pub fn extend(&mut self, line: LoadedLine) {
30+
self.chars.extend(line.chars);
31+
}
32+
pub fn char_get_mut(&mut self, index: usize) -> Option<&mut char> {
33+
self.chars.get_mut(index)
34+
}
35+
pub fn char_get(&self, index: usize) -> Option<&char> {
36+
self.chars.get(index)
37+
}
38+
pub fn split_off(&mut self, x: usize) -> Vec<char> {
39+
self.chars.split_off(x)
40+
}
41+
pub fn chars_iter(&self) -> std::slice::Iter<'_, char> {
42+
self.chars.iter()
43+
}
44+
}

src/main.rs

Lines changed: 3 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::{
66
iter::FromIterator,
77
};
88

9+
use crate::lines::LoadedLine;
910
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyModifiers};
1011
use ratatui::{
1112
layout::{Position, Rect, Size},
@@ -14,184 +15,8 @@ use ratatui::{
1415
DefaultTerminal, Frame,
1516
};
1617

17-
mod lines {
18-
pub struct LoadedLine {
19-
chars: Vec<char>,
20-
}
21-
22-
impl LoadedLine {
23-
pub fn empty() -> LoadedLine {
24-
LoadedLine { chars: vec![] }
25-
}
26-
pub fn new(chars: &[char]) -> LoadedLine {
27-
LoadedLine {
28-
chars: Vec::from(chars),
29-
}
30-
}
31-
pub fn from_vec(chars: Vec<char>) -> LoadedLine {
32-
LoadedLine { chars: chars }
33-
}
34-
pub fn len(&self) -> usize {
35-
self.chars.len()
36-
}
37-
pub fn push(&mut self, c: char) {
38-
self.chars.push(c);
39-
}
40-
pub fn insert(&mut self, index: usize, c: char) {
41-
self.chars.insert(index, c);
42-
}
43-
pub fn remove(&mut self, index: usize) {
44-
self.chars.remove(index);
45-
}
46-
pub fn extend(&mut self, line: LoadedLine) {
47-
self.chars.extend(line.chars);
48-
}
49-
pub fn char_get_mut(&mut self, index: usize) -> Option<&mut char> {
50-
self.chars.get_mut(index)
51-
}
52-
pub fn char_get(&self, index: usize) -> Option<&char> {
53-
self.chars.get(index)
54-
}
55-
pub fn split_off(&mut self, x: usize) -> Vec<char> {
56-
self.chars.split_off(x)
57-
}
58-
pub fn chars_iter(&self) -> std::slice::Iter<'_, char> {
59-
self.chars.iter()
60-
}
61-
}
62-
}
63-
64-
mod chunks {
65-
66-
use std::slice::{RSplit, Split};
67-
68-
use crate::lines::LoadedLine;
69-
70-
pub struct Chunk<'a> {
71-
file_offset: u64,
72-
is_modified: bool,
73-
data: &'a [char],
74-
}
75-
76-
impl Chunk<'_> {
77-
pub fn from_disk(file_offset: u64, data: &[char]) -> Chunk {
78-
Chunk {
79-
file_offset,
80-
is_modified: false,
81-
data,
82-
}
83-
}
84-
85-
pub fn lines_iter(&self) -> ChunkLinesIter {
86-
ChunkLinesIter {
87-
chunk: self,
88-
forward: self.data.split(Box::new(|c: &char| *c == '\n')),
89-
back: self.data.rsplit(Box::new(|c: &char| *c == '\n')),
90-
}
91-
}
92-
}
93-
94-
pub struct ChunkLinesIter<'a> {
95-
chunk: &'a Chunk<'a>,
96-
forward: Split<'a, char, Box<dyn FnMut(&char) -> bool>>,
97-
back: RSplit<'a, char, Box<dyn FnMut(&char) -> bool>>,
98-
}
99-
100-
impl<'a> Iterator for ChunkLinesIter<'a> {
101-
type Item = LoadedLine;
102-
103-
fn next(&mut self) -> Option<Self::Item> {
104-
let line = self.forward.next();
105-
return line.map(LoadedLine::new);
106-
}
107-
}
108-
109-
impl<'a> DoubleEndedIterator for ChunkLinesIter<'a> {
110-
fn next_back(&mut self) -> Option<Self::Item> {
111-
let line = self.back.next();
112-
return line.map(LoadedLine::new);
113-
}
114-
}
115-
}
116-
117-
#[cfg(test)]
118-
mod tests {
119-
120-
use chunks::Chunk;
121-
122-
#[test]
123-
fn test_chunk_lines_iter() {
124-
let data: Vec<char> = "line1\nline2\nline3\n".chars().collect();
125-
let chunk = Chunk::from_disk(0, &data);
126-
let mut iter = chunk.lines_iter();
127-
128-
assert_eq!(
129-
iter.next().unwrap().chars_iter().collect::<String>(),
130-
"line1"
131-
);
132-
assert_eq!(
133-
iter.next().unwrap().chars_iter().collect::<String>(),
134-
"line2"
135-
);
136-
assert_eq!(
137-
iter.next().unwrap().chars_iter().collect::<String>(),
138-
"line3"
139-
);
140-
141-
assert_eq!(iter.next().unwrap().chars_iter().collect::<String>(), "");
142-
assert!(iter.next().is_none());
143-
}
144-
145-
#[test]
146-
fn test_chunk_lines_iter_empty() {
147-
let data: Vec<char> = "".chars().collect();
148-
let chunk = Chunk::from_disk(0, &data);
149-
let mut iter = chunk.lines_iter();
150-
151-
assert_eq!(iter.next().unwrap().chars_iter().collect::<String>(), "");
152-
assert!(iter.next().is_none());
153-
}
154-
155-
#[test]
156-
fn test_chunk_lines_iter_no_newline() {
157-
let data: Vec<char> = "line1".chars().collect();
158-
let chunk = Chunk::from_disk(0, &data);
159-
let mut iter = chunk.lines_iter();
160-
161-
assert_eq!(
162-
iter.next().unwrap().chars_iter().collect::<String>(),
163-
"line1"
164-
);
165-
assert!(iter.next().is_none());
166-
}
167-
168-
#[test]
169-
fn test_chunk_lines_iter_double_ended() {
170-
let data: Vec<char> = "line1\nline2\nline3\n".chars().collect();
171-
let chunk = Chunk::from_disk(0, &data);
172-
let mut iter = chunk.lines_iter();
173-
174-
assert_eq!(
175-
iter.next_back().unwrap().chars_iter().collect::<String>(),
176-
""
177-
);
178-
assert_eq!(
179-
iter.next_back().unwrap().chars_iter().collect::<String>(),
180-
"line3"
181-
);
182-
assert_eq!(
183-
iter.next_back().unwrap().chars_iter().collect::<String>(),
184-
"line2"
185-
);
186-
assert_eq!(
187-
iter.next_back().unwrap().chars_iter().collect::<String>(),
188-
"line1"
189-
);
190-
assert!(iter.next_back().is_none());
191-
}
192-
}
193-
194-
use lines::LoadedLine;
18+
pub mod chunks;
19+
pub mod lines;
19520

19621
// TODO
19722
// How to represent edited content?

0 commit comments

Comments
 (0)