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}