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}