use candid::{encode_one, CandidType};
use ic_cdk::api::{msg_reject, msg_reply};
use ic_cdk::trap;
use std::marker::PhantomData;
#[derive(Debug, Copy, Clone, Default)]
pub struct ManualReply<T: ?Sized>(PhantomData<T>);
impl<T: ?Sized> ManualReply<T> {
const fn done() -> Self {
Self(PhantomData)
}
pub fn one<U>(value: U) -> Self
where
U: CandidType,
{
let bytes =
encode_one(value).unwrap_or_else(|e| trap(format!("Candid encode failed: {e}")));
msg_reply(bytes);
Self::done()
}
pub fn reject(message: impl AsRef<str>) -> Self {
msg_reject(message.as_ref());
Self::done()
}
}
impl<T> CandidType for ManualReply<T>
where
T: CandidType + ?Sized,
{
fn _ty() -> candid::types::Type {
T::_ty()
}
fn idl_serialize<S>(&self, _: S) -> Result<(), S::Error>
where
S: candid::types::Serializer,
{
Err(<S::Error as serde::ser::Error>::custom(
"ManualReply cannot be serialized (manual_reply = true)",
))
}
}