pub mod charge;
pub mod payment_request;
pub mod session;
pub use charge::ChargeRequest;
pub const INTENT_CHARGE: &str = "charge";
pub const INTENT_SESSION: &str = "session";
pub use payment_request::{
deserialize as deserialize_request, deserialize_typed as deserialize_request_typed,
from_challenge as request_from_challenge, from_challenge_typed as request_from_challenge_typed,
serialize as serialize_request, Request,
};
pub use session::SessionRequest;
pub fn parse_units(amount: &str, decimals: u8) -> crate::error::Result<String> {
if amount.is_empty() {
return Err(crate::error::MppError::InvalidAmount(
"Amount cannot be empty".to_string(),
));
}
let parts: Vec<&str> = amount.split('.').collect();
if parts.len() > 2 {
return Err(crate::error::MppError::InvalidAmount(format!(
"Invalid amount format: {}",
amount
)));
}
let integer_part = parts[0];
let fraction_part = if parts.len() == 2 { parts[1] } else { "" };
if fraction_part.len() > decimals as usize {
return Err(crate::error::MppError::InvalidAmount(format!(
"Amount {} has more than {} decimal places",
amount, decimals
)));
}
let padded_fraction = format!("{:0<width$}", fraction_part, width = decimals as usize);
let combined = format!("{}{}", integer_part, padded_fraction);
let result = combined.trim_start_matches('0');
if result.is_empty() {
Ok("0".to_string())
} else {
Ok(result.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_units_integer() {
assert_eq!(parse_units("100", 6).unwrap(), "100000000");
}
#[test]
fn test_parse_units_decimal() {
assert_eq!(parse_units("1.5", 6).unwrap(), "1500000");
}
#[test]
fn test_parse_units_small_decimal() {
assert_eq!(parse_units("0.001", 18).unwrap(), "1000000000000000");
}
#[test]
fn test_parse_units_zero() {
assert_eq!(parse_units("0", 6).unwrap(), "0");
}
#[test]
fn test_parse_units_zero_decimals() {
assert_eq!(parse_units("100", 0).unwrap(), "100");
}
#[test]
fn test_parse_units_too_many_decimal_places() {
assert!(parse_units("1.1234567", 6).is_err());
}
#[test]
fn test_parse_units_no_integer_part() {
assert_eq!(parse_units("0.5", 6).unwrap(), "500000");
}
#[test]
fn test_parse_units_empty_string() {
assert!(parse_units("", 6).is_err());
}
}