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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use std::borrow::Cow;
use crate::Op;
#[derive(Debug, Clone)]
pub struct Frame<'a> {
body: Cow<'a, str>,
ptr: usize,
op: Option<Op>,
}
impl<'a> Frame<'a> {
pub fn parse<S>(s: S) -> Frame<'a>
where
S: Into<Cow<'a, str>>,
{
let mut ret = Frame { body: s.into(), ptr: 0, op: None };
ret.advance();
ret
}
pub fn compress(ops: Vec<Op>) -> Self {
if ops.is_empty() {
return Self::parse("");
}
let mut txt = ops[0].compress(None);
for win in ops[..].windows(2) {
txt += &win[1].compress(Some(&win[0]));
}
Self::parse(txt)
}
pub fn peek<'b>(&'b self) -> Option<&'b Op> {
if self.ptr > self.body.len() {
None
} else {
self.op.as_ref()
}
}
pub fn body(&self) -> &str {
&self.body
}
fn advance(&mut self) {
if self.ptr < self.body.len() {
let input = &self.body[self.ptr..];
match Op::parse_inplace(&mut self.op, input) {
Some(p) => {
self.ptr =
p.as_ptr() as usize - self.body[..].as_ptr() as usize;
}
None => {
self.ptr = self.body.len() + 1;
}
}
} else {
self.ptr = self.body.len() + 1;
}
}
}
impl<'a> Iterator for Frame<'a> {
type Item = Op;
fn next(&mut self) -> Option<Self::Item> {
if self.ptr > self.body.len() {
None
} else {
if let Some(op) = self.op.clone() {
self.advance();
Some(op)
} else {
None
}
}
}
}
#[test]
fn count() {
let frame = "*lww#test@0:0! @1:key'value' @2:number=1 *rga#text@3:0'T'! *rga#text@6:3, @4'e' @5'x' @6't' *lww#more:a=1;.";
let frame = Frame::parse(frame);
assert_eq!(frame.count(), 9);
}
#[test]
fn iter() {
let frame = "*lww#test@0:0!@1:key'value'@2:number=1*rga#text@3:0'T'!*rga#text@6:3,@4'e'@5'x'@6't'*lww#more:a=1;.";
let mut frame = Frame::parse(frame);
while let op @ Some(_) = frame.peek().cloned() {
assert_eq!(op, frame.next());
}
}
#[test]
fn iter2() {
let frame = "*rga#test:0!@4'D'@5'E'";
let mut frame = Frame::parse(frame);
while let op @ Some(_) = frame.peek().cloned() {
assert_eq!(op, frame.next());
}
}
#[test]
fn empty_string() {
use crate::Atom;
let mut frame = Frame::parse("*lww#raw@1:one'';");
let op = frame.next().unwrap();
eprintln!("{:?}", op);
assert_eq!(op.atoms[0], Atom::String(String::default()))
}