use safer_ffi::char_p;
use crate::{error::DittoError, utils::zstr::ZString};
#[derive(Debug, Clone, PartialEq)]
pub struct QueryV2<Args> {
pub(crate) string: ZString,
pub(crate) args: Args,
pub(crate) args_cbor: Option<Vec<u8>>,
}
pub trait IntoQuery {
type Args;
fn into_query(self) -> Result<QueryV2<Self::Args>, DittoError>;
}
impl<A> IntoQuery for QueryV2<A> {
type Args = A;
fn into_query(self) -> Result<QueryV2<Self::Args>, DittoError> {
Ok(self)
}
}
impl<Q: ?Sized> IntoQuery for &Q
where
Q: ToOwned,
Q::Owned: IntoQuery,
{
type Args = <Q::Owned as IntoQuery>::Args;
fn into_query(self) -> Result<QueryV2<Self::Args>, DittoError> {
let owned = self.to_owned();
owned.into_query()
}
}
impl<Q, A> IntoQuery for (Q, A)
where
Q: IntoQuery<Args = ()>,
A: serde::Serialize,
{
type Args = A;
fn into_query(self) -> Result<QueryV2<Self::Args>, DittoError> {
let (string, args) = self;
let string = string.into_query()?.string;
let args_cbor = serde_cbor::to_vec(&args).unwrap();
Ok(QueryV2 {
string,
args,
args_cbor: Some(args_cbor),
})
}
}
impl IntoQuery for String {
type Args = ();
fn into_query(self) -> Result<QueryV2<Self::Args>, DittoError> {
Ok(QueryV2 {
string: char_p::new(self).into(),
args: (),
args_cbor: None,
})
}
}