use schemars::JsonSchema;
use serde::{Serialize, de::DeserializeOwned};
pub trait ElicitProxy: Sized {
type Proxy: Serialize + DeserializeOwned + JsonSchema;
fn into_proxy(self) -> Self::Proxy;
fn from_proxy(proxy: Self::Proxy) -> Self;
}
macro_rules! identity_proxy {
($($t:ty),+ $(,)?) => {
$(
impl ElicitProxy for $t {
type Proxy = $t;
fn into_proxy(self) -> $t { self }
fn from_proxy(proxy: $t) -> $t { proxy }
}
)+
};
}
identity_proxy!(
bool, i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, isize, usize, f32, f64, char, String,
);
impl ElicitProxy for serde_json::Value {
type Proxy = serde_json::Value;
fn into_proxy(self) -> serde_json::Value {
self
}
fn from_proxy(proxy: serde_json::Value) -> serde_json::Value {
proxy
}
}
impl<T: ElicitProxy> ElicitProxy for Option<T>
where
Option<T::Proxy>: Serialize + DeserializeOwned + JsonSchema,
{
type Proxy = Option<T::Proxy>;
fn into_proxy(self) -> Option<T::Proxy> {
self.map(T::into_proxy)
}
fn from_proxy(proxy: Option<T::Proxy>) -> Self {
proxy.map(T::from_proxy)
}
}
impl<T: ElicitProxy> ElicitProxy for Vec<T>
where
Vec<T::Proxy>: Serialize + DeserializeOwned + JsonSchema,
{
type Proxy = Vec<T::Proxy>;
fn into_proxy(self) -> Vec<T::Proxy> {
self.into_iter().map(T::into_proxy).collect()
}
fn from_proxy(proxy: Vec<T::Proxy>) -> Self {
proxy.into_iter().map(T::from_proxy).collect()
}
}
impl<T: ElicitProxy, E: ElicitProxy> ElicitProxy for Result<T, E>
where
Result<T::Proxy, E::Proxy>: Serialize + DeserializeOwned + JsonSchema,
{
type Proxy = Result<T::Proxy, E::Proxy>;
fn into_proxy(self) -> Result<T::Proxy, E::Proxy> {
self.map(T::into_proxy).map_err(E::into_proxy)
}
fn from_proxy(proxy: Result<T::Proxy, E::Proxy>) -> Self {
proxy.map(T::from_proxy).map_err(E::from_proxy)
}
}