shank-parse 0.1.1

A proc-macro crate that generates Rust client code from Shank/Anchor IDL JSON files for Solana programs.
Documentation
pub use shank_parse_macro::shank_parse;

#[doc(hidden)]
pub mod __private {
    pub use solana_sdk::instruction::{AccountMeta, Instruction};
    pub use solana_sdk::pubkey::Pubkey;

    use base64::Engine;

    pub fn base64_decode(input: &str) -> Result<Vec<u8>, base64::DecodeError> {
        base64::engine::general_purpose::STANDARD.decode(input)
    }

    pub fn base64_encode(data: &[u8]) -> String {
        base64::engine::general_purpose::STANDARD.encode(data)
    }

    // Read helpers

    pub fn read_u8(data: &[u8], offset: &mut usize) -> Result<u8, std::io::Error> {
        if *offset >= data.len() {
            return Err(std::io::Error::new(
                std::io::ErrorKind::UnexpectedEof,
                "unexpected eof",
            ));
        }
        let val = data[*offset];
        *offset += 1;
        Ok(val)
    }

    pub fn read_bool(data: &[u8], offset: &mut usize) -> Result<bool, std::io::Error> {
        Ok(read_u8(data, offset)? != 0)
    }

    macro_rules! impl_read_int {
        ($fname:ident, $ty:ty, $size:expr) => {
            pub fn $fname(data: &[u8], offset: &mut usize) -> Result<$ty, std::io::Error> {
                let end = *offset + $size;
                if end > data.len() {
                    return Err(std::io::Error::new(
                        std::io::ErrorKind::UnexpectedEof,
                        "unexpected eof",
                    ));
                }
                let mut bytes = [0u8; $size];
                bytes.copy_from_slice(&data[*offset..end]);
                *offset = end;
                Ok(<$ty>::from_le_bytes(bytes))
            }
        };
    }

    impl_read_int!(read_u16, u16, 2);
    impl_read_int!(read_u32, u32, 4);
    impl_read_int!(read_u64, u64, 8);
    impl_read_int!(read_u128, u128, 16);
    impl_read_int!(read_i8, i8, 1);
    impl_read_int!(read_i16, i16, 2);
    impl_read_int!(read_i32, i32, 4);
    impl_read_int!(read_i64, i64, 8);
    impl_read_int!(read_i128, i128, 16);

    pub fn read_bytes<const N: usize>(
        data: &[u8],
        offset: &mut usize,
    ) -> Result<[u8; N], std::io::Error> {
        let end = *offset + N;
        if end > data.len() {
            return Err(std::io::Error::new(
                std::io::ErrorKind::UnexpectedEof,
                "unexpected eof",
            ));
        }
        let mut bytes = [0u8; N];
        bytes.copy_from_slice(&data[*offset..end]);
        *offset = end;
        Ok(bytes)
    }

    // Write helpers

    pub fn write_u8(data: &mut Vec<u8>, val: u8) {
        data.push(val);
    }

    pub fn write_bool(data: &mut Vec<u8>, val: bool) {
        data.push(val as u8);
    }

    macro_rules! impl_write_int {
        ($fname:ident, $ty:ty) => {
            pub fn $fname(data: &mut Vec<u8>, val: $ty) {
                data.extend_from_slice(&val.to_le_bytes());
            }
        };
    }

    impl_write_int!(write_u16, u16);
    impl_write_int!(write_u32, u32);
    impl_write_int!(write_u64, u64);
    impl_write_int!(write_u128, u128);
    impl_write_int!(write_i8, i8);
    impl_write_int!(write_i16, i16);
    impl_write_int!(write_i32, i32);
    impl_write_int!(write_i64, i64);
    impl_write_int!(write_i128, i128);

    pub fn write_bytes(data: &mut Vec<u8>, val: &[u8]) {
        data.extend_from_slice(val);
    }
}