use std::fmt::Debug;
use serde::{de::DeserializeOwned, Serialize};
pub trait Abi: ContractAbi + ServiceAbi {}
impl<T> Abi for T where T: ContractAbi + ServiceAbi {}
pub trait ContractAbi {
type Operation: Serialize + DeserializeOwned + Send + Sync + Debug + 'static;
type Response: Serialize + DeserializeOwned + Send + Sync + Debug + 'static;
fn deserialize_operation(operation: Vec<u8>) -> Result<Self::Operation, String> {
bcs::from_bytes(&operation)
.map_err(|e| format!("BCS deserialization error {e:?} for operation {operation:?}"))
}
fn serialize_operation(operation: &Self::Operation) -> Result<Vec<u8>, String> {
bcs::to_bytes(operation)
.map_err(|e| format!("BCS serialization error {e:?} for operation {operation:?}"))
}
fn deserialize_response(response: Vec<u8>) -> Result<Self::Response, String> {
bcs::from_bytes(&response)
.map_err(|e| format!("BCS deserialization error {e:?} for response {response:?}"))
}
fn serialize_response(response: Self::Response) -> Result<Vec<u8>, String> {
bcs::to_bytes(&response)
.map_err(|e| format!("BCS serialization error {e:?} for response {response:?}"))
}
}
pub trait ServiceAbi {
type Query: Serialize + DeserializeOwned + Send + Sync + Debug + 'static;
type QueryResponse: Serialize + DeserializeOwned + Send + Sync + Debug + 'static;
}
pub trait WithContractAbi {
type Abi: ContractAbi;
}
impl<A> ContractAbi for A
where
A: WithContractAbi,
{
type Operation = <<A as WithContractAbi>::Abi as ContractAbi>::Operation;
type Response = <<A as WithContractAbi>::Abi as ContractAbi>::Response;
}
pub trait WithServiceAbi {
type Abi: ServiceAbi;
}
impl<A> ServiceAbi for A
where
A: WithServiceAbi,
{
type Query = <<A as WithServiceAbi>::Abi as ServiceAbi>::Query;
type QueryResponse = <<A as WithServiceAbi>::Abi as ServiceAbi>::QueryResponse;
}