1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use super::*;

impl<T> HasLotusJson for Vec<T>
// TODO(forest): https://github.com/ChainSafe/forest/issues/4032
//               This shouldn't recurse - LotusJson<Vec<T>> should only handle
//               the OUTER issue of serializing an empty Vec as null, and
//               shouldn't be interested in the inner representation.
where
    T: HasLotusJson + Clone,
{
    type LotusJson = Option<Vec<T::LotusJson>>;

    #[cfg(test)]
    fn snapshots() -> Vec<(serde_json::Value, Self)> {
        unimplemented!("only Vec<Cid> is tested, below")
    }

    fn into_lotus_json(self) -> Self::LotusJson {
        match self.is_empty() {
            true => None,
            false => Some(self.into_iter().map(T::into_lotus_json).collect()),
        }
    }

    fn from_lotus_json(it: Self::LotusJson) -> Self {
        match it {
            Some(it) => it.into_iter().map(T::from_lotus_json).collect(),
            None => vec![],
        }
    }
}

// an empty `Vec<T>` serializes into `null` lotus json by default,
// while an empty `NotNullVec<T>` serializes into `[]`
// this is a temporary workaround and will likely be deprecated once
// other issues on serde of `Vec<T>` are resolved.
#[derive(Debug, Clone, PartialEq, JsonSchema)]
pub struct NotNullVec<T>(pub Vec<T>);

impl<T> HasLotusJson for NotNullVec<T>
where
    T: HasLotusJson + Clone,
{
    type LotusJson = Vec<T::LotusJson>;

    #[cfg(test)]
    fn snapshots() -> Vec<(serde_json::Value, Self)> {
        unimplemented!("only Vec<Cid> is tested, below")
    }

    fn into_lotus_json(self) -> Self::LotusJson {
        self.0.into_iter().map(T::into_lotus_json).collect()
    }

    fn from_lotus_json(it: Self::LotusJson) -> Self {
        Self(it.into_iter().map(T::from_lotus_json).collect())
    }
}

#[test]
fn snapshots() {
    assert_one_snapshot(json!([{"/": "baeaaaaa"}]), vec![::cid::Cid::default()]);
}

#[cfg(test)]
quickcheck! {
    fn quickcheck(val: Vec<::cid::Cid>) -> () {
        assert_unchanged_via_json(val)
    }
}