esvm_rlp/rlpin.rs
1// Copyright 2015-2017 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::fmt;
10use {UntrustedRlp, PayloadInfo, Prototype, Decodable};
11
12impl<'a> From<UntrustedRlp<'a>> for Rlp<'a> {
13 fn from(rlp: UntrustedRlp<'a>) -> Rlp<'a> {
14 Rlp { rlp: rlp }
15 }
16}
17
18/// Data-oriented view onto trusted rlp-slice.
19///
20/// Unlikely to `UntrustedRlp` doesn't bother you with error
21/// handling. It assumes that you know what you are doing.
22#[derive(Debug)]
23pub struct Rlp<'a> {
24 rlp: UntrustedRlp<'a>
25}
26
27impl<'a> fmt::Display for Rlp<'a> {
28 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
29 write!(f, "{}", self.rlp)
30 }
31}
32
33impl<'a, 'view> Rlp<'a> where 'a: 'view {
34 /// Create a new instance of `Rlp`
35 pub fn new(bytes: &'a [u8]) -> Rlp<'a> {
36 Rlp {
37 rlp: UntrustedRlp::new(bytes)
38 }
39 }
40
41 /// The raw data of the RLP as slice.
42 ///
43 /// ```rust
44 /// extern crate rlp;
45 /// use rlp::*;
46 ///
47 /// fn main () {
48 /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
49 /// let rlp = Rlp::new(&data);
50 /// let dog = rlp.at(1).as_raw();
51 /// assert_eq!(dog, &[0x83, b'd', b'o', b'g']);
52 /// }
53 /// ```
54 pub fn as_raw(&'view self) -> &'a [u8] {
55 self.rlp.as_raw()
56 }
57
58 /// Get the prototype of the RLP.
59 pub fn prototype(&self) -> Prototype {
60 self.rlp.prototype().unwrap()
61 }
62
63 /// Get payload info.
64 pub fn payload_info(&self) -> PayloadInfo {
65 self.rlp.payload_info().unwrap()
66 }
67
68 /// Get underlieing data.
69 pub fn data(&'view self) -> &'a [u8] {
70 self.rlp.data().unwrap()
71 }
72
73 /// Returns number of RLP items.
74 ///
75 /// ```rust
76 /// extern crate rlp;
77 /// use rlp::*;
78 ///
79 /// fn main () {
80 /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
81 /// let rlp = Rlp::new(&data);
82 /// assert_eq!(rlp.item_count(), 2);
83 /// let view = rlp.at(1);
84 /// assert_eq!(view.item_count(), 0);
85 /// }
86 /// ```
87 pub fn item_count(&self) -> usize {
88 self.rlp.item_count().unwrap_or(0)
89 }
90
91 /// Returns the number of bytes in the data, or zero if it isn't data.
92 ///
93 /// ```rust
94 /// extern crate rlp;
95 /// use rlp::*;
96 ///
97 /// fn main () {
98 /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
99 /// let rlp = Rlp::new(&data);
100 /// assert_eq!(rlp.size(), 0);
101 /// let view = rlp.at(1);
102 /// assert_eq!(view.size(), 3);
103 /// }
104 /// ```
105 pub fn size(&self) -> usize {
106 self.rlp.size()
107 }
108
109 /// Get view onto RLP-slice at index.
110 ///
111 /// Caches offset to given index, so access to successive
112 /// slices is faster.
113 ///
114 /// ```rust
115 /// extern crate rlp;
116 /// use rlp::*;
117 ///
118 /// fn main () {
119 /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
120 /// let rlp = Rlp::new(&data);
121 /// let dog: String = rlp.at(1).as_val();
122 /// assert_eq!(dog, "dog".to_string());
123 /// }
124 /// ```
125 pub fn at(&'view self, index: usize) -> Rlp<'a> {
126 From::from(self.rlp.at(index).unwrap())
127 }
128
129 /// No value
130 ///
131 /// ```rust
132 /// extern crate rlp;
133 /// use rlp::*;
134 ///
135 /// fn main () {
136 /// let data = vec![];
137 /// let rlp = Rlp::new(&data);
138 /// assert!(rlp.is_null());
139 /// }
140 /// ```
141 pub fn is_null(&self) -> bool {
142 self.rlp.is_null()
143 }
144
145 /// Contains a zero-length string or zero-length list.
146 ///
147 /// ```rust
148 /// extern crate rlp;
149 /// use rlp::*;
150 ///
151 /// fn main () {
152 /// let data = vec![0xc0];
153 /// let rlp = Rlp::new(&data);
154 /// assert!(rlp.is_empty());
155 /// }
156 /// ```
157 pub fn is_empty(&self) -> bool {
158 self.rlp.is_empty()
159 }
160
161 /// List value
162 ///
163 /// ```rust
164 /// extern crate rlp;
165 /// use rlp::*;
166 ///
167 /// fn main () {
168 /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
169 /// let rlp = Rlp::new(&data);
170 /// assert!(rlp.is_list());
171 /// }
172 /// ```
173 pub fn is_list(&self) -> bool {
174 self.rlp.is_list()
175 }
176
177 /// String value
178 ///
179 /// ```rust
180 /// extern crate rlp;
181 /// use rlp::*;
182 ///
183 /// fn main () {
184 /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
185 /// let rlp = Rlp::new(&data);
186 /// assert!(rlp.at(1).is_data());
187 /// }
188 /// ```
189 pub fn is_data(&self) -> bool {
190 self.rlp.is_data()
191 }
192
193 /// Int value
194 ///
195 /// ```rust
196 /// extern crate rlp;
197 /// use rlp::*;
198 ///
199 /// fn main () {
200 /// let data = vec![0xc1, 0x10];
201 /// let rlp = Rlp::new(&data);
202 /// assert_eq!(rlp.is_int(), false);
203 /// assert_eq!(rlp.at(0).is_int(), true);
204 /// }
205 /// ```
206 pub fn is_int(&self) -> bool {
207 self.rlp.is_int()
208 }
209
210 /// Get iterator over rlp-slices
211 ///
212 /// ```rust
213 /// extern crate rlp;
214 /// use rlp::*;
215 ///
216 /// fn main () {
217 /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
218 /// let rlp = Rlp::new(&data);
219 /// let strings: Vec<String> = rlp.iter().map(| i | i.as_val()).collect();
220 /// }
221 /// ```
222 pub fn iter(&'view self) -> RlpIterator<'a, 'view> {
223 self.into_iter()
224 }
225
226 /// Decode data into an object
227 pub fn as_val<T>(&self) -> T where T: Decodable {
228 self.rlp.as_val().expect("Unexpected rlp error")
229 }
230
231 pub fn as_list<T>(&self) -> Vec<T> where T: Decodable {
232 self.iter().map(|rlp| rlp.as_val()).collect()
233 }
234
235 /// Decode data at given list index into an object
236 pub fn val_at<T>(&self, index: usize) -> T where T: Decodable {
237 self.at(index).as_val()
238 }
239
240 pub fn list_at<T>(&self, index: usize) -> Vec<T> where T: Decodable {
241 self.at(index).as_list()
242 }
243}
244
245/// Iterator over trusted rlp-slice list elements.
246pub struct RlpIterator<'a, 'view> where 'a: 'view {
247 rlp: &'view Rlp<'a>,
248 index: usize
249}
250
251impl<'a, 'view> IntoIterator for &'view Rlp<'a> where 'a: 'view {
252 type Item = Rlp<'a>;
253 type IntoIter = RlpIterator<'a, 'view>;
254
255 fn into_iter(self) -> Self::IntoIter {
256 RlpIterator {
257 rlp: self,
258 index: 0,
259 }
260 }
261}
262
263impl<'a, 'view> Iterator for RlpIterator<'a, 'view> {
264 type Item = Rlp<'a>;
265
266 fn next(&mut self) -> Option<Rlp<'a>> {
267 let index = self.index;
268 let result = self.rlp.rlp.at(index).ok().map(From::from);
269 self.index += 1;
270 result
271 }
272}