use { super::{check_account_owner, MAX_FORMATTED_DIGITS, U64_BYTES}, core::str::from_utf8_unchecked, pinocchio::{ account_info::AccountInfo, program::set_return_data, program_error::ProgramError, ProgramResult, }, pinocchio_log::logger::{Argument, Logger}, spl_token_interface::{ error::TokenError, state::{load, mint::Mint}, }, }; pub fn process_amount_to_ui_amount( accounts: &[AccountInfo], instruction_data: &[u8], ) -> ProgramResult { let amount = if instruction_data.len() >= U64_BYTES { // SAFETY: The minimum size of the instruction data is `U64_BYTES` bytes. unsafe { u64::from_le_bytes(*(instruction_data.as_ptr() as *const [u8; U64_BYTES])) } } else { return Err(TokenError::InvalidInstruction.into()); }; let mint_info = accounts.first().ok_or(ProgramError::NotEnoughAccountKeys)?; check_account_owner(mint_info)?; // SAFETY: single immutable borrow to `mint_info` account data and // `load` validates that the mint is initialized. let mint = unsafe { load::(mint_info.borrow_data_unchecked()).map_err(|_| TokenError::InvalidMint)? }; let mut logger = Logger::::default(); logger.append_with_args(amount, &[Argument::Precision(mint.decimals)]); // "Extract" the formatted string from the logger. // // SAFETY: the logger is guaranteed to be a valid UTF-8 string. let mut s = unsafe { from_utf8_unchecked(&logger) }; if mint.decimals > 0 && s.contains('.') { let zeros_trimmed = s.trim_end_matches('0'); s = zeros_trimmed.trim_end_matches('.'); } set_return_data(s.as_bytes()); Ok(()) }