cfx_rpc_primitives/
index.rs1use serde::{
6 de::{Error, Visitor},
7 Deserialize, Deserializer,
8};
9use std::fmt;
10
11#[derive(Debug, PartialEq)]
13pub struct Index(usize);
14
15impl Index {
16 #[allow(dead_code)]
18 pub fn value(&self) -> usize { self.0 }
19}
20
21impl<'a> Deserialize<'a> for Index {
22 fn deserialize<D>(deserializer: D) -> Result<Index, D::Error>
23 where D: Deserializer<'a> {
24 deserializer.deserialize_any(IndexVisitor)
25 }
26}
27
28struct IndexVisitor;
29
30impl<'a> Visitor<'a> for IndexVisitor {
31 type Value = Index;
32
33 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
34 write!(formatter, "a hex-encoded or decimal index")
35 }
36
37 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
38 where E: Error {
39 match value {
40 _ if value.starts_with("0x") => {
41 usize::from_str_radix(&value[2..], 16)
42 .map(Index)
43 .map_err(|e| Error::custom(format!("Invalid index: {}", e)))
44 }
45 _ => value
46 .parse::<usize>()
47 .map(Index)
48 .map_err(|e| Error::custom(format!("Invalid index: {}", e))),
49 }
50 }
51
52 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
53 where E: Error {
54 self.visit_str(value.as_ref())
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use serde_json;
62
63 #[test]
64 fn block_number_deserialization() {
65 let s = r#"["0xa", "10"]"#;
66 let deserialized: Vec<Index> = serde_json::from_str(s).unwrap();
67 assert_eq!(deserialized, vec![Index(10), Index(10)]);
68 }
69}