df_hyperliquid_core/utils/
units.rs1use crate::utils::dec::{Dec, Round};
6
7pub const USDC_DECIMALS: u32 = 6;
9
10pub const HYPE_DECIMALS: u32 = 8;
12
13#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
14pub enum BadUnits {
15 #[error("{0} is not a positive amount")]
16 NotPositive(Dec),
17 #[error("{value} has more than {places} decimal places")]
18 TooFine { value: Dec, places: u32 },
19 #[error("{0} is too large")]
20 TooLarge(Dec),
21}
22
23pub fn exact_units(value: Dec, places: u32) -> Result<u64, BadUnits> {
26 if value.places() > places {
27 return Err(BadUnits::TooFine { value, places });
28 }
29 cut_units(value, places)
30}
31
32pub fn cut_units(value: Dec, places: u32) -> Result<u64, BadUnits> {
35 if !value.is_positive() {
36 return Err(BadUnits::NotPositive(value));
37 }
38 let units = value.units_at(places, Round::Down).ok_or(BadUnits::TooLarge(value))?;
39 match u64::try_from(units) {
40 Ok(0) => Err(BadUnits::NotPositive(value)),
41 Ok(units) => Ok(units),
42 Err(_) => Err(BadUnits::TooLarge(value)),
43 }
44}
45
46#[cfg(test)]
47#[path = "tests/units.rs"]
48mod tests;