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