gel_protocol/
descriptors.rs

1/*!
2([Website reference](https://www.edgedb.com/docs/reference/protocol/typedesc)) Types for the [Descriptor] enum.
3
4```rust,ignore
5pub enum Descriptor {
6    Set(SetDescriptor),
7    ObjectShape(ObjectShapeDescriptor),
8    BaseScalar(BaseScalarTypeDescriptor),
9    Scalar(ScalarTypeDescriptor),
10    Tuple(TupleTypeDescriptor),
11    NamedTuple(NamedTupleTypeDescriptor),
12    Array(ArrayTypeDescriptor),
13    Enumeration(EnumerationTypeDescriptor),
14    InputShape(InputShapeTypeDescriptor),
15    Range(RangeTypeDescriptor),
16    MultiRange(MultiRangeTypeDescriptor),
17    TypeAnnotation(TypeAnnotationDescriptor),
18}
19```
20
21From the website:
22
23>The type descriptor is essentially a list of type information blocks:
24>* each block encodes one type;
25>* blocks can reference other blocks.
26
27>While parsing the _blocks_, a database driver can assemble an _encoder_ or a _decoder_ of the Gel binary data.
28
29>An _encoder_ is used to encode objects, native to the driver’s runtime, to binary data that EdegDB can decode and work with.
30
31>A _decoder_ is used to decode data from Gel native format to data types native to the driver.
32*/
33
34use std::collections::{BTreeMap, BTreeSet};
35use std::convert::{TryFrom, TryInto};
36use std::fmt::{Debug, Formatter};
37use std::ops::Deref;
38use std::sync::Arc;
39
40use bytes::{Buf, BufMut, BytesMut};
41use gel_errors::{ClientEncodingError, DescriptorMismatch, Error, ErrorKind};
42use snafu::{ensure, OptionExt};
43use uuid::Uuid;
44
45use crate::codec::{build_codec, uuid_to_known_name, Codec};
46use crate::common::{Cardinality, State};
47use crate::encoding::{Decode, Input};
48use crate::errors::{self, CodecError, DecodeError};
49use crate::errors::{InvalidTypeDescriptor, UnexpectedTypePos};
50use crate::features::ProtocolVersion;
51use crate::query_arg::{self, Encoder, QueryArg};
52use crate::queryable;
53use crate::value::Value;
54
55pub use crate::common::RawTypedesc;
56
57#[derive(Debug, Copy, Clone, PartialEq, Eq)]
58pub struct TypePos(pub u16);
59
60#[derive(Debug, Clone, PartialEq, Eq)]
61pub enum Descriptor {
62    Set(SetDescriptor),
63    ObjectShape(ObjectShapeDescriptor),
64    BaseScalar(BaseScalarTypeDescriptor),
65    Scalar(ScalarTypeDescriptor),
66    Tuple(TupleTypeDescriptor),
67    NamedTuple(NamedTupleTypeDescriptor),
68    Array(ArrayTypeDescriptor),
69    Enumeration(EnumerationTypeDescriptor),
70    InputShape(InputShapeTypeDescriptor),
71    Range(RangeTypeDescriptor),
72    MultiRange(MultiRangeTypeDescriptor),
73    Object(ObjectTypeDescriptor),
74    Compound(CompoundTypeDescriptor),
75    SQLRow(SQLRowDescriptor),
76    TypeAnnotation(TypeAnnotationDescriptor),
77}
78
79#[derive(Clone, PartialEq, Eq)]
80pub struct DescriptorUuid(Uuid);
81
82impl Debug for DescriptorUuid {
83    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
84        match uuid_to_known_name(&self.0) {
85            Some(known_name) => write!(f, "{known_name}"),
86            None => write!(f, "{}", &self.0),
87        }
88    }
89}
90
91impl Deref for DescriptorUuid {
92    type Target = Uuid;
93
94    fn deref(&self) -> &Self::Target {
95        &self.0
96    }
97}
98
99impl From<Uuid> for DescriptorUuid {
100    fn from(uuid: Uuid) -> Self {
101        Self(uuid)
102    }
103}
104
105impl PartialEq<Uuid> for DescriptorUuid {
106    fn eq(&self, other: &Uuid) -> bool {
107        self.0 == *other
108    }
109}
110
111#[derive(Debug)]
112pub struct Typedesc {
113    pub(crate) proto: ProtocolVersion,
114    pub(crate) array: Vec<Descriptor>,
115    pub(crate) root_id: Uuid,
116    pub(crate) root_pos: Option<TypePos>,
117}
118
119#[derive(Clone, Debug, PartialEq, Eq)]
120pub struct SetDescriptor {
121    pub id: DescriptorUuid,
122    pub type_pos: TypePos,
123}
124
125#[derive(Clone, Debug, PartialEq, Eq)]
126pub struct ObjectShapeDescriptor {
127    pub id: DescriptorUuid,
128    pub ephemeral_free_shape: bool,
129    pub type_pos: Option<TypePos>,
130    pub elements: Vec<ShapeElement>,
131}
132
133#[derive(Clone, Debug, PartialEq, Eq)]
134pub struct InputShapeTypeDescriptor {
135    pub id: DescriptorUuid,
136    pub elements: Vec<InputShapeElement>,
137}
138
139#[derive(Debug, Clone, PartialEq, Eq)]
140pub struct ShapeElement {
141    pub flag_implicit: bool,
142    pub flag_link_property: bool,
143    pub flag_link: bool,
144    pub cardinality: Option<Cardinality>,
145    pub name: String,
146    pub type_pos: TypePos,
147    pub source_type_pos: Option<TypePos>,
148}
149
150#[derive(Debug, Clone, PartialEq, Eq)]
151pub struct InputShapeElement {
152    pub cardinality: Option<Cardinality>,
153    pub name: String,
154    pub type_pos: TypePos,
155}
156
157#[derive(Clone, Debug, PartialEq, Eq)]
158pub struct BaseScalarTypeDescriptor {
159    pub id: DescriptorUuid,
160}
161
162#[derive(Clone, Debug, PartialEq, Eq)]
163pub struct ScalarTypeDescriptor {
164    pub id: DescriptorUuid,
165    pub base_type_pos: Option<TypePos>,
166    pub name: Option<String>,
167    pub schema_defined: Option<bool>,
168    pub ancestors: Vec<TypePos>,
169}
170
171#[derive(Clone, Debug, PartialEq, Eq)]
172pub struct TupleTypeDescriptor {
173    pub id: DescriptorUuid,
174    pub element_types: Vec<TypePos>,
175    pub name: Option<String>,
176    pub schema_defined: Option<bool>,
177    pub ancestors: Vec<TypePos>,
178}
179
180#[derive(Clone, Debug, PartialEq, Eq)]
181pub struct NamedTupleTypeDescriptor {
182    pub id: DescriptorUuid,
183    pub elements: Vec<TupleElement>,
184    pub name: Option<String>,
185    pub schema_defined: Option<bool>,
186    pub ancestors: Vec<TypePos>,
187}
188
189#[derive(Clone, Debug, PartialEq, Eq)]
190pub struct ObjectTypeDescriptor {
191    pub id: DescriptorUuid,
192    pub name: Option<String>,
193    pub schema_defined: Option<bool>,
194}
195
196#[derive(Clone, Debug, PartialEq, Eq)]
197pub struct SQLRowDescriptor {
198    pub id: DescriptorUuid,
199    pub elements: Vec<SQLRowElement>,
200}
201
202#[derive(Clone, Debug, PartialEq, Eq)]
203pub struct SQLRowElement {
204    pub name: String,
205    pub type_pos: TypePos,
206}
207
208#[derive(Clone, Debug, PartialEq, Eq)]
209#[repr(u8)]
210pub enum TypeOperation {
211    UNION = 1,
212    INTERSECTION = 2,
213}
214
215#[derive(Clone, Debug, PartialEq, Eq)]
216pub struct CompoundTypeDescriptor {
217    pub id: DescriptorUuid,
218    pub name: Option<String>,
219    pub schema_defined: Option<bool>,
220    pub op: TypeOperation,
221    pub components: Vec<TypePos>,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq)]
225pub struct TupleElement {
226    pub name: String,
227    pub type_pos: TypePos,
228}
229
230#[derive(Clone, Debug, PartialEq, Eq)]
231pub struct ArrayTypeDescriptor {
232    pub id: DescriptorUuid,
233    pub type_pos: TypePos,
234    pub dimensions: Vec<Option<u32>>,
235    pub name: Option<String>,
236    pub schema_defined: Option<bool>,
237    pub ancestors: Vec<TypePos>,
238}
239
240#[derive(Clone, Debug, PartialEq, Eq)]
241pub struct RangeTypeDescriptor {
242    pub id: DescriptorUuid,
243    pub type_pos: TypePos,
244    pub name: Option<String>,
245    pub schema_defined: Option<bool>,
246    pub ancestors: Vec<TypePos>,
247}
248
249#[derive(Clone, Debug, PartialEq, Eq)]
250pub struct MultiRangeTypeDescriptor {
251    pub id: DescriptorUuid,
252    pub type_pos: TypePos,
253    pub name: Option<String>,
254    pub schema_defined: Option<bool>,
255    pub ancestors: Vec<TypePos>,
256}
257
258#[derive(Clone, Debug, PartialEq, Eq)]
259pub struct EnumerationTypeDescriptor {
260    pub id: DescriptorUuid,
261    pub members: Vec<String>,
262    pub name: Option<String>,
263    pub schema_defined: Option<bool>,
264    pub ancestors: Vec<TypePos>,
265}
266
267#[derive(Clone, Debug, PartialEq, Eq)]
268pub struct TypeAnnotationDescriptor {
269    pub annotated_type: u8,
270    pub id: DescriptorUuid,
271    pub annotation: String,
272}
273
274pub struct StateBorrow<'a> {
275    pub module: &'a Option<String>,
276    pub aliases: &'a BTreeMap<String, String>,
277    pub config: &'a BTreeMap<String, Value>,
278    pub globals: &'a BTreeMap<String, Value>,
279}
280
281impl Typedesc {
282    pub fn id(&self) -> &Uuid {
283        &self.root_id
284    }
285    pub fn descriptors(&self) -> &[Descriptor] {
286        &self.array
287    }
288    pub fn root_pos(&self) -> Option<TypePos> {
289        self.root_pos
290    }
291    pub fn build_codec(&self) -> Result<Arc<dyn Codec>, CodecError> {
292        build_codec(self.root_pos(), self.descriptors())
293    }
294    pub fn get(&self, type_pos: TypePos) -> Result<&Descriptor, CodecError> {
295        self.array
296            .get(type_pos.0 as usize)
297            .context(UnexpectedTypePos {
298                position: type_pos.0,
299            })
300    }
301    pub fn nothing(protocol: &ProtocolVersion) -> Typedesc {
302        Typedesc {
303            proto: protocol.clone(),
304            array: Vec::new(),
305            root_id: Uuid::from_u128(0),
306            root_pos: None,
307        }
308    }
309    pub fn is_empty_tuple(&self) -> bool {
310        match self.root() {
311            Some(Descriptor::Tuple(t)) => {
312                *t.id == Uuid::from_u128(0xFF) && t.element_types.is_empty()
313            }
314            _ => false,
315        }
316    }
317    pub fn root(&self) -> Option<&Descriptor> {
318        self.root_pos.and_then(|pos| self.array.get(pos.0 as usize))
319    }
320    pub(crate) fn decode_with_id(root_id: Uuid, buf: &mut Input) -> Result<Self, DecodeError> {
321        let mut descriptors = Vec::new();
322        while buf.remaining() > 0 {
323            match Descriptor::decode(buf)? {
324                Descriptor::TypeAnnotation(_) => {}
325                item => descriptors.push(item),
326            }
327        }
328        let root_pos = if root_id == Uuid::from_u128(0) {
329            None
330        } else {
331            let idx = descriptors
332                .iter()
333                .position(|x| *x.id() == root_id)
334                .context(errors::UuidNotFound { uuid: root_id })?;
335            let pos = idx
336                .try_into()
337                .ok()
338                .context(errors::TooManyDescriptors { index: idx })?;
339            Some(TypePos(pos))
340        };
341        Ok(Typedesc {
342            proto: buf.proto().clone(),
343            array: descriptors,
344            root_id,
345            root_pos,
346        })
347    }
348    pub fn as_query_arg_context(&self) -> query_arg::DescriptorContext {
349        query_arg::DescriptorContext {
350            proto: &self.proto,
351            descriptors: self.descriptors(),
352            root_pos: self.root_pos,
353        }
354    }
355    pub fn as_queryable_context(&self) -> queryable::DescriptorContext {
356        let mut ctx = queryable::DescriptorContext::new(self.descriptors());
357        ctx.has_implicit_id = self.proto.has_implicit_id();
358        ctx.has_implicit_tid = self.proto.has_implicit_tid();
359        ctx
360    }
361    pub fn serialize_state(&self, state: &StateBorrow) -> Result<State, Error> {
362        #[derive(Debug)]
363        struct Indices {
364            module: (u32, TypePos),
365            aliases: (u32, TypePos),
366            config: (u32, TypePos),
367            globals: (u32, TypePos),
368        }
369        let mut buf = BytesMut::with_capacity(128);
370        let ctx = self.as_query_arg_context();
371        let mut enc = Encoder::new(&ctx, &mut buf);
372
373        let root = enc
374            .ctx
375            .root_pos
376            .ok_or_else(|| DescriptorMismatch::with_message("invalid state descriptor"))
377            .and_then(|p| enc.ctx.get(p))?;
378        let indices = match root {
379            Descriptor::InputShape(desc) => {
380                let mut module = None;
381                let mut aliases = None;
382                let mut config = None;
383                let mut globals = None;
384                for (i, elem) in desc.elements.iter().enumerate() {
385                    let i = i as u32;
386                    match &elem.name[..] {
387                        "module" => module = Some((i, elem.type_pos)),
388                        "aliases" => aliases = Some((i, elem.type_pos)),
389                        "config" => config = Some((i, elem.type_pos)),
390                        "globals" => globals = Some((i, elem.type_pos)),
391                        _ => {}
392                    }
393                }
394                Indices {
395                    module: module.ok_or_else(|| {
396                        DescriptorMismatch::with_message("no `module` field in state")
397                    })?,
398                    aliases: aliases.ok_or_else(|| {
399                        DescriptorMismatch::with_message("no `aliases` field in state")
400                    })?,
401                    config: config.ok_or_else(|| {
402                        DescriptorMismatch::with_message("no `config` field in state")
403                    })?,
404                    globals: globals.ok_or_else(|| {
405                        DescriptorMismatch::with_message("no `globals` field in state")
406                    })?,
407                }
408            }
409            _ => return Err(DescriptorMismatch::with_message("invalid state descriptor")),
410        };
411
412        enc.buf.reserve(4 + 8 * 4);
413        enc.buf.put_u32(4);
414
415        let module = state.module.as_deref().unwrap_or("default");
416        module.check_descriptor(enc.ctx, indices.module.1)?;
417
418        enc.buf.reserve(8);
419        enc.buf.put_u32(indices.module.0);
420        module.encode_slot(&mut enc)?;
421
422        match enc.ctx.get(indices.aliases.1)? {
423            Descriptor::Array(arr) => match enc.ctx.get(arr.type_pos)? {
424                Descriptor::Tuple(tup) => {
425                    if tup.element_types.len() != 2 {
426                        return Err(DescriptorMismatch::with_message(
427                            "invalid type descriptor for aliases",
428                        ));
429                    }
430                    "".check_descriptor(enc.ctx, tup.element_types[0])?;
431                    "".check_descriptor(enc.ctx, tup.element_types[1])?;
432                }
433                _ => {
434                    return Err(DescriptorMismatch::with_message(
435                        "invalid type descriptor for aliases",
436                    ));
437                }
438            },
439            _ => {
440                return Err(DescriptorMismatch::with_message(
441                    "invalid type descriptor for aliases",
442                ));
443            }
444        }
445
446        enc.buf
447            .reserve(4 + 16 + state.aliases.len() * (4 + (8 + 4) * 2));
448        enc.buf.put_u32(indices.aliases.0);
449        enc.length_prefixed(|enc| {
450            enc.buf.put_u32(
451                state
452                    .aliases
453                    .len()
454                    .try_into()
455                    .map_err(|_| ClientEncodingError::with_message("too many aliases"))?,
456            );
457            for (key, value) in state.aliases {
458                enc.length_prefixed(|enc| {
459                    enc.buf.reserve(4 + (8 + 4) * 2);
460                    enc.buf.put_u32(2);
461                    enc.buf.put_u32(0); // reserved
462
463                    key.encode_slot(enc)?;
464                    value.encode_slot(enc)?;
465                    Ok(())
466                })?;
467            }
468            Ok(())
469        })?;
470
471        enc.buf.reserve(4);
472        enc.buf.put_u32(indices.config.0);
473        enc.length_prefixed(|enc| {
474            serialize_variables(enc, state.config, indices.config.1, "config")
475        })?;
476        enc.buf.reserve(4);
477        enc.buf.put_u32(indices.globals.0);
478        enc.length_prefixed(|enc| {
479            serialize_variables(enc, state.globals, indices.globals.1, "globals")
480        })?;
481        let data = buf.freeze();
482        Ok(State {
483            typedesc_id: self.root_id,
484            data,
485        })
486    }
487    pub fn proto(&self) -> &ProtocolVersion {
488        &self.proto
489    }
490}
491
492fn serialize_variables(
493    enc: &mut Encoder,
494    variables: &BTreeMap<String, Value>,
495
496    type_pos: TypePos,
497    tag: &str,
498) -> Result<(), Error> {
499    enc.buf.reserve(4 + variables.len() * (4 + 4));
500    enc.buf.put_u32(
501        variables
502            .len()
503            .try_into()
504            .map_err(|_| ClientEncodingError::with_message(format!("too many items in {tag}")))?,
505    );
506
507    let desc = match enc.ctx.get(type_pos)? {
508        Descriptor::InputShape(desc) => desc,
509        _ => {
510            return Err(DescriptorMismatch::with_message(format!(
511                "invalid type descriptor for {tag}"
512            )));
513        }
514    };
515
516    let mut serialized = 0;
517    for (idx, el) in desc.elements.iter().enumerate() {
518        if let Some(value) = variables.get(&el.name) {
519            value.check_descriptor(enc.ctx, el.type_pos)?;
520            serialized += 1;
521            enc.buf.reserve(8);
522            enc.buf.put_u32(idx as u32);
523            value.encode_slot(enc)?;
524        }
525    }
526
527    if serialized != variables.len() {
528        let mut extra_vars = variables.keys().collect::<BTreeSet<_>>();
529        for el in &desc.elements {
530            extra_vars.remove(&el.name);
531        }
532        return Err(ClientEncodingError::with_message(format!(
533            "non-existing entries {} of {}",
534            extra_vars
535                .into_iter()
536                .map(|x| &x[..])
537                .collect::<Vec<_>>()
538                .join(", "),
539            tag
540        )));
541    }
542
543    Ok(())
544}
545
546impl Descriptor {
547    pub fn id(&self) -> &Uuid {
548        use Descriptor::*;
549        match self {
550            Set(i) => &i.id,
551            ObjectShape(i) => &i.id,
552            BaseScalar(i) => &i.id,
553            Scalar(i) => &i.id,
554            Tuple(i) => &i.id,
555            NamedTuple(i) => &i.id,
556            Array(i) => &i.id,
557            Range(i) => &i.id,
558            MultiRange(i) => &i.id,
559            Enumeration(i) => &i.id,
560            InputShape(i) => &i.id,
561            Object(i) => &i.id,
562            Compound(i) => &i.id,
563            SQLRow(i) => &i.id,
564            TypeAnnotation(i) => &i.id,
565        }
566    }
567    pub fn decode(buf: &mut Input) -> Result<Descriptor, DecodeError> {
568        <Descriptor as Decode>::decode(buf)
569    }
570    pub fn normalize_to_base(
571        &self,
572        ctx: &query_arg::DescriptorContext,
573    ) -> Result<Descriptor, Error> {
574        let norm = match self {
575            Descriptor::Scalar(d) if d.base_type_pos.is_some() => {
576                match ctx.get(d.base_type_pos.unwrap())? {
577                    Descriptor::Scalar(d) => {
578                        Descriptor::BaseScalar(BaseScalarTypeDescriptor { id: d.id.clone() })
579                    }
580                    desc => desc.clone(),
581                }
582            }
583            Descriptor::Scalar(d) => {
584                if ctx.proto.is_2() {
585                    Descriptor::BaseScalar(BaseScalarTypeDescriptor { id: d.id.clone() })
586                } else {
587                    unreachable!("scalar dereference to a non-base type")
588                }
589            }
590            desc => desc.clone(),
591        };
592
593        Ok(norm)
594    }
595}
596
597impl<T: Decode> Decode for Vec<T> {
598    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
599        ensure!(buf.remaining() >= 2, errors::Underflow);
600        let element_count = buf.get_u16();
601        let mut elements = Vec::with_capacity(element_count as usize);
602        for _ in 0..element_count {
603            elements.push(T::decode(buf)?);
604        }
605        Ok(elements)
606    }
607}
608
609impl Decode for Option<u32> {
610    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
611        ensure!(buf.remaining() >= 4, errors::Underflow);
612
613        let val = match buf.get_i32() {
614            -1 => None,
615            n if n > 0 => Some(n as u32),
616            _ => errors::InvalidOptionU32.fail()?,
617        };
618
619        Ok(val)
620    }
621}
622
623impl Decode for TypePos {
624    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
625        ensure!(buf.remaining() >= 2, errors::Underflow);
626        Ok(Self(buf.get_u16()))
627    }
628}
629
630impl Decode for Descriptor {
631    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
632        use Descriptor as D;
633        if buf.proto().is_2() {
634            ensure!(buf.remaining() >= 4, errors::Underflow);
635            let desc_len = buf.get_u32() as u64;
636            ensure!((buf.remaining() as u64) >= desc_len, errors::Underflow);
637        }
638        ensure!(buf.remaining() >= 1, errors::Underflow);
639        match buf.chunk()[0] {
640            0x00 => SetDescriptor::decode(buf).map(D::Set),
641            0x01 => ObjectShapeDescriptor::decode(buf).map(D::ObjectShape),
642            0x02 => BaseScalarTypeDescriptor::decode(buf).map(D::BaseScalar),
643            0x03 => ScalarTypeDescriptor::decode(buf).map(D::Scalar),
644            0x04 => TupleTypeDescriptor::decode(buf).map(D::Tuple),
645            0x05 => NamedTupleTypeDescriptor::decode(buf).map(D::NamedTuple),
646            0x06 => ArrayTypeDescriptor::decode(buf).map(D::Array),
647            0x07 => EnumerationTypeDescriptor::decode(buf).map(D::Enumeration),
648            0x08 => InputShapeTypeDescriptor::decode(buf).map(D::InputShape),
649            0x09 => RangeTypeDescriptor::decode(buf).map(D::Range),
650            0x0A => ObjectTypeDescriptor::decode(buf).map(D::Object),
651            0x0B => CompoundTypeDescriptor::decode(buf).map(D::Compound),
652            0x0C => MultiRangeTypeDescriptor::decode(buf).map(D::MultiRange),
653            0x0D => SQLRowDescriptor::decode(buf).map(D::SQLRow),
654            0x7F..=0xFF => TypeAnnotationDescriptor::decode(buf).map(D::TypeAnnotation),
655            descriptor => InvalidTypeDescriptor { descriptor }.fail()?,
656        }
657    }
658}
659
660impl Decode for SetDescriptor {
661    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
662        ensure!(buf.remaining() >= 19, errors::Underflow);
663        assert!(buf.get_u8() == 0);
664        let id = Uuid::decode(buf)?.into();
665        let type_pos = TypePos(buf.get_u16());
666        Ok(SetDescriptor { id, type_pos })
667    }
668}
669
670impl Decode for ObjectShapeDescriptor {
671    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
672        ensure!(buf.remaining() >= 19, errors::Underflow);
673        assert!(buf.get_u8() == 1);
674        let id = Uuid::decode(buf)?.into();
675        let type_desc = if buf.proto().is_2() {
676            let ephemeral_free_shape = bool::decode(buf)?;
677            let type_pos = Some(TypePos::decode(buf)?);
678            let elements = Vec::<ShapeElement>::decode(buf)?;
679            ObjectShapeDescriptor {
680                id,
681                elements,
682                ephemeral_free_shape,
683                type_pos,
684            }
685        } else {
686            let elements = Vec::<ShapeElement>::decode(buf)?;
687            ObjectShapeDescriptor {
688                id,
689                elements,
690                ephemeral_free_shape: false,
691                type_pos: None,
692            }
693        };
694        Ok(type_desc)
695    }
696}
697
698impl Decode for ShapeElement {
699    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
700        ensure!(buf.remaining() >= 7, errors::Underflow);
701        let flags = buf.get_u32();
702        let cardinality = Some(Cardinality::try_from(buf.get_u8())?);
703        let name = String::decode(buf)?;
704        let type_pos = TypePos::decode(buf)?;
705        let source_type_pos = if buf.proto().is_2() {
706            Some(TypePos::decode(buf)?)
707        } else {
708            None
709        };
710        Ok(ShapeElement {
711            flag_implicit: flags & 0b001 != 0,
712            flag_link_property: flags & 0b010 != 0,
713            flag_link: flags & 0b100 != 0,
714            cardinality,
715            name,
716            type_pos,
717            source_type_pos,
718        })
719    }
720}
721
722impl Decode for InputShapeTypeDescriptor {
723    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
724        ensure!(buf.remaining() >= 19, errors::Underflow);
725        assert!(buf.get_u8() == 8);
726        let id = Uuid::decode(buf)?.into();
727        let elements = Vec::<InputShapeElement>::decode(buf)?;
728        Ok(InputShapeTypeDescriptor { id, elements })
729    }
730}
731
732impl Decode for InputShapeElement {
733    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
734        ensure!(buf.remaining() >= 7, errors::Underflow);
735        let _flags = buf.get_u32();
736        let cardinality = Some(TryFrom::try_from(buf.get_u8())?);
737        let name = String::decode(buf)?;
738        let type_pos = TypePos::decode(buf)?;
739        Ok(InputShapeElement {
740            cardinality,
741            name,
742            type_pos,
743        })
744    }
745}
746
747impl Decode for BaseScalarTypeDescriptor {
748    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
749        let desc_byte = buf.get_u8();
750        assert!(desc_byte == 2);
751        ensure!(
752            !buf.proto().is_2(),
753            InvalidTypeDescriptor {
754                descriptor: desc_byte
755            }
756        );
757        let id = Uuid::decode(buf)?.into();
758        Ok(BaseScalarTypeDescriptor { id })
759    }
760}
761
762impl Decode for SQLRowDescriptor {
763    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
764        ensure!(buf.remaining() >= 19, errors::Underflow);
765        assert!(buf.get_u8() == 0x0D);
766        let id = Uuid::decode(buf)?.into();
767        let elements = Vec::<SQLRowElement>::decode(buf)?;
768        Ok(SQLRowDescriptor { id, elements })
769    }
770}
771
772impl Decode for SQLRowElement {
773    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
774        let name = String::decode(buf)?;
775        let type_pos = TypePos::decode(buf)?;
776        Ok(SQLRowElement { name, type_pos })
777    }
778}
779
780impl Decode for ObjectTypeDescriptor {
781    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
782        ensure!(buf.remaining() >= 19, errors::Underflow);
783        assert!(buf.get_u8() == 0x0A);
784        let id = Uuid::decode(buf)?.into();
785        let name = Some(String::decode(buf)?);
786        let schema_defined = Some(bool::decode(buf)?);
787        let type_desc = ObjectTypeDescriptor {
788            id,
789            name,
790            schema_defined,
791        };
792        Ok(type_desc)
793    }
794}
795
796impl Decode for TypeOperation {
797    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
798        ensure!(buf.remaining() >= 1, errors::Underflow);
799        let val = match buf.get_u8() {
800            0x00 => TypeOperation::UNION,
801            0x01 => TypeOperation::INTERSECTION,
802            _ => errors::InvalidTypeOperation.fail()?,
803        };
804        Ok(val)
805    }
806}
807
808impl Decode for CompoundTypeDescriptor {
809    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
810        ensure!(buf.remaining() >= 19, errors::Underflow);
811        assert!(buf.get_u8() == 0x0B);
812        let id = Uuid::decode(buf)?.into();
813        let name = Some(String::decode(buf)?);
814        let schema_defined = Some(bool::decode(buf)?);
815        ensure!(buf.remaining() >= 1, errors::Underflow);
816        let op = TypeOperation::decode(buf)?;
817        let components = Vec::<TypePos>::decode(buf)?;
818        let type_desc = CompoundTypeDescriptor {
819            id,
820            name,
821            schema_defined,
822            op,
823            components,
824        };
825        Ok(type_desc)
826    }
827}
828
829impl Decode for ScalarTypeDescriptor {
830    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
831        ensure!(buf.remaining() >= 19, errors::Underflow);
832        assert!(buf.get_u8() == 3);
833        let id = Uuid::decode(buf)?.into();
834        let type_desc = if buf.proto().is_2() {
835            let name = Some(String::decode(buf)?);
836            let schema_defined = Some(bool::decode(buf)?);
837            let ancestors = Vec::<TypePos>::decode(buf)?;
838            let base_type_pos = ancestors.last().copied();
839            ScalarTypeDescriptor {
840                id,
841                base_type_pos,
842                name,
843                schema_defined,
844                ancestors,
845            }
846        } else {
847            let base_type_pos = Some(TypePos(buf.get_u16()));
848            ScalarTypeDescriptor {
849                id,
850                base_type_pos,
851                name: None,
852                schema_defined: None,
853                ancestors: vec![],
854            }
855        };
856        Ok(type_desc)
857    }
858}
859
860impl Decode for TupleTypeDescriptor {
861    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
862        ensure!(buf.remaining() >= 19, errors::Underflow);
863        assert!(buf.get_u8() == 4);
864        let id = Uuid::decode(buf)?.into();
865
866        let type_desc = if buf.proto().is_2() {
867            let name = Some(String::decode(buf)?);
868            let schema_defined = Some(bool::decode(buf)?);
869            let ancestors = Vec::<TypePos>::decode(buf)?;
870            let element_types = Vec::<TypePos>::decode(buf)?;
871            TupleTypeDescriptor {
872                id,
873                element_types,
874                name,
875                schema_defined,
876                ancestors,
877            }
878        } else {
879            let element_types = Vec::<TypePos>::decode(buf)?;
880            TupleTypeDescriptor {
881                id,
882                element_types,
883                name: None,
884                schema_defined: None,
885                ancestors: vec![],
886            }
887        };
888        Ok(type_desc)
889    }
890}
891
892impl Decode for NamedTupleTypeDescriptor {
893    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
894        ensure!(buf.remaining() >= 19, errors::Underflow);
895        assert!(buf.get_u8() == 5);
896        let id = Uuid::decode(buf)?.into();
897
898        let type_desc = if buf.proto().is_2() {
899            let name = Some(String::decode(buf)?);
900            let schema_defined = Some(bool::decode(buf)?);
901            let ancestors = Vec::<TypePos>::decode(buf)?;
902            let elements = Vec::<TupleElement>::decode(buf)?;
903            NamedTupleTypeDescriptor {
904                id,
905                elements,
906                name,
907                schema_defined,
908                ancestors,
909            }
910        } else {
911            let elements = Vec::<TupleElement>::decode(buf)?;
912            NamedTupleTypeDescriptor {
913                id,
914                elements,
915                name: None,
916                schema_defined: None,
917                ancestors: vec![],
918            }
919        };
920
921        Ok(type_desc)
922    }
923}
924
925impl Decode for TupleElement {
926    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
927        let name = String::decode(buf)?;
928        let type_pos = TypePos::decode(buf)?;
929        Ok(TupleElement { name, type_pos })
930    }
931}
932
933impl Decode for ArrayTypeDescriptor {
934    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
935        ensure!(buf.remaining() >= 21, errors::Underflow);
936        assert!(buf.get_u8() == 6);
937        let id = Uuid::decode(buf)?.into();
938        let type_desc = if buf.proto().is_2() {
939            let name = Some(String::decode(buf)?);
940            let schema_defined = Some(bool::decode(buf)?);
941            let ancestors = Vec::<TypePos>::decode(buf)?;
942            let type_pos = TypePos::decode(buf)?;
943            let dimensions = Vec::<Option<u32>>::decode(buf)?;
944            ArrayTypeDescriptor {
945                id,
946                type_pos,
947                dimensions,
948                name,
949                schema_defined,
950                ancestors,
951            }
952        } else {
953            let type_pos = TypePos::decode(buf)?;
954            let dimensions = Vec::<Option<u32>>::decode(buf)?;
955            ArrayTypeDescriptor {
956                id,
957                type_pos,
958                dimensions,
959                name: None,
960                schema_defined: None,
961                ancestors: vec![],
962            }
963        };
964
965        Ok(type_desc)
966    }
967}
968
969impl Decode for RangeTypeDescriptor {
970    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
971        ensure!(buf.remaining() >= 19, errors::Underflow);
972        assert!(buf.get_u8() == 9);
973        let id = Uuid::decode(buf)?.into();
974        let type_desc = if buf.proto().is_2() {
975            let name = Some(String::decode(buf)?);
976            let schema_defined = Some(bool::decode(buf)?);
977            let ancestors = Vec::<TypePos>::decode(buf)?;
978            let type_pos = TypePos::decode(buf)?;
979            RangeTypeDescriptor {
980                id,
981                type_pos,
982                name,
983                schema_defined,
984                ancestors,
985            }
986        } else {
987            let type_pos = TypePos::decode(buf)?;
988            RangeTypeDescriptor {
989                id,
990                type_pos,
991                name: None,
992                schema_defined: None,
993                ancestors: vec![],
994            }
995        };
996
997        Ok(type_desc)
998    }
999}
1000
1001impl Decode for MultiRangeTypeDescriptor {
1002    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
1003        ensure!(buf.remaining() >= 19, errors::Underflow);
1004        assert!(buf.get_u8() == 0x0C);
1005        let id = Uuid::decode(buf)?.into();
1006        let type_desc = if buf.proto().is_2() {
1007            let name = Some(String::decode(buf)?);
1008            let schema_defined = Some(bool::decode(buf)?);
1009            let ancestors = Vec::<TypePos>::decode(buf)?;
1010            let type_pos = TypePos::decode(buf)?;
1011            MultiRangeTypeDescriptor {
1012                id,
1013                type_pos,
1014                name,
1015                schema_defined,
1016                ancestors,
1017            }
1018        } else {
1019            let type_pos = TypePos::decode(buf)?;
1020            MultiRangeTypeDescriptor {
1021                id,
1022                type_pos,
1023                name: None,
1024                schema_defined: None,
1025                ancestors: vec![],
1026            }
1027        };
1028
1029        Ok(type_desc)
1030    }
1031}
1032
1033impl Decode for EnumerationTypeDescriptor {
1034    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
1035        ensure!(buf.remaining() >= 19, errors::Underflow);
1036        assert!(buf.get_u8() == 7);
1037        let id = Uuid::decode(buf)?.into();
1038        let type_desc = if buf.proto().is_2() {
1039            let name = Some(String::decode(buf)?);
1040            let schema_defined = Some(bool::decode(buf)?);
1041            let ancestors = Vec::<TypePos>::decode(buf)?;
1042            let members = Vec::<String>::decode(buf)?;
1043            EnumerationTypeDescriptor {
1044                id,
1045                members,
1046                name,
1047                schema_defined,
1048                ancestors,
1049            }
1050        } else {
1051            let members = Vec::<String>::decode(buf)?;
1052            EnumerationTypeDescriptor {
1053                id,
1054                members,
1055                name: None,
1056                schema_defined: None,
1057                ancestors: vec![],
1058            }
1059        };
1060
1061        Ok(type_desc)
1062    }
1063}
1064
1065impl Decode for TypeAnnotationDescriptor {
1066    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
1067        ensure!(buf.remaining() >= 21, errors::Underflow);
1068        let annotated_type = buf.get_u8();
1069        assert!(annotated_type >= 0x7F);
1070        let id = Uuid::decode(buf)?.into();
1071        let annotation = String::decode(buf)?;
1072        Ok(TypeAnnotationDescriptor {
1073            annotated_type,
1074            id,
1075            annotation,
1076        })
1077    }
1078}
1079
1080#[cfg(test)]
1081mod tests {
1082    use crate::descriptors::{
1083        BaseScalarTypeDescriptor, Descriptor, DescriptorUuid, SetDescriptor, TypePos,
1084    };
1085    use uuid::Uuid;
1086
1087    #[test]
1088    fn descriptor_uuid_debug_outputs() {
1089        let float_32: Uuid = "00000000-0000-0000-0000-000000000106".parse().unwrap();
1090        let descriptor_id = DescriptorUuid::from(float_32);
1091        assert_eq!(format!("{descriptor_id:?}"), "BaseScalar(float32)");
1092
1093        let random_uuid: Uuid = "7cc7e050-ef76-4ae9-b8a6-053ca9baa3d5".parse().unwrap();
1094        let descriptor_id = DescriptorUuid::from(random_uuid);
1095        assert_eq!(
1096            format!("{descriptor_id:?}"),
1097            "7cc7e050-ef76-4ae9-b8a6-053ca9baa3d5"
1098        );
1099
1100        let base_scalar = Descriptor::BaseScalar(BaseScalarTypeDescriptor {
1101            id: "00000000-0000-0000-0000-000000000106"
1102                .parse::<Uuid>()
1103                .unwrap()
1104                .into(),
1105        });
1106        assert_eq!(
1107            format!("{base_scalar:?}"),
1108            "BaseScalar(BaseScalarTypeDescriptor { id: BaseScalar(float32) })"
1109        );
1110
1111        let set_descriptor_with_float32 = Descriptor::Set(SetDescriptor {
1112            id: "00000000-0000-0000-0000-000000000106"
1113                .parse::<Uuid>()
1114                .unwrap()
1115                .into(),
1116            type_pos: TypePos(0),
1117        });
1118        assert_eq!(
1119            format!("{set_descriptor_with_float32:?}"),
1120            "Set(SetDescriptor { id: BaseScalar(float32), type_pos: TypePos(0) })"
1121        );
1122    }
1123}