use std::sync::Arc;
use bytes::Bytes;
use edgedb_errors::{DescriptorMismatch, ProtocolEncodingError};
use edgedb_errors::{Error, ErrorKind};
use crate::codec::Codec;
use crate::descriptors::TypePos;
use crate::queryable::{Decoder, DescriptorContext, Queryable};
use crate::value::Value;
pub trait Sealed: Sized {}
pub trait QueryResult: Sealed {
type State;
fn prepare(ctx: &DescriptorContext, root_pos: TypePos) -> Result<Self::State, Error>;
fn decode(state: &mut Self::State, msg: &Bytes) -> Result<Self, Error>;
}
impl<T: Queryable> Sealed for T {}
impl Sealed for Value {}
impl<T: Queryable> QueryResult for T {
type State = Decoder;
fn prepare(ctx: &DescriptorContext, root_pos: TypePos) -> Result<Decoder, Error> {
T::check_descriptor(ctx, root_pos).map_err(DescriptorMismatch::with_source)?;
Ok(Decoder {
has_implicit_id: ctx.has_implicit_id,
has_implicit_tid: ctx.has_implicit_tid,
has_implicit_tname: ctx.has_implicit_tname,
})
}
fn decode(decoder: &mut Decoder, msg: &Bytes) -> Result<Self, Error> {
Queryable::decode(decoder, msg).map_err(ProtocolEncodingError::with_source)
}
}
impl QueryResult for Value {
type State = Arc<dyn Codec>;
fn prepare(ctx: &DescriptorContext, root_pos: TypePos) -> Result<Arc<dyn Codec>, Error> {
ctx.build_codec(root_pos)
}
fn decode(codec: &mut Arc<dyn Codec>, msg: &Bytes) -> Result<Self, Error> {
codec
.decode(msg)
.map_err(ProtocolEncodingError::with_source)
}
}