mina_p2p_messages/
list.rs

1use std::{
2    collections::LinkedList,
3    ops::{Deref, DerefMut},
4};
5
6use binprot::{BinProtRead, BinProtWrite, Nat0};
7use malloc_size_of_derive::MallocSizeOf;
8use rsexp::OfSexp;
9
10pub type Backend<T> = LinkedList<T>;
11
12/// Represents OCaml list type.
13#[derive(
14    Clone,
15    Debug,
16    Default,
17    PartialEq,
18    Eq,
19    PartialOrd,
20    Ord,
21    serde::Serialize,
22    serde::Deserialize,
23    derive_more::From,
24    derive_more::Into,
25    MallocSizeOf,
26)]
27pub struct List<T>(Backend<T>);
28
29impl<T> List<T> {
30    pub fn new() -> Self {
31        List(Backend::new())
32    }
33
34    pub fn one(elt: T) -> Self {
35        let mut l = List(Backend::new());
36        l.push_front(elt);
37        l
38    }
39
40    // pub fn iter(&self) -> <&Backend<T> as IntoIterator>::IntoIter {
41    //     (self).into_iter()
42    // }
43
44    pub fn push_front(&mut self, element: T) {
45        self.0.push_front(element)
46    }
47}
48
49impl<T: OfSexp> OfSexp for List<T> {
50    fn of_sexp(s: &rsexp::Sexp) -> Result<Self, rsexp::IntoSexpError>
51    where
52        Self: Sized,
53    {
54        let elts = s.extract_list("List")?;
55        let mut backend = Backend::new();
56        for elt in elts.iter() {
57            backend.push_back(rsexp::OfSexp::of_sexp(elt)?);
58        }
59        Ok(Self(backend))
60    }
61}
62
63impl<T: rsexp::SexpOf> rsexp::SexpOf for List<T> {
64    fn sexp_of(&self) -> rsexp::Sexp {
65        let elements: Vec<rsexp::Sexp> = self.0.iter().map(|item| item.sexp_of()).collect();
66
67        rsexp::Sexp::List(elements)
68    }
69}
70
71impl<T> Deref for List<T> {
72    type Target = Backend<T>;
73
74    fn deref(&self) -> &Self::Target {
75        &self.0
76    }
77}
78
79impl<T> DerefMut for List<T> {
80    fn deref_mut(&mut self) -> &mut Self::Target {
81        &mut self.0
82    }
83}
84
85impl<T> IntoIterator for List<T> {
86    type Item = T;
87
88    type IntoIter = <Backend<T> as IntoIterator>::IntoIter;
89
90    fn into_iter(self) -> Self::IntoIter {
91        self.0.into_iter()
92    }
93}
94
95impl<'a, T> IntoIterator for &'a List<T> {
96    type Item = &'a T;
97
98    type IntoIter = <&'a Backend<T> as IntoIterator>::IntoIter;
99
100    fn into_iter(self) -> Self::IntoIter {
101        self.0.iter()
102    }
103}
104
105impl<T> FromIterator<T> for List<T> {
106    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
107        List(Backend::from_iter(iter))
108    }
109}
110
111impl<T> BinProtRead for List<T>
112where
113    T: BinProtRead,
114{
115    fn binprot_read<R: std::io::prelude::Read + ?Sized>(r: &mut R) -> Result<Self, binprot::Error> {
116        let Nat0(len) = Nat0::binprot_read(r)?;
117        let mut v: Backend<T> = Backend::new();
118        for _i in 0..len {
119            let item = T::binprot_read(r)?;
120            v.push_back(item)
121        }
122        Ok(List(v))
123    }
124}
125
126impl<T> BinProtWrite for List<T>
127where
128    T: BinProtWrite,
129{
130    fn binprot_write<W: std::io::prelude::Write>(&self, w: &mut W) -> std::io::Result<()> {
131        let len = self.0.len() as u64;
132        Nat0(len).binprot_write(w)?;
133        for v in self.0.iter() {
134            v.binprot_write(w)?
135        }
136        Ok(())
137    }
138}