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
129
130
131
132
133
134
135
use rlp::{Rlp, Decodable, DecoderError};
pub struct ViewRlp<'a> {
pub rlp: Rlp<'a>,
file: &'a str,
line: u32,
}
impl<'a, 'view> ViewRlp<'a> where 'a : 'view {
#[doc(hidden)]
pub fn new(bytes: &'a [u8], file: &'a str, line: u32) -> Self {
ViewRlp {
rlp: Rlp::new(bytes),
file,
line
}
}
fn new_from_rlp(&self, rlp: Rlp<'a>) -> Self {
ViewRlp {
rlp,
file: self.file,
line: self.line
}
}
fn maybe_at(&self, index: usize) -> Option<ViewRlp<'a>> {
self.rlp.at(index)
.map(|rlp| self.new_from_rlp(rlp))
.ok()
}
fn expect_valid_rlp<T>(&self, r: Result<T, DecoderError>) -> T {
r.unwrap_or_else(|e| panic!(
"View rlp is trusted and should be valid. Constructed in {} on line {}: {}",
self.file,
self.line,
e
))
}
pub fn at(&self, index: usize) -> ViewRlp<'a> {
let rlp = self.expect_valid_rlp(self.rlp.at(index));
self.new_from_rlp(rlp)
}
pub fn iter(&'view self) -> ViewRlpIterator<'a, 'view> {
self.into_iter()
}
pub fn as_val<T>(&self) -> T where T: Decodable {
self.expect_valid_rlp(self.rlp.as_val())
}
pub fn val_at<T>(&self, index: usize) -> T where T : Decodable {
self.expect_valid_rlp(self.rlp.val_at(index))
}
pub fn list_at<T>(&self, index: usize) -> Vec<T> where T: Decodable {
self.expect_valid_rlp(self.rlp.list_at(index))
}
pub fn item_count(&self) -> usize {
self.expect_valid_rlp(self.rlp.item_count())
}
pub fn as_raw(&'view self) -> &'a [u8] {
self.rlp.as_raw()
}
}
pub struct ViewRlpIterator<'a, 'view> where 'a: 'view {
rlp: &'view ViewRlp<'a>,
index: usize,
}
impl<'a, 'view> IntoIterator for &'view ViewRlp<'a> where 'a: 'view {
type Item = ViewRlp<'a>;
type IntoIter = ViewRlpIterator<'a, 'view>;
fn into_iter(self) -> Self::IntoIter {
ViewRlpIterator {
rlp: self,
index: 0,
}
}
}
impl<'a, 'view> Iterator for ViewRlpIterator<'a, 'view> {
type Item = ViewRlp<'a>;
fn next(&mut self) -> Option<ViewRlp<'a>> {
let index = self.index;
let result = self.rlp.maybe_at(index);
self.index += 1;
result
}
}
#[macro_export]
macro_rules! view {
($view: ident, $bytes: expr) => {
$view::new($crate::views::ViewRlp::new($bytes, file!(), line!()))
};
}