use {
crate::error::{ClientResult, Error, ParseError},
std::ops::Deref,
};
#[derive(Debug, PartialEq, Clone)]
pub enum Value {
Null,
Bool(bool),
UInt8(u8),
UInt16(u16),
UInt32(u32),
UInt64(u64),
SInt8(i8),
SInt16(i16),
SInt32(i32),
SInt64(i64),
Float32(f32),
Float64(f64),
Binary(Vec<u8>),
String(String),
List(Vec<Self>),
}
impl FromValue for Value {
fn from_value(v: Value) -> ClientResult<Self> {
Ok(v)
}
}
impl Value {
pub fn parse<T: FromValue>(self) -> ClientResult<T> {
T::from_value(self)
}
pub fn parse_cloned<T: FromValue>(&self) -> ClientResult<T> {
T::from_value(self.clone())
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct Row {
values: Vec<Value>,
}
impl Deref for Row {
type Target = [Value];
fn deref(&self) -> &Self::Target {
&self.values
}
}
impl Row {
pub(crate) fn new(values: Vec<Value>) -> Self {
Self { values }
}
pub fn values(&self) -> &[Value] {
&self.values
}
pub fn into_values(self) -> Vec<Value> {
self.values
}
pub fn into_first(mut self) -> ClientResult<Value> {
if self.values.is_empty() {
Err(Error::ParseError(ParseError::ResponseMismatch))
} else {
Ok(self.values.remove(0))
}
}
pub fn into_first_as<T: FromValue>(self) -> ClientResult<T> {
self.into_first().and_then(FromValue::from_value)
}
}
impl From<Vec<Value>> for Row {
fn from(values: Vec<Value>) -> Self {
Self { values }
}
}
#[derive(Debug, PartialEq, Clone)]
pub enum Response {
Empty,
Value(Value),
Row(Row),
Rows(Vec<Row>),
Error(u16),
}
impl Response {
pub fn parse<T: FromResponse>(self) -> ClientResult<T> {
T::from_response(self)
}
}
pub trait FromResponse: Sized {
fn from_response(resp: Response) -> ClientResult<Self>;
}
impl FromResponse for () {
fn from_response(resp: Response) -> ClientResult<Self> {
match resp {
Response::Empty => Ok(()),
Response::Error(e) => Err(Error::ServerError(e)),
_ => Err(Error::ParseError(ParseError::ResponseMismatch)),
}
}
}
pub trait FromValue: Sized {
fn from_value(v: Value) -> ClientResult<Self>;
}
impl<V: FromValue> FromResponse for V {
fn from_response(resp: Response) -> ClientResult<Self> {
match resp {
Response::Value(v) => V::from_value(v),
Response::Row(_) | Response::Empty | Response::Rows(_) => {
Err(Error::ParseError(ParseError::ResponseMismatch))
}
Response::Error(e) => Err(Error::ServerError(e)),
}
}
}
impl<V: FromValue> FromValue for Option<V> {
fn from_value(v: Value) -> ClientResult<Self> {
match v {
Value::Null => Ok(None),
v => FromValue::from_value(v).map(|v| Some(v)),
}
}
}
macro_rules! from_response_direct {
($($ty:ty as $var:ident),* $(,)?) => {
$(impl FromValue for $ty {
fn from_value(v: Value) -> ClientResult<Self> {
match v {
Value::$var(capture) => Ok(From::from(capture)),
_ => Err(Error::ParseError(ParseError::TypeMismatch)),
}
}
})*
}
}
from_response_direct!(
bool as Bool,
u8 as UInt8,
u16 as UInt16,
u32 as UInt32,
u64 as UInt64,
i8 as SInt8,
i16 as SInt16,
i32 as SInt32,
i64 as SInt64,
f32 as Float32,
f64 as Float64,
Vec<u8> as Binary,
Box<[u8]> as Binary,
String as String,
Box<str> as String,
Vec<Value> as List,
);
macro_rules! from_response_row {
($(($($elem:ident),*) as $size:literal),* $(,)?) => {
$(
impl<$($elem: FromValue),*> FromResponse for ($($elem),*,) {
fn from_response(resp: Response) -> ClientResult<Self> {
let row = match resp {
Response::Row(r) => r.into_values(),
Response::Empty | Response::Value(_) | Response::Rows(_) => return Err(Error::ParseError(ParseError::ResponseMismatch)),
Response::Error(e) => return Err(Error::ServerError(e)),
};
if row.len() != $size {
return Err(Error::ParseError(ParseError::TypeMismatch));
}
let mut values = row.into_iter();
Ok(($($elem::from_value(values.next().unwrap())?),*,))
}
}
impl<$($elem: FromValue),*> FromRow for ($($elem),*,) {
fn from_row(row: Row) -> ClientResult<Self> {
if row.values().len() != $size {
return Err(Error::ParseError(ParseError::TypeMismatch));
}
let mut values = row.into_values().into_iter();
Ok(($($elem::from_value(values.next().unwrap())?),*,))
}
}
)*
}
}
from_response_row!(
(A) as 1,
(A, B) as 2,
(A, B, C) as 3,
(A, B, C, D) as 4,
(A, B, C, D, E) as 5,
(A, B, C, D, E, F) as 6,
(A, B, C, D, E, F, G) as 7,
(A, B, C, D, E, F, G, H) as 8,
(A, B, C, D, E, F, G, H, I) as 9,
(A, B, C, D, E, F, G, H, I, J) as 10,
(A, B, C, D, E, F, G, H, I, J, K) as 11,
(A, B, C, D, E, F, G, H, I, J, K, L) as 12,
(A, B, C, D, E, F, G, H, I, J, K, L, M) as 13,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N) as 14,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) as 15,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) as 16,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) as 17,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) as 18,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S) as 19,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) as 20,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U) as 21,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V) as 22,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W) as 23,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X) as 24,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y) as 25,
(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z) as 26,
);
impl FromResponse for Row {
fn from_response(resp: Response) -> ClientResult<Self> {
match resp {
Response::Row(r) => Ok(r),
Response::Error(e) => Err(Error::ServerError(e)),
_ => Err(Error::ParseError(ParseError::ResponseMismatch)),
}
}
}
impl FromResponse for Vec<Row> {
fn from_response(resp: Response) -> ClientResult<Self> {
match resp {
Response::Rows(rows) => Ok(rows),
Response::Error(e) => Err(Error::ServerError(e)),
_ => Err(Error::ParseError(ParseError::ResponseMismatch)),
}
}
}
pub trait FromRow: Sized {
fn from_row(row: Row) -> ClientResult<Self>;
}
impl FromRow for Row {
fn from_row(row: Row) -> ClientResult<Self> {
Ok(row)
}
}
#[derive(Debug, PartialEq)]
pub struct Rows<T: FromRow = Row>(Vec<T>);
impl<T: FromRow> Rows<T> {
pub fn into_rows(self) -> Vec<T> {
self.0
}
}
impl<T: FromRow> FromResponse for Rows<T> {
fn from_response(resp: Response) -> ClientResult<Self> {
match resp {
Response::Rows(rows) => {
let mut ret = vec![];
for row in rows {
ret.push(T::from_row(row)?);
}
Ok(Self(ret))
}
Response::Error(e) => Err(Error::ServerError(e)),
_ => Err(Error::ParseError(ParseError::ResponseMismatch)),
}
}
}
impl<T: FromRow> Deref for Rows<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct RList<T = Value>(Vec<T>);
impl<T: FromValue> From<Vec<T>> for RList<T> {
fn from(values: Vec<T>) -> Self {
Self(values)
}
}
impl<T: FromValue> RList<T> {
pub fn into_values(self) -> Vec<T> {
self.0
}
}
impl<T: FromValue> Deref for RList<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: FromValue> FromValue for RList<T> {
fn from_value(v: Value) -> ClientResult<Self> {
match v {
Value::List(l) => {
let mut ret = Vec::new();
for value in l {
ret.push(T::from_value(value)?);
}
Ok(Self(ret))
}
_ => Err(Error::ParseError(ParseError::TypeMismatch)),
}
}
}
#[test]
fn resp_list_parse() {
let response_list = Response::Row(Row::new(vec![
Value::String("sayan".to_owned()),
Value::List(vec![
Value::String("c".to_owned()),
Value::String("assembly".to_owned()),
Value::String("rust".to_owned()),
]),
]));
let (name, languages) = response_list.parse::<(String, RList<String>)>().unwrap();
assert_eq!(name, "sayan");
assert_eq!(languages.as_ref(), vec!["c", "assembly", "rust"]);
}