use std::{
any::{type_name, Any},
fmt,
};
use serde::Serialize;
use crate::ProcedureError;
pub struct DynOutput<'a> {
inner: Repr<'a>,
pub(crate) type_name: &'static str,
}
enum Repr<'a> {
Serialize(&'a (dyn erased_serde::Serialize + Send + Sync)),
Value(&'a mut (dyn Any + Send)),
}
impl<'a> DynOutput<'a> {
pub(crate) fn new_value<T: Send + 'static>(value: &'a mut T) -> Self {
Self {
inner: Repr::Value(value),
type_name: type_name::<T>(),
}
}
pub fn new_serialize<T: Serialize + Send + Sync>(value: &'a mut T) -> Self {
Self {
inner: Repr::Serialize(value),
type_name: type_name::<T>(),
}
}
pub fn as_serialize(self) -> Option<impl Serialize + Send + Sync + 'a> {
match self.inner {
Repr::Serialize(v) => Some(v),
Repr::Value(_) => None,
}
}
pub fn as_value<T: Send + 'static>(self) -> Option<T> {
match self.inner {
Repr::Serialize(_) => None,
Repr::Value(v) => v
.downcast_mut::<Option<Result<T, ProcedureError>>>()?
.take()
.expect("unreachable")
.ok(),
}
}
}
impl<'a> fmt::Debug for DynOutput<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
todo!();
}
}