1#![allow(clippy::arithmetic_side_effects)]
2#![deny(missing_docs)]
3#![cfg_attr(not(test), forbid(unsafe_code))]
4
5pub mod error;
8pub mod instruction;
9pub mod native_mint;
10pub mod processor;
11pub mod state;
12
13#[cfg(not(feature = "no-entrypoint"))]
14mod entrypoint;
15
16pub mod atlas_program {
19 #![allow(missing_docs)]
20 pub mod entrypoint {
21 pub use atlas_program_error::ProgramResult;
22 }
23 pub mod instruction {
24 pub use atlas_instruction::{AccountMeta, Instruction};
25 }
26 pub mod program_error {
27 pub use atlas_program_error::ProgramError;
28 }
29 pub mod program_option {
30 pub use atlas_program_option::COption;
31 }
32 pub mod program_pack {
33 pub use atlas_program_pack::{IsInitialized, Pack, Sealed};
34 }
35 pub mod pubkey {
36 pub use atlas_pubkey::{Pubkey, PUBKEY_BYTES};
37 }
38}
39use atlas_program_error::ProgramError;
40pub use atlas_token_interface::{check_id, check_program_account, id, ID};
42
43pub fn ui_amount_to_amount(ui_amount: f64, decimals: u8) -> u64 {
46 (ui_amount * 10_usize.pow(decimals as u32) as f64) as u64
47}
48
49pub fn amount_to_ui_amount(amount: u64, decimals: u8) -> f64 {
52 amount as f64 / 10_usize.pow(decimals as u32) as f64
53}
54
55pub fn amount_to_ui_amount_string(amount: u64, decimals: u8) -> String {
58 let decimals = decimals as usize;
59 if decimals > 0 {
60 let mut s = format!("{:01$}", amount, decimals + 1);
62 s.insert(s.len() - decimals, '.');
64 s
65 } else {
66 amount.to_string()
67 }
68}
69
70pub fn amount_to_ui_amount_string_trimmed(amount: u64, decimals: u8) -> String {
73 let mut s = amount_to_ui_amount_string(amount, decimals);
74 if decimals > 0 {
75 let zeros_trimmed = s.trim_end_matches('0');
76 s = zeros_trimmed.trim_end_matches('.').to_string();
77 }
78 s
79}
80
81pub fn try_ui_amount_into_amount(ui_amount: String, decimals: u8) -> Result<u64, ProgramError> {
84 let decimals = decimals as usize;
85 let mut parts = ui_amount.split('.');
86 let mut amount_str = parts.next().unwrap().to_string();
89 let after_decimal = parts.next().unwrap_or("");
90 let after_decimal = after_decimal.trim_end_matches('0');
91 if (amount_str.is_empty() && after_decimal.is_empty())
92 || parts.next().is_some()
93 || after_decimal.len() > decimals
94 {
95 return Err(ProgramError::InvalidArgument);
96 }
97
98 amount_str.push_str(after_decimal);
99 for _ in 0..decimals.saturating_sub(after_decimal.len()) {
100 amount_str.push('0');
101 }
102 amount_str
103 .parse::<u64>()
104 .map_err(|_| ProgramError::InvalidArgument)
105}