gel_protocol/serialization/decode/queryable/
collections.rs

1use crate::descriptors::{Descriptor, TypePos};
2use crate::errors::DecodeError;
3use crate::queryable::DescriptorMismatch;
4use crate::queryable::{Decoder, DescriptorContext, Queryable};
5use crate::serialization::decode::DecodeArrayLike;
6use std::iter::FromIterator;
7
8impl<T: Queryable> Queryable for Option<T> {
9    type Args = T::Args;
10
11    fn decode(decoder: &Decoder, args: &Self::Args, buf: &[u8]) -> Result<Self, DecodeError> {
12        Ok(Some(T::decode(decoder, args, buf)?))
13    }
14
15    fn decode_optional(
16        decoder: &Decoder,
17        args: &Self::Args,
18        buf: Option<&[u8]>,
19    ) -> Result<Self, DecodeError> {
20        buf.map(|buf| T::decode(decoder, args, buf)).transpose()
21    }
22
23    fn check_descriptor(
24        ctx: &DescriptorContext,
25        type_pos: TypePos,
26    ) -> Result<T::Args, DescriptorMismatch> {
27        T::check_descriptor(ctx, type_pos)
28    }
29}
30
31struct Collection<T>(T);
32
33impl<T: IntoIterator + FromIterator<<T as IntoIterator>::Item>> Collection<T>
34where
35    <T as IntoIterator>::Item: Queryable,
36{
37    fn decode(
38        decoder: &Decoder,
39        args: &<<T as IntoIterator>::Item as Queryable>::Args,
40        buf: &[u8],
41    ) -> Result<T, DecodeError> {
42        let elements = DecodeArrayLike::new_collection(buf)?;
43        let elements = elements.map(|e| <T as IntoIterator>::Item::decode(decoder, args, e?));
44        elements.collect::<Result<T, DecodeError>>()
45    }
46
47    fn decode_optional(
48        decoder: &Decoder,
49        args: &<<T as IntoIterator>::Item as Queryable>::Args,
50        buf: Option<&[u8]>,
51    ) -> Result<T, DecodeError> {
52        match buf {
53            Some(buf) => Self::decode(decoder, args, buf),
54            None => Ok(T::from_iter(std::iter::empty())),
55        }
56    }
57
58    fn check_descriptor(
59        ctx: &DescriptorContext,
60        type_pos: TypePos,
61    ) -> Result<<<T as IntoIterator>::Item as Queryable>::Args, DescriptorMismatch> {
62        let desc = ctx.get(type_pos)?;
63        let element_type_pos = match desc {
64            Descriptor::Set(desc) => desc.type_pos,
65            Descriptor::Array(desc) => desc.type_pos,
66            _ => return Err(ctx.wrong_type(desc, "array or set")),
67        };
68        <T as IntoIterator>::Item::check_descriptor(ctx, element_type_pos)
69    }
70}
71
72impl<T: Queryable> Queryable for Vec<T> {
73    type Args = T::Args;
74
75    fn decode(decoder: &Decoder, args: &T::Args, buf: &[u8]) -> Result<Self, DecodeError> {
76        Collection::<Vec<T>>::decode(decoder, args, buf)
77    }
78
79    fn decode_optional(
80        decoder: &Decoder,
81        args: &T::Args,
82        buf: Option<&[u8]>,
83    ) -> Result<Self, DecodeError> {
84        Collection::<Vec<T>>::decode_optional(decoder, args, buf)
85    }
86
87    fn check_descriptor(
88        ctx: &DescriptorContext,
89        type_pos: TypePos,
90    ) -> Result<T::Args, DescriptorMismatch> {
91        Collection::<Vec<T>>::check_descriptor(ctx, type_pos)
92    }
93}