forest/lotus_json/
vec.rs

1// Copyright 2019-2025 ChainSafe Systems
2// SPDX-License-Identifier: Apache-2.0, MIT
3
4use super::*;
5
6impl<T> HasLotusJson for Vec<T>
7// TODO(forest): https://github.com/ChainSafe/forest/issues/4032
8//               This shouldn't recurse - LotusJson<Vec<T>> should only handle
9//               the OUTER issue of serializing an empty Vec as null, and
10//               shouldn't be interested in the inner representation.
11where
12    T: HasLotusJson + Clone,
13{
14    type LotusJson = Option<Vec<T::LotusJson>>;
15
16    #[cfg(test)]
17    fn snapshots() -> Vec<(serde_json::Value, Self)> {
18        unimplemented!("only Vec<Cid> is tested, below")
19    }
20
21    fn into_lotus_json(self) -> Self::LotusJson {
22        match self.is_empty() {
23            true => None,
24            false => Some(self.into_iter().map(T::into_lotus_json).collect()),
25        }
26    }
27
28    fn from_lotus_json(it: Self::LotusJson) -> Self {
29        match it {
30            Some(it) => it.into_iter().map(T::from_lotus_json).collect(),
31            None => vec![],
32        }
33    }
34}
35
36// an empty `Vec<T>` serializes into `null` lotus json by default,
37// while an empty `NotNullVec<T>` serializes into `[]`
38// this is a temporary workaround and will likely be deprecated once
39// other issues on serde of `Vec<T>` are resolved.
40#[derive(Debug, Clone, PartialEq, JsonSchema)]
41pub struct NotNullVec<T>(pub Vec<T>);
42
43impl<T> HasLotusJson for NotNullVec<T>
44where
45    T: HasLotusJson + Clone,
46{
47    type LotusJson = Vec<T::LotusJson>;
48
49    #[cfg(test)]
50    fn snapshots() -> Vec<(serde_json::Value, Self)> {
51        unimplemented!("only Vec<Cid> is tested, below")
52    }
53
54    fn into_lotus_json(self) -> Self::LotusJson {
55        self.0.into_iter().map(T::into_lotus_json).collect()
56    }
57
58    fn from_lotus_json(it: Self::LotusJson) -> Self {
59        Self(it.into_iter().map(T::from_lotus_json).collect())
60    }
61}
62
63#[test]
64fn snapshots() {
65    assert_one_snapshot(json!([{"/": "baeaaaaa"}]), vec![::cid::Cid::default()]);
66}
67
68#[cfg(test)]
69quickcheck! {
70    fn quickcheck(val: Vec<::cid::Cid>) -> () {
71        assert_unchanged_via_json(val)
72    }
73}