use codec::{Decode, Encode};
use scale_decode::{visitor::DecodeAsTypeResult, IntoVisitor, Visitor};
use scale_encode::EncodeAsType;
#[derive(Debug, Encode, Decode, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
pub struct Static<T>(pub T);
impl<T: Encode> EncodeAsType for Static<T> {
fn encode_as_type_to(
&self,
_type_id: u32,
_types: &scale_decode::PortableRegistry,
out: &mut Vec<u8>,
) -> Result<(), scale_encode::Error> {
self.0.encode_to(out);
Ok(())
}
}
pub struct StaticDecodeAsTypeVisitor<T>(std::marker::PhantomData<T>);
impl<T: Decode> Visitor for StaticDecodeAsTypeVisitor<T> {
type Value<'scale, 'info> = Static<T>;
type Error = scale_decode::Error;
fn unchecked_decode_as_type<'scale, 'info>(
self,
input: &mut &'scale [u8],
_type_id: scale_decode::visitor::TypeId,
_types: &'info scale_info::PortableRegistry,
) -> DecodeAsTypeResult<Self, Result<Self::Value<'scale, 'info>, Self::Error>> {
use scale_decode::{visitor::DecodeError, Error};
let decoded = T::decode(input)
.map(Static)
.map_err(|e| Error::new(DecodeError::CodecError(e).into()));
DecodeAsTypeResult::Decoded(decoded)
}
}
impl<T: Decode> IntoVisitor for Static<T> {
type Visitor = StaticDecodeAsTypeVisitor<T>;
fn into_visitor() -> Self::Visitor {
StaticDecodeAsTypeVisitor(std::marker::PhantomData)
}
}
impl<T> From<T> for Static<T> {
fn from(value: T) -> Self {
Static(value)
}
}
impl<T> std::ops::Deref for Static<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> std::ops::DerefMut for Static<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}