hpl-toolkit 0.0.5

HPL toolkit
Documentation
use std::io::Read;

use anchor_lang::prelude::*;

#[cfg(feature = "compression")]
use crate::compression::*;

#[cfg(feature = "schema")]
use crate::schema::*;

#[cfg_attr(feature = "debug", derive(Debug))]
#[derive(Clone, Eq, PartialEq)]
pub struct ShortString(String);

impl ShortString {
    pub fn new(string: String) -> std::io::Result<Self> {
        if string.len() > 255 {
            return Err(std::io::Error::new(
                std::io::ErrorKind::InvalidInput,
                "Short string length shall not exceed 255",
            ));
        }
        Ok(Self(string))
    }

    pub fn new_unchecked(string: String) -> Self {
        Self::new(string).expect("Short string length shall not exceed 255")
    }

    pub unsafe fn new_unsafe(string: String) -> Self {
        Self::new_unchecked(string)
    }

    pub fn to_string(&self) -> String {
        self.0.clone()
    }

    pub fn as_str(&self) -> &str {
        self.0.as_str()
    }
}

impl From<String> for ShortString {
    fn from(value: String) -> Self {
        Self::new_unchecked(value)
    }
}

impl From<&String> for ShortString {
    fn from(value: &String) -> Self {
        Self::new_unchecked(value.to_owned())
    }
}

impl Into<String> for ShortString {
    fn into(self) -> String {
        self.0
    }
}

impl PartialEq<String> for ShortString {
    fn eq(&self, other: &String) -> bool {
        self.0 == *other
    }
}

impl From<&str> for ShortString {
    fn from(value: &str) -> Self {
        Self::new_unchecked(value.to_string())
    }
}

impl AnchorSerialize for ShortString {
    fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
        let length = self.0.len() as u8;
        length.serialize(writer)?;
        writer.write(self.0.as_bytes())?;
        Ok(())
    }
}

impl AnchorDeserialize for ShortString {
    fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
        let mut buf: [u8; 1] = [0; 1];
        let limit = reader.read(&mut buf)?;
        if limit != 1 {
            #[cfg(feature = "log")]
            crate::logger::debug!("limit: {}, Buf: {:?}", limit, buf);
            return Err(std::io::Error::new(
                std::io::ErrorKind::InvalidInput,
                "Unexpected length of input",
            ));
        }

        let mut string = String::new();
        reader.take(buf[0] as u64).read_to_string(&mut string)?;
        Ok(Self(string))
    }
}

#[cfg(feature = "idl-build")]
impl anchor_lang::IdlBuild for ShortString {
    /// Returns the full module path of the type.
    fn get_full_path() -> String {
        format!(
            "{0}::{1}",
            "hpl_toolkit::utils::short_string", "ShortString",
        )
    }
}

#[cfg(feature = "compression")]
impl ToNode for ShortString {
    fn to_node(&self) -> [u8; 32] {
        self.0.to_node()
    }
}

#[cfg(feature = "schema")]
impl ToSchema for ShortString {
    fn schema() -> Schema {
        String::schema()
    }

    fn schema_value(&self) -> SchemaValue {
        self.0.schema_value()
    }
}