fn parse_signed_to_satoshi(
    mut s: &str,
    denom: Denomination,
) -> Result<(bool, u64), ParseAmountError> {
    if s.len() == 0 {
        return Err(ParseAmountError::InvalidFormat);
    }
    if s.len() > 50 {
        return Err(ParseAmountError::InputTooLarge);
    }

    let is_negative = s.chars().next().unwrap() == '-';
    if is_negative {
        if s.len() == 1 {
            return Err(ParseAmountError::InvalidFormat);
        }
        s = &s[1..];
    }

    let max_decimals = {
        // The difference in precision between native (satoshi)
        // and desired denomination.
        let precision_diff = -denom.precision();
        if precision_diff < 0 {
            // If precision diff is negative, this means we are parsing
            // into a less precise amount. That is not allowed unless
            // there are no decimals and the last digits are zeroes as
            // many as the difference in precision.
            let last_n = precision_diff.abs() as usize;
            if is_too_precise(s, last_n) {
                return Err(ParseAmountError::TooPrecise);
            }
            s = &s[0..s.len() - last_n];
            0
        } else {
            precision_diff
        }
    };

    let mut decimals = None;
    let mut value: u64 = 0; // as satoshis
    for c in s.chars() {
        match c {
            '0'...'9' => {
                // Do `value = 10 * value + digit`, catching overflows.
                match 10_u64.checked_mul(value) {
                    None => return Err(ParseAmountError::TooBig),
                    Some(val) => match val.checked_add((c as u8 - b'0') as u64) {
                        None => return Err(ParseAmountError::TooBig),
                        Some(val) => value = val,
                    },
                }
                // Increment the decimal digit counter if past decimal.
                decimals = match decimals {
                    None => None,
                    Some(d) if d < max_decimals => Some(d + 1),
                    _ => return Err(ParseAmountError::TooPrecise),
                };
            }
            '.' => match decimals {
                None => decimals = Some(0),
                // Double decimal dot.
                _ => return Err(ParseAmountError::InvalidFormat),
            },
            c => return Err(ParseAmountError::InvalidCharacter(c)),
        }
    }

    // Decimally shift left by `max_decimals - decimals`.
    let scale_factor = max_decimals - decimals.unwrap_or(0);
    for _ in 0..scale_factor {
        value = match 10_u64.checked_mul(value) {
            Some(v) => v,
            None => return Err(ParseAmountError::TooBig),
        };
    }

    Ok((is_negative, value))
}
/// Parse decimal string in the given denomination into a satoshi value and a
/// bool indicator for a negative amount.
Parse decimal string in the given denomination into a satoshi value and a
bool indicator for a negative amount.
Parse decimal string in the given denomination into a satoshi value and a bool indicator for a negative amount .
fn parse_signed_to_satoshi(
    mut s: &str,
    denom: Denomination,
) -> Result<(bool, u64), ParseAmountError> {
    if s.len() == 0 {
        return Err(ParseAmountError::InvalidFormat);
    }
    if s.len() > 50 {
        return Err(ParseAmountError::InputTooLarge);
    }
    let is_negative = s.chars().next().unwrap() == '-';
    if is_negative {
        if s.len() == 1 {
            return Err(ParseAmountError::InvalidFormat);
        }
        s = &s[1..];
    }
    let max_decimals = {
        // The difference in precision between native (satoshi)
        // and desired denomination.
        let precision_diff = -denom.precision();
        if precision_diff < 0 {
            // If precision diff is negative, this means we are parsing
            // into a less precise amount. That is not allowed unless
            // there are no decimals and the last digits are zeroes as
            // many as the difference in precision.
            let last_n = precision_diff.abs() as usize;
            if is_too_precise(s, last_n) {
                return Err(ParseAmountError::TooPrecise);
            }
            s = &s[0..s.len() - last_n];
            0
        } else {
            precision_diff
        }
    };
    let mut decimals = None;
    let mut value: u64 = 0; // as satoshis
    for c in s.chars() {
        match c {
            '0'...'9' => {
                // Do `value = 10 * value + digit`, catching overflows.
                match 10_u64.checked_mul(value) {
                    None => return Err(ParseAmountError::TooBig),
                    Some(val) => match val.checked_add((c as u8 - b'0') as u64) {
                        None => return Err(ParseAmountError::TooBig),
                        Some(val) => value = val,
                    },
                }
                // Increment the decimal digit counter if past decimal.
                decimals = match decimals {
                    None => None,
                    Some(d) if d < max_decimals => Some(d + 1),
                    _ => return Err(ParseAmountError::TooPrecise),
                };
            }
            '.' => match decimals {
                None => decimals = Some(0),
                // Double decimal dot.
                _ => return Err(ParseAmountError::InvalidFormat),
            },
            c => return Err(ParseAmountError::InvalidCharacter(c)),
        }
    }
    // Decimally shift left by `max_decimals - decimals`.
    let scale_factor = max_decimals - decimals.unwrap_or(0);
    for _ in 0..scale_factor {
        value = match 10_u64.checked_mul(value) {
            Some(v) => v,
            None => return Err(ParseAmountError::TooBig),
        };
    }
    Ok((is_negative, value))
}
fn parse_signed_to_satoshi ( mut s : & str , denom : Denomination , ) -> Result < ( bool , u64 ) , ParseAmountError > { if s . len ( ) == 0 { return Err ( ParseAmountError :: InvalidFormat ) ; } if s . len ( ) > 50 { return Err ( ParseAmountError :: InputTooLarge ) ; } let is_negative = s . chars ( ) . next ( ) . unwrap ( ) == '-' ; if is_negative { if s . len ( ) == 1 { return Err ( ParseAmountError :: InvalidFormat ) ; } s = & s [ 1 .. ] ; } let max_decimals = { // The difference in precision between native (satoshi) // and desired denomination. let precision_diff = - denom . precision ( ) ; if precision_diff < 0 { // If precision diff is negative, this means we are parsing // into a less precise amount. That is not allowed unless // there are no decimals and the last digits are zeroes as // many as the difference in precision. let last_n = precision_diff . abs ( ) as usize ; if is_too_precise ( s , last_n ) { return Err ( ParseAmountError :: TooPrecise ) ; } s = & s [ 0 .. s . len ( ) - last_n ] ; 0 } else { precision_diff } } ; let mut decimals = None ; let mut value : u64 = 0 ; // as satoshis for c in s . chars ( ) { match c { '0' ... '9' => { // Do `value = 10 * value + digit`, catching overflows. match 10_u64 . checked_mul ( value ) { None => return Err ( ParseAmountError :: TooBig ) , Some ( val ) => match val . checked_add ( ( c as u8 - b'0' ) as u64 ) { None => return Err ( ParseAmountError :: TooBig ) , Some ( val ) => value = val , } , } // Increment the decimal digit counter if past decimal. decimals = match decimals { None => None , Some ( d ) if d < max_decimals => Some ( d + 1 ) , _ => return Err ( ParseAmountError :: TooPrecise ) , } ; } '.' => match decimals { None => decimals = Some ( 0 ) , // Double decimal dot. _ => return Err ( ParseAmountError :: InvalidFormat ) , } , c => return Err ( ParseAmountError :: InvalidCharacter ( c ) ) , } } // Decimally shift left by `max_decimals - decimals`. let scale_factor = max_decimals - decimals . unwrap_or ( 0 ) ; for _ in 0 .. scale_factor { value = match 10_u64 . checked_mul ( value ) { Some ( v ) => v , None => return Err ( ParseAmountError :: TooBig ) , } ; } Ok ( ( is_negative , value ) ) }
Parse decimal string in the given denomination into a satoshi value and a
bool indicator for a negative amount.
Parse decimal string in the given denomination into a satoshi value and a bool indicator for a negative amount .
s
&str
denom
Denomination
s
&str
denom
Denomination