eva_common/value/
index.rs1use crate::value::Value;
2use serde::{de, ser, ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer};
3
4#[derive(Debug, Clone, Eq, PartialEq, Hash)]
5pub struct Index(Vec<usize>);
6
7impl Index {
8 #[inline]
9 pub fn as_slice(&self) -> IndexSlice<'_> {
10 IndexSlice(&self.0)
11 }
12}
13
14impl<'de> Deserialize<'de> for Index {
15 #[inline]
16 fn deserialize<D>(deserializer: D) -> Result<Index, D::Error>
17 where
18 D: Deserializer<'de>,
19 {
20 let val: Value = Deserialize::deserialize(deserializer)?;
21 match val {
22 Value::String(s) => {
23 let mut res = Vec::new();
24 for v in s.split(',') {
25 let i = v.parse::<usize>().map_err(de::Error::custom)?;
26 res.push(i);
27 }
28 Ok(Index(res))
29 }
30 Value::Seq(s) => {
31 let mut res = Vec::with_capacity(s.len());
32 for v in s {
33 let i = u64::try_from(v).map_err(de::Error::custom)?;
34 let u = usize::try_from(i).map_err(de::Error::custom)?;
35 res.push(u);
36 }
37 Ok(Index(res))
38 }
39 _ => {
40 if let Ok(v) = u64::try_from(val) {
41 Ok(Index(vec![usize::try_from(v).map_err(de::Error::custom)?]))
42 } else {
43 Err(de::Error::custom(
44 "unsupported index (should be integer, list or string)",
45 ))
46 }
47 }
48 }
49 }
50}
51
52impl Serialize for Index {
53 #[inline]
54 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55 where
56 S: Serializer,
57 {
58 if self.0.len() == 1 {
59 serializer.serialize_u64(u64::try_from(self.0[0]).map_err(ser::Error::custom)?)
60 } else {
61 let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
62 for idx in &self.0 {
63 seq.serialize_element(idx)?;
64 }
65 seq.end()
66 }
67 }
68}
69
70#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
71#[allow(clippy::module_name_repetitions)]
72pub struct IndexSlice<'a>(pub(crate) &'a [usize]);