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 {}",
512                tag
513            )));
514        }
515    };
516
517    let mut serialized = 0;
518    for (idx, el) in desc.elements.iter().enumerate() {
519        if let Some(value) = variables.get(&el.name) {
520            value.check_descriptor(enc.ctx, el.type_pos)?;
521            serialized += 1;
522            enc.buf.reserve(8);
523            enc.buf.put_u32(idx as u32);
524            value.encode_slot(enc)?;
525        }
526    }
527
528    if serialized != variables.len() {
529        let mut extra_vars = variables.keys().collect::<BTreeSet<_>>();
530        for el in &desc.elements {
531            extra_vars.remove(&el.name);
532        }
533        return Err(ClientEncodingError::with_message(format!(
534            "non-existing entries {} of {}",
535            extra_vars
536                .into_iter()
537                .map(|x| &x[..])
538                .collect::<Vec<_>>()
539                .join(", "),
540            tag
541        )));
542    }
543
544    Ok(())
545}
546
547impl Descriptor {
548    pub fn id(&self) -> &Uuid {
549        use Descriptor::*;
550        match self {
551            Set(i) => &i.id,
552            ObjectShape(i) => &i.id,
553            BaseScalar(i) => &i.id,
554            Scalar(i) => &i.id,
555            Tuple(i) => &i.id,
556            NamedTuple(i) => &i.id,
557            Array(i) => &i.id,
558            Range(i) => &i.id,
559            MultiRange(i) => &i.id,
560            Enumeration(i) => &i.id,
561            InputShape(i) => &i.id,
562            Object(i) => &i.id,
563            Compound(i) => &i.id,
564            SQLRow(i) => &i.id,
565            TypeAnnotation(i) => &i.id,
566        }
567    }
568    pub fn decode(buf: &mut Input) -> Result<Descriptor, DecodeError> {
569        <Descriptor as Decode>::decode(buf)
570    }
571    pub fn normalize_to_base(
572        &self,
573        ctx: &query_arg::DescriptorContext,
574    ) -> Result<Descriptor, Error> {
575        let norm = match self {
576            Descriptor::Scalar(d) if d.base_type_pos.is_some() => {
577                match ctx.get(d.base_type_pos.unwrap())? {
578                    Descriptor::Scalar(d) => {
579                        Descriptor::BaseScalar(BaseScalarTypeDescriptor { id: d.id.clone() })
580                    }
581                    desc => desc.clone(),
582                }
583            }
584            Descriptor::Scalar(d) => {
585                if ctx.proto.is_2() {
586                    Descriptor::BaseScalar(BaseScalarTypeDescriptor { id: d.id.clone() })
587                } else {
588                    unreachable!("scalar dereference to a non-base type")
589                }
590            }
591            desc => desc.clone(),
592        };
593
594        Ok(norm)
595    }
596}
597
598impl<T: Decode> Decode for Vec<T> {
599    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
600        ensure!(buf.remaining() >= 2, errors::Underflow);
601        let element_count = buf.get_u16();
602        let mut elements = Vec::with_capacity(element_count as usize);
603        for _ in 0..element_count {
604            elements.push(T::decode(buf)?);
605        }
606        Ok(elements)
607    }
608}
609
610impl Decode for Option<u32> {
611    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
612        ensure!(buf.remaining() >= 4, errors::Underflow);
613
614        let val = match buf.get_i32() {
615            -1 => None,
616            n if n > 0 => Some(n as u32),
617            _ => errors::InvalidOptionU32.fail()?,
618        };
619
620        Ok(val)
621    }
622}
623
624impl Decode for TypePos {
625    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
626        ensure!(buf.remaining() >= 2, errors::Underflow);
627        Ok(Self(buf.get_u16()))
628    }
629}
630
631impl Decode for Descriptor {
632    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
633        use Descriptor as D;
634        if buf.proto().is_2() {
635            ensure!(buf.remaining() >= 4, errors::Underflow);
636            let desc_len = buf.get_u32() as u64;
637            ensure!((buf.remaining() as u64) >= desc_len, errors::Underflow);
638        }
639        ensure!(buf.remaining() >= 1, errors::Underflow);
640        match buf.chunk()[0] {
641            0x00 => SetDescriptor::decode(buf).map(D::Set),
642            0x01 => ObjectShapeDescriptor::decode(buf).map(D::ObjectShape),
643            0x02 => BaseScalarTypeDescriptor::decode(buf).map(D::BaseScalar),
644            0x03 => ScalarTypeDescriptor::decode(buf).map(D::Scalar),
645            0x04 => TupleTypeDescriptor::decode(buf).map(D::Tuple),
646            0x05 => NamedTupleTypeDescriptor::decode(buf).map(D::NamedTuple),
647            0x06 => ArrayTypeDescriptor::decode(buf).map(D::Array),
648            0x07 => EnumerationTypeDescriptor::decode(buf).map(D::Enumeration),
649            0x08 => InputShapeTypeDescriptor::decode(buf).map(D::InputShape),
650            0x09 => RangeTypeDescriptor::decode(buf).map(D::Range),
651            0x0A => ObjectTypeDescriptor::decode(buf).map(D::Object),
652            0x0B => CompoundTypeDescriptor::decode(buf).map(D::Compound),
653            0x0C => MultiRangeTypeDescriptor::decode(buf).map(D::MultiRange),
654            0x0D => SQLRowDescriptor::decode(buf).map(D::SQLRow),
655            0x7F..=0xFF => TypeAnnotationDescriptor::decode(buf).map(D::TypeAnnotation),
656            descriptor => InvalidTypeDescriptor { descriptor }.fail()?,
657        }
658    }
659}
660
661impl Decode for SetDescriptor {
662    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
663        ensure!(buf.remaining() >= 19, errors::Underflow);
664        assert!(buf.get_u8() == 0);
665        let id = Uuid::decode(buf)?.into();
666        let type_pos = TypePos(buf.get_u16());
667        Ok(SetDescriptor { id, type_pos })
668    }
669}
670
671impl Decode for ObjectShapeDescriptor {
672    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
673        ensure!(buf.remaining() >= 19, errors::Underflow);
674        assert!(buf.get_u8() == 1);
675        let id = Uuid::decode(buf)?.into();
676        let type_desc = if buf.proto().is_2() {
677            let ephemeral_free_shape = bool::decode(buf)?;
678            let type_pos = Some(TypePos::decode(buf)?);
679            let elements = Vec::<ShapeElement>::decode(buf)?;
680            ObjectShapeDescriptor {
681                id,
682                elements,
683                ephemeral_free_shape,
684                type_pos,
685            }
686        } else {
687            let elements = Vec::<ShapeElement>::decode(buf)?;
688            ObjectShapeDescriptor {
689                id,
690                elements,
691                ephemeral_free_shape: false,
692                type_pos: None,
693            }
694        };
695        Ok(type_desc)
696    }
697}
698
699impl Decode for ShapeElement {
700    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
701        ensure!(buf.remaining() >= 7, errors::Underflow);
702        let (flags, cardinality) = if buf.proto().is_at_least(0, 11) {
703            let flags = buf.get_u32();
704            let cardinality = TryFrom::try_from(buf.get_u8())?;
705            (flags, Some(cardinality))
706        } else {
707            (buf.get_u8() as u32, None)
708        };
709        let name = String::decode(buf)?;
710        let type_pos = TypePos::decode(buf)?;
711        let source_type_pos = if buf.proto().is_2() {
712            Some(TypePos::decode(buf)?)
713        } else {
714            None
715        };
716        Ok(ShapeElement {
717            flag_implicit: flags & 0b001 != 0,
718            flag_link_property: flags & 0b010 != 0,
719            flag_link: flags & 0b100 != 0,
720            cardinality,
721            name,
722            type_pos,
723            source_type_pos,
724        })
725    }
726}
727
728impl Decode for InputShapeTypeDescriptor {
729    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
730        ensure!(buf.remaining() >= 19, errors::Underflow);
731        assert!(buf.get_u8() == 8);
732        let id = Uuid::decode(buf)?.into();
733        let elements = Vec::<InputShapeElement>::decode(buf)?;
734        Ok(InputShapeTypeDescriptor { id, elements })
735    }
736}
737
738impl Decode for InputShapeElement {
739    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
740        ensure!(buf.remaining() >= 7, errors::Underflow);
741        let _flags = buf.get_u32();
742        let cardinality = Some(TryFrom::try_from(buf.get_u8())?);
743        let name = String::decode(buf)?;
744        let type_pos = TypePos::decode(buf)?;
745        Ok(InputShapeElement {
746            cardinality,
747            name,
748            type_pos,
749        })
750    }
751}
752
753impl Decode for BaseScalarTypeDescriptor {
754    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
755        let desc_byte = buf.get_u8();
756        assert!(desc_byte == 2);
757        ensure!(
758            !buf.proto().is_2(),
759            InvalidTypeDescriptor {
760                descriptor: desc_byte
761            }
762        );
763        let id = Uuid::decode(buf)?.into();
764        Ok(BaseScalarTypeDescriptor { id })
765    }
766}
767
768impl Decode for SQLRowDescriptor {
769    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
770        ensure!(buf.remaining() >= 19, errors::Underflow);
771        assert!(buf.get_u8() == 0x0D);
772        let id = Uuid::decode(buf)?.into();
773        let elements = Vec::<SQLRowElement>::decode(buf)?;
774        Ok(SQLRowDescriptor { id, elements })
775    }
776}
777
778impl Decode for SQLRowElement {
779    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
780        let name = String::decode(buf)?;
781        let type_pos = TypePos::decode(buf)?;
782        Ok(SQLRowElement { name, type_pos })
783    }
784}
785
786impl Decode for ObjectTypeDescriptor {
787    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
788        ensure!(buf.remaining() >= 19, errors::Underflow);
789        assert!(buf.get_u8() == 0x0A);
790        let id = Uuid::decode(buf)?.into();
791        let name = Some(String::decode(buf)?);
792        let schema_defined = Some(bool::decode(buf)?);
793        let type_desc = ObjectTypeDescriptor {
794            id,
795            name,
796            schema_defined,
797        };
798        Ok(type_desc)
799    }
800}
801
802impl Decode for TypeOperation {
803    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
804        ensure!(buf.remaining() >= 1, errors::Underflow);
805        let val = match buf.get_u8() {
806            0x00 => TypeOperation::UNION,
807            0x01 => TypeOperation::INTERSECTION,
808            _ => errors::InvalidTypeOperation.fail()?,
809        };
810        Ok(val)
811    }
812}
813
814impl Decode for CompoundTypeDescriptor {
815    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
816        ensure!(buf.remaining() >= 19, errors::Underflow);
817        assert!(buf.get_u8() == 0x0B);
818        let id = Uuid::decode(buf)?.into();
819        let name = Some(String::decode(buf)?);
820        let schema_defined = Some(bool::decode(buf)?);
821        ensure!(buf.remaining() >= 1, errors::Underflow);
822        let op = TypeOperation::decode(buf)?;
823        let components = Vec::<TypePos>::decode(buf)?;
824        let type_desc = CompoundTypeDescriptor {
825            id,
826            name,
827            schema_defined,
828            op,
829            components,
830        };
831        Ok(type_desc)
832    }
833}
834
835impl Decode for ScalarTypeDescriptor {
836    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
837        ensure!(buf.remaining() >= 19, errors::Underflow);
838        assert!(buf.get_u8() == 3);
839        let id = Uuid::decode(buf)?.into();
840        let type_desc = if buf.proto().is_2() {
841            let name = Some(String::decode(buf)?);
842            let schema_defined = Some(bool::decode(buf)?);
843            let ancestors = Vec::<TypePos>::decode(buf)?;
844            let base_type_pos = ancestors.last().copied();
845            ScalarTypeDescriptor {
846                id,
847                base_type_pos,
848                name,
849                schema_defined,
850                ancestors,
851            }
852        } else {
853            let base_type_pos = Some(TypePos(buf.get_u16()));
854            ScalarTypeDescriptor {
855                id,
856                base_type_pos,
857                name: None,
858                schema_defined: None,
859                ancestors: vec![],
860            }
861        };
862        Ok(type_desc)
863    }
864}
865
866impl Decode for TupleTypeDescriptor {
867    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
868        ensure!(buf.remaining() >= 19, errors::Underflow);
869        assert!(buf.get_u8() == 4);
870        let id = Uuid::decode(buf)?.into();
871
872        let type_desc = if buf.proto().is_2() {
873            let name = Some(String::decode(buf)?);
874            let schema_defined = Some(bool::decode(buf)?);
875            let ancestors = Vec::<TypePos>::decode(buf)?;
876            let element_types = Vec::<TypePos>::decode(buf)?;
877            TupleTypeDescriptor {
878                id,
879                element_types,
880                name,
881                schema_defined,
882                ancestors,
883            }
884        } else {
885            let element_types = Vec::<TypePos>::decode(buf)?;
886            TupleTypeDescriptor {
887                id,
888                element_types,
889                name: None,
890                schema_defined: None,
891                ancestors: vec![],
892            }
893        };
894        Ok(type_desc)
895    }
896}
897
898impl Decode for NamedTupleTypeDescriptor {
899    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
900        ensure!(buf.remaining() >= 19, errors::Underflow);
901        assert!(buf.get_u8() == 5);
902        let id = Uuid::decode(buf)?.into();
903
904        let type_desc = if buf.proto().is_2() {
905            let name = Some(String::decode(buf)?);
906            let schema_defined = Some(bool::decode(buf)?);
907            let ancestors = Vec::<TypePos>::decode(buf)?;
908            let elements = Vec::<TupleElement>::decode(buf)?;
909            NamedTupleTypeDescriptor {
910                id,
911                elements,
912                name,
913                schema_defined,
914                ancestors,
915            }
916        } else {
917            let elements = Vec::<TupleElement>::decode(buf)?;
918            NamedTupleTypeDescriptor {
919                id,
920                elements,
921                name: None,
922                schema_defined: None,
923                ancestors: vec![],
924            }
925        };
926
927        Ok(type_desc)
928    }
929}
930
931impl Decode for TupleElement {
932    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
933        let name = String::decode(buf)?;
934        let type_pos = TypePos::decode(buf)?;
935        Ok(TupleElement { name, type_pos })
936    }
937}
938
939impl Decode for ArrayTypeDescriptor {
940    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
941        ensure!(buf.remaining() >= 21, errors::Underflow);
942        assert!(buf.get_u8() == 6);
943        let id = Uuid::decode(buf)?.into();
944        let type_desc = if buf.proto().is_2() {
945            let name = Some(String::decode(buf)?);
946            let schema_defined = Some(bool::decode(buf)?);
947            let ancestors = Vec::<TypePos>::decode(buf)?;
948            let type_pos = TypePos::decode(buf)?;
949            let dimensions = Vec::<Option<u32>>::decode(buf)?;
950            ArrayTypeDescriptor {
951                id,
952                type_pos,
953                dimensions,
954                name,
955                schema_defined,
956                ancestors,
957            }
958        } else {
959            let type_pos = TypePos::decode(buf)?;
960            let dimensions = Vec::<Option<u32>>::decode(buf)?;
961            ArrayTypeDescriptor {
962                id,
963                type_pos,
964                dimensions,
965                name: None,
966                schema_defined: None,
967                ancestors: vec![],
968            }
969        };
970
971        Ok(type_desc)
972    }
973}
974
975impl Decode for RangeTypeDescriptor {
976    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
977        ensure!(buf.remaining() >= 19, errors::Underflow);
978        assert!(buf.get_u8() == 9);
979        let id = Uuid::decode(buf)?.into();
980        let type_desc = if buf.proto().is_2() {
981            let name = Some(String::decode(buf)?);
982            let schema_defined = Some(bool::decode(buf)?);
983            let ancestors = Vec::<TypePos>::decode(buf)?;
984            let type_pos = TypePos::decode(buf)?;
985            RangeTypeDescriptor {
986                id,
987                type_pos,
988                name,
989                schema_defined,
990                ancestors,
991            }
992        } else {
993            let type_pos = TypePos::decode(buf)?;
994            RangeTypeDescriptor {
995                id,
996                type_pos,
997                name: None,
998                schema_defined: None,
999                ancestors: vec![],
1000            }
1001        };
1002
1003        Ok(type_desc)
1004    }
1005}
1006
1007impl Decode for MultiRangeTypeDescriptor {
1008    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
1009        ensure!(buf.remaining() >= 19, errors::Underflow);
1010        assert!(buf.get_u8() == 0x0C);
1011        let id = Uuid::decode(buf)?.into();
1012        let type_desc = if buf.proto().is_2() {
1013            let name = Some(String::decode(buf)?);
1014            let schema_defined = Some(bool::decode(buf)?);
1015            let ancestors = Vec::<TypePos>::decode(buf)?;
1016            let type_pos = TypePos::decode(buf)?;
1017            MultiRangeTypeDescriptor {
1018                id,
1019                type_pos,
1020                name,
1021                schema_defined,
1022                ancestors,
1023            }
1024        } else {
1025            let type_pos = TypePos::decode(buf)?;
1026            MultiRangeTypeDescriptor {
1027                id,
1028                type_pos,
1029                name: None,
1030                schema_defined: None,
1031                ancestors: vec![],
1032            }
1033        };
1034
1035        Ok(type_desc)
1036    }
1037}
1038
1039impl Decode for EnumerationTypeDescriptor {
1040    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
1041        ensure!(buf.remaining() >= 19, errors::Underflow);
1042        assert!(buf.get_u8() == 7);
1043        let id = Uuid::decode(buf)?.into();
1044        let type_desc = if buf.proto().is_2() {
1045            let name = Some(String::decode(buf)?);
1046            let schema_defined = Some(bool::decode(buf)?);
1047            let ancestors = Vec::<TypePos>::decode(buf)?;
1048            let members = Vec::<String>::decode(buf)?;
1049            EnumerationTypeDescriptor {
1050                id,
1051                members,
1052                name,
1053                schema_defined,
1054                ancestors,
1055            }
1056        } else {
1057            let members = Vec::<String>::decode(buf)?;
1058            EnumerationTypeDescriptor {
1059                id,
1060                members,
1061                name: None,
1062                schema_defined: None,
1063                ancestors: vec![],
1064            }
1065        };
1066
1067        Ok(type_desc)
1068    }
1069}
1070
1071impl Decode for TypeAnnotationDescriptor {
1072    fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
1073        ensure!(buf.remaining() >= 21, errors::Underflow);
1074        let annotated_type = buf.get_u8();
1075        assert!(annotated_type >= 0x7F);
1076        let id = Uuid::decode(buf)?.into();
1077        let annotation = String::decode(buf)?;
1078        Ok(TypeAnnotationDescriptor {
1079            annotated_type,
1080            id,
1081            annotation,
1082        })
1083    }
1084}
1085
1086#[cfg(test)]
1087mod tests {
1088    use crate::descriptors::{
1089        BaseScalarTypeDescriptor, Descriptor, DescriptorUuid, SetDescriptor, TypePos,
1090    };
1091    use uuid::Uuid;
1092
1093    #[test]
1094    fn descriptor_uuid_debug_outputs() {
1095        let float_32: Uuid = "00000000-0000-0000-0000-000000000106".parse().unwrap();
1096        let descriptor_id = DescriptorUuid::from(float_32);
1097        assert_eq!(format!("{descriptor_id:?}"), "BaseScalar(float32)");
1098
1099        let random_uuid: Uuid = "7cc7e050-ef76-4ae9-b8a6-053ca9baa3d5".parse().unwrap();
1100        let descriptor_id = DescriptorUuid::from(random_uuid);
1101        assert_eq!(
1102            format!("{descriptor_id:?}"),
1103            "7cc7e050-ef76-4ae9-b8a6-053ca9baa3d5"
1104        );
1105
1106        let base_scalar = Descriptor::BaseScalar(BaseScalarTypeDescriptor {
1107            id: "00000000-0000-0000-0000-000000000106"
1108                .parse::<Uuid>()
1109                .unwrap()
1110                .into(),
1111        });
1112        assert_eq!(
1113            format!("{base_scalar:?}"),
1114            "BaseScalar(BaseScalarTypeDescriptor { id: BaseScalar(float32) })"
1115        );
1116
1117        let set_descriptor_with_float32 = Descriptor::Set(SetDescriptor {
1118            id: "00000000-0000-0000-0000-000000000106"
1119                .parse::<Uuid>()
1120                .unwrap()
1121                .into(),
1122            type_pos: TypePos(0),
1123        });
1124        assert_eq!(
1125            format!("{set_descriptor_with_float32:?}"),
1126            "Set(SetDescriptor { id: BaseScalar(float32), type_pos: TypePos(0) })"
1127        );
1128    }
1129}