Skip to main content

oxc_ecmascript/
string_to_big_int.rs

1use num_bigint::BigInt;
2use num_traits::{Num, Zero};
3
4/// `StringToBigInt`
5///
6/// <https://tc39.es/ecma262/#sec-stringtobigint>
7pub trait StringToBigInt<'a> {
8    fn string_to_big_int(&self) -> Option<BigInt>;
9}
10
11impl StringToBigInt<'_> for &str {
12    fn string_to_big_int(&self) -> Option<BigInt> {
13        if self.contains('\u{000b}') {
14            // vertical tab is not always whitespace
15            return None;
16        }
17
18        let s = self.trim();
19
20        if s.is_empty() {
21            return Some(BigInt::zero());
22        }
23
24        if s.len() > 2 && s.as_bytes()[0] == b'0' {
25            // `| 32` converts upper case ASCII letters to lower case.
26            // A bit more efficient than testing for `b'x' | b'X'`.
27            // https://godbolt.org/z/Korrhd4TE
28            let radix: u32 = match s.as_bytes()[1] | 32 {
29                b'x' => 16,
30                b'o' => 8,
31                b'b' => 2,
32                _ => return None,
33            };
34
35            return BigInt::from_str_radix(&s[2..], radix).ok();
36        }
37
38        BigInt::from_str_radix(s, 10).ok()
39    }
40}