gel_protocol/serialization/decode/queryable/
collections.rs1use 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}