Skip to content

Commit

Permalink
Showing 14 changed files with 789 additions and 140 deletions.
2 changes: 1 addition & 1 deletion edgedb-protocol/Cargo.toml
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ rust-version.workspace = true

[dependencies]
bytes = "1.5.0"
snafu = {version="0.8.0"}
snafu = {version="0.8.0", features=["backtrace"]}
uuid = "1.1.2"
num-bigint = {version="0.4.3", optional=true}
num-traits = {version="0.2.10", optional=true}
59 changes: 57 additions & 2 deletions edgedb-protocol/src/codec.rs
Original file line number Diff line number Diff line change
@@ -98,6 +98,20 @@ pub struct ShapeElement {
pub name: String,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InputObjectShape(pub(crate) Arc<InputObjectShapeInfo>);

#[derive(Debug, PartialEq, Eq)]
pub struct InputObjectShapeInfo {
pub elements: Vec<InputShapeElement>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct InputShapeElement {
pub cardinality: Option<Cardinality>,
pub name: String,
}

#[derive(Debug, PartialEq, Eq)]
pub struct NamedTupleShapeInfo {
pub elements: Vec<TupleElement>,
@@ -179,7 +193,7 @@ pub struct Object {

#[derive(Debug)]
pub struct Input {
shape: ObjectShape,
shape: InputObjectShape,
codecs: Vec<Arc<dyn Codec>>,
}

@@ -247,6 +261,19 @@ impl Deref for ObjectShape {
}
}

impl InputObjectShape {
pub fn new(elements: Vec<InputShapeElement>) -> Self {
InputObjectShape(Arc::new(InputObjectShapeInfo { elements }))
}
}

impl Deref for InputObjectShape {
type Target = InputObjectShapeInfo;
fn deref(&self) -> &InputObjectShapeInfo {
&self.0
}
}

impl Deref for NamedTupleShape {
type Target = NamedTupleShapeInfo;
fn deref(&self) -> &NamedTupleShapeInfo {
@@ -263,7 +290,10 @@ impl<'a> CodecBuilder<'a> {
D::Set(d) => Ok(Arc::new(Set::build(d, self)?)),
D::ObjectShape(d) => Ok(Arc::new(Object::build(d, self)?)),
D::Scalar(d) => Ok(Arc::new(Scalar {
inner: self.build(d.base_type_pos)?,
inner: match d.base_type_pos {
Some(type_pos) => self.build(type_pos)?,
None => scalar_codec(&d.id)?,
},
})),
D::Tuple(d) => Ok(Arc::new(Tuple::build(d, self)?)),
D::NamedTuple(d) => Ok(Arc::new(NamedTuple::build(d, self)?)),
@@ -281,6 +311,8 @@ impl<'a> CodecBuilder<'a> {
D::Enumeration(d) => Ok(Arc::new(Enum {
members: d.members.iter().map(|x| x[..].into()).collect(),
})),
D::Object(_) => Ok(Arc::new(Nothing {})),
D::Compound(_) => Ok(Arc::new(Nothing {})),
D::InputShape(d) => Ok(Arc::new(Input::build(d, self)?)),
// type annotations are stripped from codecs array before
// building a codec
@@ -815,6 +847,7 @@ impl<'a> From<&'a descriptors::ShapeElement> for ShapeElement {
cardinality,
name,
type_pos: _,
source_type_pos: _,
} = e;
ShapeElement {
flag_implicit: *flag_implicit,
@@ -826,6 +859,28 @@ impl<'a> From<&'a descriptors::ShapeElement> for ShapeElement {
}
}

impl<'a> From<&'a [descriptors::InputShapeElement]> for InputObjectShape {
fn from(shape: &'a [descriptors::InputShapeElement]) -> InputObjectShape {
InputObjectShape(Arc::new(InputObjectShapeInfo {
elements: shape.iter().map(InputShapeElement::from).collect(),
}))
}
}

impl<'a> From<&'a descriptors::InputShapeElement> for InputShapeElement {
fn from(e: &'a descriptors::InputShapeElement) -> InputShapeElement {
let descriptors::InputShapeElement {
cardinality,
name,
type_pos: _,
} = e;
InputShapeElement {
cardinality: *cardinality,
name: name.clone(),
}
}
}

impl<'a> From<&'a [descriptors::TupleElement]> for NamedTupleShape {
fn from(shape: &'a [descriptors::TupleElement]) -> NamedTupleShape {
NamedTupleShape(Arc::new(NamedTupleShapeInfo {
495 changes: 417 additions & 78 deletions edgedb-protocol/src/descriptors.rs

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions edgedb-protocol/src/encoding.rs
Original file line number Diff line number Diff line change
@@ -194,3 +194,25 @@ impl Encode for Uuid {
Ok(())
}
}

impl Decode for bool {
fn decode(buf: &mut Input) -> Result<Self, DecodeError> {
ensure!(buf.remaining() >= 1, errors::Underflow);
let res = match buf.get_u8() {
0x00 => false,
0x01 => true,
v => errors::InvalidBool { val: v }.fail()?,
};
Ok(res)
}
}

impl Encode for bool {
fn encode(&self, buf: &mut Output) -> Result<(), EncodeError> {
buf.extend(match self {
true => &[0x01],
false => &[0x00],
});
Ok(())
}
}
8 changes: 6 additions & 2 deletions edgedb-protocol/src/errors.rs
Original file line number Diff line number Diff line change
@@ -73,8 +73,10 @@ pub enum DecodeError {
InvalidArrayOrSetShape { backtrace: Backtrace },
#[snafu(display("decimal or bigint sign bytes have invalid value"))]
BadSign { backtrace: Backtrace },
#[snafu(display("invalid boolean value"))]
InvalidBool { backtrace: Backtrace },
#[snafu(display("invalid boolean value: {val:?}"))]
InvalidBool { backtrace: Backtrace, val: u8 },
#[snafu(display("invalid optional u32 value"))]
InvalidOptionU32 { backtrace: Backtrace },
#[snafu(display("datetime is out of range"))]
InvalidDate { backtrace: Backtrace },
#[snafu(display("json format is invalid"))]
@@ -102,6 +104,8 @@ pub enum DecodeError {
backtrace: Backtrace,
annotation: &'static str,
},
#[snafu(display("invalid type operation value"))]
InvalidTypeOperation { backtrace: Backtrace },
}

#[derive(Snafu, Debug)]
5 changes: 4 additions & 1 deletion edgedb-protocol/src/features.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ pub struct ProtocolVersion {
impl ProtocolVersion {
pub fn current() -> ProtocolVersion {
ProtocolVersion {
major_ver: 1,
major_ver: 2,
minor_ver: 0,
}
}
@@ -23,6 +23,9 @@ impl ProtocolVersion {
pub fn is_1(&self) -> bool {
self.major_ver >= 1
}
pub fn is_2(&self) -> bool {
self.major_ver >= 2
}
pub fn supports_inline_typenames(&self) -> bool {
self.version_tuple() >= (0, 9)
}
13 changes: 5 additions & 8 deletions edgedb-protocol/src/query_arg.rs
Original file line number Diff line number Diff line change
@@ -93,7 +93,7 @@ impl DescriptorContext<'_> {
}
pub fn wrong_type(&self, descriptor: &Descriptor, expected: &str) -> Error {
DescriptorMismatch::with_message(format!(
"\nEdgeDB returned unexpected type {descriptor:?}\nClient expected {expected}"
"server returned unexpected type {descriptor:?} when client expected {expected}"
))
}
pub fn field_number(&self, expected: usize, unexpected: usize) -> Error {
@@ -210,13 +210,10 @@ impl QueryArg for Value {
fn check_descriptor(&self, ctx: &DescriptorContext, pos: TypePos) -> Result<(), Error> {
use Descriptor::*;
use Value::*;
let mut desc = ctx.get(pos)?;
if let Scalar(d) = desc {
desc = ctx.get(d.base_type_pos)?;
}
let desc = ctx.get(pos)?.normalize_to_base(ctx)?;

match (self, desc) {
(Nothing, _) => Ok(()), // any descriptor works
(_, Scalar(_)) => unreachable!("scalar dereference to a non-base type"),
(BigInt(_), BaseScalar(d)) if d.id == codec::STD_BIGINT => Ok(()),
(Bool(_), BaseScalar(d)) if d.id == codec::STD_BOOL => Ok(()),
(Bytes(_), BaseScalar(d)) if d.id == codec::STD_BYTES => Ok(()),
@@ -239,10 +236,10 @@ impl QueryArg for Value {
(Uuid(_), BaseScalar(d)) if d.id == codec::STD_UUID => Ok(()),
(Enum(val), Enumeration(EnumerationTypeDescriptor { members, .. })) => {
let val = val.deref();
check_enum(val, members)
check_enum(val, &members)
}
// TODO(tailhook) all types
(_, desc) => Err(ctx.wrong_type(desc, self.kind())),
(_, desc) => Err(ctx.wrong_type(&desc, self.kind())),
}
}
fn to_value(&self) -> Result<Value, Error> {
7 changes: 5 additions & 2 deletions edgedb-protocol/src/serialization/decode/queryable/scalars.rs
Original file line number Diff line number Diff line change
@@ -21,8 +21,11 @@ pub(crate) fn check_scalar(
use crate::descriptors::Descriptor::{BaseScalar, Scalar};
let desc = ctx.get(type_pos)?;
match desc {
Scalar(scalar) => {
return check_scalar(ctx, scalar.base_type_pos, type_id, name);
Scalar(scalar) if scalar.base_type_pos.is_some() => {
return check_scalar(ctx, scalar.base_type_pos.unwrap(), type_id, name);
}
Scalar(scalar) if *scalar.id == type_id => {
return Ok(());
}
BaseScalar(base) if *base.id == type_id => {
return Ok(());
9 changes: 6 additions & 3 deletions edgedb-protocol/src/serialization/decode/raw_scalar.rs
Original file line number Diff line number Diff line change
@@ -50,8 +50,11 @@ fn check_scalar(
use crate::descriptors::Descriptor::{BaseScalar, Scalar};
let desc = ctx.get(type_pos)?;
match desc {
Scalar(scalar) => {
return check_scalar(ctx, scalar.base_type_pos, type_id, name);
Scalar(scalar) if scalar.base_type_pos.is_some() => {
return check_scalar(ctx, scalar.base_type_pos.unwrap(), type_id, name);
}
Scalar(scalar) if ctx.proto.is_2() && *scalar.id == type_id => {
return Ok(());
}
BaseScalar(base) if *base.id == type_id => {
return Ok(());
@@ -152,7 +155,7 @@ impl<'t> RawCodec<'t> for bool {
let res = match buf[0] {
0x00 => false,
0x01 => true,
_ => errors::InvalidBool.fail()?,
v => errors::InvalidBool { val: v }.fail()?,
};
Ok(res)
}
13 changes: 5 additions & 8 deletions edgedb-protocol/src/value.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
Contains the [Value] enum.
*/
pub use crate::codec::EnumValue;
use crate::codec::{NamedTupleShape, ObjectShape, ShapeElement};
use crate::codec::{InputObjectShape, InputShapeElement, NamedTupleShape, ObjectShape};
use crate::common::Cardinality;
use crate::model::{BigInt, ConfigMemory, Decimal, Range, Uuid};
use crate::model::{DateDuration, Json, RelativeDuration};
@@ -50,7 +50,7 @@ pub enum Value {

#[derive(Clone, Debug)]
pub struct SparseObject {
pub(crate) shape: ObjectShape,
pub(crate) shape: InputObjectShape,
pub(crate) fields: Vec<Option<Option<Value>>>,
}

@@ -113,24 +113,21 @@ impl SparseObject {
let mut elements = Vec::new();
let mut fields = Vec::new();
for (key, val) in iter.into_iter() {
elements.push(ShapeElement {
flag_implicit: false,
flag_link_property: false,
flag_link: false,
elements.push(InputShapeElement {
cardinality: Some(Cardinality::AtMostOne),
name: key.to_string(),
});
fields.push(Some(val.into()));
}
SparseObject {
shape: ObjectShape::new(elements),
shape: InputObjectShape::new(elements),
fields,
}
}
/// Create an empty sparse object
pub fn empty() -> SparseObject {
SparseObject {
shape: ObjectShape::new(Vec::new()),
shape: InputObjectShape::new(Vec::new()),
fields: Vec::new(),
}
}
48 changes: 46 additions & 2 deletions edgedb-protocol/tests/codecs.rs
Original file line number Diff line number Diff line change
@@ -333,6 +333,7 @@ fn object_codec() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: String::from("__tid__"),
type_pos: TypePos(0),
source_type_pos: None,
},
ShapeElement {
flag_implicit: false,
@@ -341,6 +342,7 @@ fn object_codec() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: String::from("id"),
type_pos: TypePos(0),
source_type_pos: None,
},
];
let shape = elements.as_slice().into();
@@ -356,6 +358,8 @@ fn object_codec() -> Result<(), Box<dyn Error>> {
id: "5d5ebe41-eac8-eab7-a24e-cc3a8cd2766c"
.parse::<Uuid>()?
.into(),
ephemeral_free_shape: false,
type_pos: None,
elements,
}),
],
@@ -383,7 +387,7 @@ fn object_codec() -> Result<(), Box<dyn Error>> {
fn input_codec() -> Result<(), Box<dyn Error>> {
let sdd = StateDataDescription {
typedesc: RawTypedesc {
proto: ProtocolVersion::current(),
proto: ProtocolVersion::new(1, 0),
id: "fd6c3b17504a714858ec2282431ce72c".parse()?,
data: Bytes::from_static(
b"\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
@@ -459,6 +463,7 @@ fn set_codec() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: "__tid__".into(),
type_pos: TypePos(0),
source_type_pos: None,
},
ShapeElement {
flag_implicit: true,
@@ -467,6 +472,7 @@ fn set_codec() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: "id".into(),
type_pos: TypePos(0),
source_type_pos: None,
},
ShapeElement {
flag_implicit: false,
@@ -475,6 +481,7 @@ fn set_codec() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: "first_name".into(),
type_pos: TypePos(1),
source_type_pos: None,
},
];
let outer_elements = vec![
@@ -485,6 +492,7 @@ fn set_codec() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: "__tid__".into(),
type_pos: TypePos(0),
source_type_pos: None,
},
ShapeElement {
flag_implicit: true,
@@ -493,6 +501,7 @@ fn set_codec() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: "id".into(),
type_pos: TypePos(0),
source_type_pos: None,
},
ShapeElement {
flag_implicit: false,
@@ -501,6 +510,7 @@ fn set_codec() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: "first_name".into(),
type_pos: TypePos(1),
source_type_pos: None,
},
ShapeElement {
flag_implicit: false,
@@ -509,6 +519,7 @@ fn set_codec() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: "collegues".into(),
type_pos: TypePos(3),
source_type_pos: None,
},
];
let inner_shape = ObjectShape::from(&inner_elements[..]);
@@ -531,6 +542,8 @@ fn set_codec() -> Result<(), Box<dyn Error>> {
.parse::<Uuid>()?
.into(),
elements: inner_elements,
ephemeral_free_shape: false,
type_pos: None,
}),
Descriptor::Set(SetDescriptor {
id: "afbb389d-aa73-2aae-9310-84a9163cb5ed"
@@ -543,6 +556,8 @@ fn set_codec() -> Result<(), Box<dyn Error>> {
.parse::<Uuid>()?
.into(),
elements: outer_elements,
ephemeral_free_shape: false,
type_pos: None,
}),
],
)?;
@@ -854,7 +869,10 @@ fn custom_scalar() -> Result<(), Box<dyn Error>> {
id: "234dc787-2646-11ea-bebd-010d530c06ca"
.parse::<Uuid>()?
.into(),
base_type_pos: TypePos(0),
base_type_pos: Some(TypePos(0)),
name: None,
schema_defined: None,
ancestors: vec![],
}),
],
)?;
@@ -883,6 +901,9 @@ fn tuple() -> Result<(), Box<dyn Error>> {
.parse::<Uuid>()?
.into(),
element_types: vec![TypePos(0), TypePos(1)],
name: None,
schema_defined: None,
ancestors: vec![],
}),
],
)?;
@@ -928,6 +949,9 @@ fn named_tuple() -> Result<(), Box<dyn Error>> {
.parse::<Uuid>()?
.into(),
elements,
name: None,
schema_defined: None,
ancestors: vec![],
}),
],
)?;
@@ -961,6 +985,9 @@ fn array() -> Result<(), Box<dyn Error>> {
.into(),
type_pos: TypePos(0),
dimensions: vec![None],
name: None,
schema_defined: None,
ancestors: vec![],
}),
],
)?;
@@ -991,6 +1018,9 @@ fn enums() -> Result<(), Box<dyn Error>> {
.parse::<Uuid>()?
.into(),
members: vec!["x".into(), "y".into()],
name: None,
schema_defined: None,
ancestors: vec![],
})],
)?;
encoding_eq!(&codec, bconcat!(b"x"), Value::Enum("x".into()));
@@ -1007,6 +1037,7 @@ fn set_of_arrays() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: String::from("__tname__"),
type_pos: TypePos(0),
source_type_pos: None,
},
ShapeElement {
flag_implicit: true,
@@ -1015,6 +1046,7 @@ fn set_of_arrays() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: String::from("id"),
type_pos: TypePos(1),
source_type_pos: None,
},
ShapeElement {
flag_implicit: false,
@@ -1023,6 +1055,7 @@ fn set_of_arrays() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: String::from("sets"),
type_pos: TypePos(4),
source_type_pos: None,
},
];
let shape = ObjectShape::from(&elements[..]);
@@ -1051,6 +1084,9 @@ fn set_of_arrays() -> Result<(), Box<dyn Error>> {
.into(),
type_pos: TypePos(2),
dimensions: vec![None],
name: None,
schema_defined: None,
ancestors: vec![],
}),
Descriptor::Set(SetDescriptor {
id: "499ffd5c-f21b-574d-af8a-1c094c9d6fb0"
@@ -1063,6 +1099,8 @@ fn set_of_arrays() -> Result<(), Box<dyn Error>> {
.parse::<Uuid>()?
.into(),
elements,
ephemeral_free_shape: false,
type_pos: None,
}),
],
)?;
@@ -1110,6 +1148,9 @@ fn range() -> Result<(), Box<dyn Error>> {
.unwrap()
.into(),
type_pos: TypePos(0),
name: None,
schema_defined: None,
ancestors: vec![],
}),
],
)?;
@@ -1142,6 +1183,9 @@ fn multi_range() -> Result<(), Box<dyn Error>> {
.unwrap()
.into(),
type_pos: TypePos(0),
name: None,
schema_defined: None,
ancestors: vec![],
}),
],
)?;
8 changes: 4 additions & 4 deletions edgedb-protocol/tests/server_messages.rs
Original file line number Diff line number Diff line change
@@ -244,12 +244,12 @@ fn command_data_description1() -> Result<(), Box<dyn Error>> {
capabilities: Capabilities::MODIFICATIONS,
result_cardinality: Cardinality::AtMostOne,
input: RawTypedesc {
proto: ProtocolVersion::current(),
proto: ProtocolVersion::new(1, 0),
id: Uuid::from_u128(0xFF),
data: Bytes::from_static(b"\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\0\0"),
},
output: RawTypedesc {
proto: ProtocolVersion::current(),
proto: ProtocolVersion::new(1, 0),
id: Uuid::from_u128(0x105),
data: Bytes::from_static(b"\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x05"),
},
@@ -270,12 +270,12 @@ fn command_data_description1() -> Result<(), Box<dyn Error>> {
capabilities: Capabilities::MODIFICATIONS,
result_cardinality: Cardinality::NoResult,
input: RawTypedesc {
proto: ProtocolVersion::current(),
proto: ProtocolVersion::new(1, 0),
id: Uuid::from_u128(0xFF),
data: Bytes::from_static(b"\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\0\0"),
},
output: RawTypedesc {
proto: ProtocolVersion::current(),
proto: ProtocolVersion::new(1, 0),
id: Uuid::from_u128(0),
data: Bytes::from_static(b""),
},
222 changes: 202 additions & 20 deletions edgedb-protocol/tests/type_descriptors.rs
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@ use bytes::{Buf, Bytes};
use std::error::Error;

use edgedb_protocol::descriptors::BaseScalarTypeDescriptor;
use edgedb_protocol::descriptors::ObjectTypeDescriptor;
use edgedb_protocol::descriptors::ScalarTypeDescriptor;
use edgedb_protocol::descriptors::TupleTypeDescriptor;
use edgedb_protocol::descriptors::{Descriptor, TypePos};
use edgedb_protocol::descriptors::{ObjectShapeDescriptor, ShapeElement};
@@ -12,9 +14,9 @@ use uuid::Uuid;

mod base;

fn decode(bytes: &[u8]) -> Result<Vec<Descriptor>, DecodeError> {
fn decode(pv: ProtocolVersion, bytes: &[u8]) -> Result<Vec<Descriptor>, DecodeError> {
let bytes = Bytes::copy_from_slice(bytes);
let mut input = Input::new(ProtocolVersion::current(), bytes);
let mut input = Input::new(pv, bytes);
let mut result = Vec::new();
while input.remaining() > 0 {
result.push(Descriptor::decode(&mut input)?);
@@ -23,27 +25,31 @@ fn decode(bytes: &[u8]) -> Result<Vec<Descriptor>, DecodeError> {
Ok(result)
}

fn decode_10(bytes: &[u8]) -> Result<Vec<Descriptor>, DecodeError> {
let bytes = Bytes::copy_from_slice(bytes);
let mut input = Input::new(ProtocolVersion::new(0, 10), bytes);
let mut result = Vec::new();
while input.remaining() > 0 {
result.push(Descriptor::decode(&mut input)?);
}
assert!(input.remaining() == 0);
Ok(result)
fn decode_2_0(bytes: &[u8]) -> Result<Vec<Descriptor>, DecodeError> {
decode(ProtocolVersion::new(2, 0), bytes)
}

fn decode_1_0(bytes: &[u8]) -> Result<Vec<Descriptor>, DecodeError> {
decode(ProtocolVersion::new(1, 0), bytes)
}

fn decode_0_10(bytes: &[u8]) -> Result<Vec<Descriptor>, DecodeError> {
decode(ProtocolVersion::new(0, 10), bytes)
}

#[test]
fn empty_tuple() -> Result<(), Box<dyn Error>> {
// `SELECT ()`
assert_eq!(
decode(b"\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\0\0")?,
decode_1_0(b"\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\0\0")?,
vec![Descriptor::Tuple(TupleTypeDescriptor {
id: "00000000-0000-0000-0000-0000000000FF"
.parse::<Uuid>()?
.into(),
element_types: Vec::new(),
name: None,
schema_defined: None,
ancestors: vec![],
}),]
);
Ok(())
@@ -53,7 +59,7 @@ fn empty_tuple() -> Result<(), Box<dyn Error>> {
fn one_tuple() -> Result<(), Box<dyn Error>> {
// `SELECT (1,)`
assert_eq!(
decode(bconcat!(
decode_1_0(bconcat!(
b"\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x05"
b"\x04\x1cyGes%\x89Sa\x03\xe7\x87vE\xad9\0\x01\0\0"))?,
vec![
@@ -67,16 +73,19 @@ fn one_tuple() -> Result<(), Box<dyn Error>> {
.parse::<Uuid>()?
.into(),
element_types: vec![TypePos(0)],
name: None,
schema_defined: None,
ancestors: vec![],
}),
]
);
Ok(())
}

#[test]
fn single_int() -> Result<(), Box<dyn Error>> {
fn single_int_1_0() -> Result<(), Box<dyn Error>> {
assert_eq!(
decode(b"\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x05")?,
decode_1_0(b"\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x05")?,
vec![Descriptor::BaseScalar(BaseScalarTypeDescriptor {
id: "00000000-0000-0000-0000-000000000105"
.parse::<Uuid>()?
@@ -86,10 +95,70 @@ fn single_int() -> Result<(), Box<dyn Error>> {
Ok(())
}

#[test]
fn single_int_2_0() -> Result<(), Box<dyn Error>> {
assert_eq!(
decode_2_0(b"\0\0\0\"\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x05\0\0\0\nstd::int64\x01\0\0")?,
vec![Descriptor::Scalar(ScalarTypeDescriptor {
id: "00000000-0000-0000-0000-000000000105"
.parse::<Uuid>()?
.into(),
name: Some(String::from("std::int64")),
schema_defined: Some(true),
ancestors: vec![],
base_type_pos: None,
})]
);
Ok(())
}

#[test]
fn single_derived_int_2_0() -> Result<(), Box<dyn Error>> {
assert_eq!(
decode_2_0(bconcat!(
b"\0\0\0\"\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x05\0\0\0\n"
b"std::int64\x01\0\0\0\0\0)\x03\x91v\xff\x8c\x95\xb6\x11\xef\x9c"
b" [\x0e\x8c=\xaa\xc8\0\0\0\x0fdefault::my_int\x01\0\x01\0\0\0\0\0"
b"-\x03J\xa0\x08{\x95\xb7\x11\xef\xbd\xe2?\xfa\xe3\r\x13\xe9\0\0\0"
b"\x11default::my_int_2\x01\0\x02\0\x01\0\0"
))?,
vec![
Descriptor::Scalar(ScalarTypeDescriptor {
id: "00000000-0000-0000-0000-000000000105"
.parse::<Uuid>()?
.into(),
name: Some(String::from("std::int64")),
schema_defined: Some(true),
ancestors: vec![],
base_type_pos: None,
}),
Descriptor::Scalar(ScalarTypeDescriptor {
id: "9176ff8c-95b6-11ef-9c20-5b0e8c3daac8"
.parse::<Uuid>()?
.into(),
name: Some(String::from("default::my_int")),
schema_defined: Some(true),
ancestors: vec![TypePos(0)],
base_type_pos: Some(TypePos(0)),
}),
Descriptor::Scalar(ScalarTypeDescriptor {
id: "4aa0087b-95b7-11ef-bde2-3ffae30d13e9"
.parse::<Uuid>()?
.into(),
name: Some(String::from("default::my_int_2")),
schema_defined: Some(true),
ancestors: vec![TypePos(1), TypePos(0)],
base_type_pos: Some(TypePos(0)),
}),
]
);
Ok(())
}

#[test]
fn duration() -> Result<(), Box<dyn Error>> {
assert_eq!(
decode(b"\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x0e")?,
decode_1_0(b"\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x0e")?,
vec![Descriptor::BaseScalar(BaseScalarTypeDescriptor {
id: "00000000-0000-0000-0000-00000000010e"
.parse::<Uuid>()?
@@ -100,9 +169,9 @@ fn duration() -> Result<(), Box<dyn Error>> {
}

#[test]
fn object_10() -> Result<(), Box<dyn Error>> {
fn object_0_10() -> Result<(), Box<dyn Error>> {
assert_eq!(
decode_10(bconcat!(
decode_0_10(bconcat!(
b"\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\x02"
b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x01\x01n"
b"\xbb\xbe\xda\0P\x14\xfe\x84\xbc\x82\x15@\xb1"
@@ -123,6 +192,8 @@ fn object_10() -> Result<(), Box<dyn Error>> {
id: "6ebbbeda-0050-14fe-84bc-821540b152cd"
.parse::<Uuid>()?
.into(),
ephemeral_free_shape: false,
type_pos: None,
elements: vec![
ShapeElement {
flag_implicit: true,
@@ -131,6 +202,7 @@ fn object_10() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: String::from("__tid__"),
type_pos: TypePos(0),
source_type_pos: None,
},
ShapeElement {
flag_implicit: true,
@@ -139,6 +211,7 @@ fn object_10() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: String::from("id"),
type_pos: TypePos(0),
source_type_pos: None,
},
ShapeElement {
flag_implicit: false,
@@ -147,6 +220,7 @@ fn object_10() -> Result<(), Box<dyn Error>> {
cardinality: None,
name: String::from("title"),
type_pos: TypePos(1),
source_type_pos: None,
}
]
})
@@ -156,10 +230,10 @@ fn object_10() -> Result<(), Box<dyn Error>> {
}

#[test]
fn object() -> Result<(), Box<dyn Error>> {
fn object_1_0() -> Result<(), Box<dyn Error>> {
use edgedb_protocol::common::Cardinality::*;
assert_eq!(
decode(bconcat!(
decode_1_0(bconcat!(
// equivalent of 0.10
//b"\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x01\x02"
//b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\x01,sT"
@@ -186,6 +260,8 @@ fn object() -> Result<(), Box<dyn Error>> {
id: "6e27dba0-7861-24c2-86a9-15a6f2e3faf5"
.parse::<Uuid>()?
.into(),
ephemeral_free_shape: false,
type_pos: None,
elements: vec![
ShapeElement {
flag_implicit: true,
@@ -194,6 +270,7 @@ fn object() -> Result<(), Box<dyn Error>> {
cardinality: Some(One),
name: String::from("__tname__"),
type_pos: TypePos(0),
source_type_pos: None,
},
ShapeElement {
flag_implicit: true,
@@ -202,6 +279,7 @@ fn object() -> Result<(), Box<dyn Error>> {
cardinality: Some(One),
name: String::from("id"),
type_pos: TypePos(1),
source_type_pos: None,
},
ShapeElement {
flag_implicit: false,
@@ -210,10 +288,114 @@ fn object() -> Result<(), Box<dyn Error>> {
cardinality: Some(AtMostOne),
name: String::from("title"),
type_pos: TypePos(0),
source_type_pos: None,
}
]
})
]
);
Ok(())
}

#[test]
fn object_2_0() -> Result<(), Box<dyn Error>> {
use edgedb_protocol::common::Cardinality::*;
// SELECT Foo {
// id,
// title,
// [IS Bar].body,
// }
assert_eq!(
decode_2_0(bconcat!(
b"\0\0\0 \x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\x01\0\0\0\x08"
b"std::str\x01\0\0\0\0\0!\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"
b"\0\0\0\0\tstd::uuid\x01\0\0\0\0\0\"\n\xc3\xcc\xa7R\x95\xb7"
b"\x11\xef\xb4\x87\x1d\x1b\x9f\xa20\x03\0\0\0\x0cdefault::Foo"
b"\x01\0\0\0\"\n\r\xdc\xd7\x1e\x95\xb8\x11\xef\x82M!7\x80\\^4"
b"\0\0\0\x0cdefault::Bar\x01\0\0\0^\x01\x1dMg\xe7{\xdd]9\x90\x97"
b"O\x82\xfa\xd8\xaf7\0\0\x02\0\x04\0\0\0\x01A\0\0\0\t__tname__"
b"\0\0\0\x02\0\0\0\0A\0\0\0\x02id\0\x01\0\x02\0\0\0\0o\0\0\0\x05"
b"title\0\0\0\x02\0\0\0\0o\0\0\0\x04body\0\0\0\x03"
))?,
vec![
Descriptor::Scalar(ScalarTypeDescriptor {
id: "00000000-0000-0000-0000-000000000101"
.parse::<Uuid>()?
.into(),
name: Some(String::from("std::str")),
schema_defined: Some(true),
ancestors: vec![],
base_type_pos: None,
}),
Descriptor::Scalar(ScalarTypeDescriptor {
id: "00000000-0000-0000-0000-000000000100"
.parse::<Uuid>()?
.into(),
name: Some(String::from("std::uuid")),
schema_defined: Some(true),
ancestors: vec![],
base_type_pos: None,
}),
Descriptor::Object(ObjectTypeDescriptor {
id: "c3cca752-95b7-11ef-b487-1d1b9fa23003"
.parse::<Uuid>()?
.into(),
name: Some(String::from("default::Foo")),
schema_defined: Some(true),
}),
Descriptor::Object(ObjectTypeDescriptor {
id: "0ddcd71e-95b8-11ef-824d-2137805c5e34"
.parse::<Uuid>()?
.into(),
name: Some(String::from("default::Bar")),
schema_defined: Some(true),
}),
Descriptor::ObjectShape(ObjectShapeDescriptor {
id: "1d4d67e7-7bdd-5d39-9097-4f82fad8af37"
.parse::<Uuid>()?
.into(),
ephemeral_free_shape: false,
type_pos: Some(TypePos(2)),
elements: vec![
ShapeElement {
flag_implicit: true,
flag_link_property: false,
flag_link: false,
cardinality: Some(One),
name: String::from("__tname__"),
type_pos: TypePos(0),
source_type_pos: Some(TypePos(2)),
},
ShapeElement {
flag_implicit: false,
flag_link_property: false,
flag_link: false,
cardinality: Some(One),
name: String::from("id"),
type_pos: TypePos(1),
source_type_pos: Some(TypePos(2)),
},
ShapeElement {
flag_implicit: false,
flag_link_property: false,
flag_link: false,
cardinality: Some(AtMostOne),
name: String::from("title"),
type_pos: TypePos(0),
source_type_pos: Some(TypePos(2)),
},
ShapeElement {
flag_implicit: false,
flag_link_property: false,
flag_link: false,
cardinality: Some(AtMostOne),
name: String::from("body"),
type_pos: TypePos(0),
source_type_pos: Some(TypePos(3)),
},
]
})
]
);
Ok(())
}
18 changes: 9 additions & 9 deletions flake.lock

0 comments on commit aadf0b6

Please sign in to comment.