1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
use std::fmt::{Display, Error, Formatter};
use std::fs::File;
use std::io::{ErrorKind, Read};
use std::path::Path;
use std::rc::Rc;
// Set to a small value to help identify bugs in the implementation.
const MAX_NODE_SIZE: usize = 4;
struct Branch {
len: usize,
left: Rc<Node>,
right: Rc<Node>,
}
enum Node {
Leaf(Vec<u8>),
Branch(Branch),
}
impl Node {
fn len(&self) -> usize {
return match self {
Node::Leaf(v) => v.len(),
Node::Branch(b) => b.len,
};
}
fn write(&self, out: &mut Vec<u8>) {
match self {
Node::Leaf(v) => {
out.extend(v);
}
Node::Branch(b) => {
b.left.write(out);
b.right.write(out);
}
}
}
}
impl Display for Node {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let mut buf = Vec::new();
self.write(&mut buf);
return write!(f, "{}", String::from_utf8_lossy(&buf));
}
}
pub struct Rope(Rc<Node>);
impl Rope {
fn concat(self, Rope(other): Rope) -> Rope {
let Rope(me) = self;
if me.len() == 0 {
return Rope(other);
}
if other.len() == 0 {
return Rope(me);
}
return Rope(Rc::new(Node::Branch(Branch {
len: me.len() + other.len(),
left: me,
right: other,
})));
}
pub fn open(path: &Path) -> Result<Rope, String> {
let mut f = match File::open(path) {
Ok(f) => f,
Err(err) => {
return Err(format!("open: {}", err));
}
};
let mut rope = Rope(Rc::new(Node::Leaf(vec![])));
loop {
let mut buf = vec![0; MAX_NODE_SIZE];
let n = match f.read(&mut buf) {
Ok(n) => n,
Err(err) => {
if err.kind() == ErrorKind::Interrupted {
continue;
}
return Err(format!("read: {}", err));
}
};
if n == 0 {
break;
}
rope = rope.concat(Rope(Rc::new(Node::Leaf(buf))));
}
return Ok(rope);
}
}
impl Display for Rope {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
let Rope(n) = self;
return write!(f, "{}", n);
}
}
|