clone-solana-ledger 2.2.12

Solana ledger
Documentation
use std::{
    ops::{Deref, DerefMut},
    sync::Arc,
};

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Payload {
    Shared(Arc<Vec<u8>>),
    Unique(Vec<u8>),
}

macro_rules! make_mut {
    ($self:ident) => {
        match $self {
            Self::Shared(bytes) => Arc::make_mut(bytes),
            Self::Unique(bytes) => bytes,
        }
    };
}

macro_rules! dispatch {
    ($vis:vis fn $name:ident(&self $(, $arg:ident : $ty:ty)?) $(-> $out:ty)?) => {
        #[inline]
        $vis fn $name(&self $(, $arg:$ty)?) $(-> $out)? {
            match self {
                Self::Shared(bytes) => bytes.$name($($arg, )?),
                Self::Unique(bytes) => bytes.$name($($arg, )?),
            }
        }
    };
    ($vis:vis fn $name:ident(&mut self $(, $arg:ident : $ty:ty)*) $(-> $out:ty)?) => {
        #[inline]
        $vis fn $name(&mut self $(, $arg:$ty)*) $(-> $out)? {
            make_mut!(self).$name($($arg, )*)
        }
    }
}

impl Payload {
    #[cfg(test)]
    dispatch!(pub(crate) fn push(&mut self, byte: u8));

    #[inline]
    pub(crate) fn resize(&mut self, size: usize, byte: u8) {
        if self.len() != size {
            make_mut!(self).resize(size, byte);
        }
    }

    #[inline]
    pub(crate) fn truncate(&mut self, size: usize) {
        if self.len() > size {
            make_mut!(self).truncate(size);
        }
    }

    #[inline]
    pub fn unwrap_or_clone(this: Self) -> Vec<u8> {
        match this {
            Self::Shared(bytes) => Arc::unwrap_or_clone(bytes),
            Self::Unique(bytes) => bytes,
        }
    }
}

pub(crate) mod serde_bytes_payload {
    use {
        super::Payload,
        serde::{Deserialize, Deserializer, Serializer},
        serde_bytes::ByteBuf,
    };

    pub(crate) fn serialize<S: Serializer>(
        payload: &Payload,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_bytes(payload)
    }

    pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Payload, D::Error>
    where
        D: Deserializer<'de>,
    {
        Deserialize::deserialize(deserializer)
            .map(ByteBuf::into_vec)
            .map(Payload::from)
    }
}

impl From<Vec<u8>> for Payload {
    #[inline]
    fn from(bytes: Vec<u8>) -> Self {
        Self::Unique(bytes)
    }
}

impl From<Arc<Vec<u8>>> for Payload {
    #[inline]
    fn from(bytes: Arc<Vec<u8>>) -> Self {
        Self::Shared(bytes)
    }
}

impl AsRef<[u8]> for Payload {
    dispatch!(fn as_ref(&self) -> &[u8]);
}

impl Deref for Payload {
    type Target = [u8];
    dispatch!(fn deref(&self) -> &Self::Target);
}

impl DerefMut for Payload {
    dispatch!(fn deref_mut(&mut self) -> &mut Self::Target);
}