pub(crate) const DECIMAL_RUNS: &[(u32, u32)] = &[
(0x30, 0x39),
(0x660, 0x669),
(0x6F0, 0x6F9),
(0x7C0, 0x7C9),
(0x966, 0x96F),
(0x9E6, 0x9EF),
(0xA66, 0xA6F),
(0xAE6, 0xAEF),
(0xB66, 0xB6F),
(0xBE6, 0xBEF),
(0xC66, 0xC6F),
(0xCE6, 0xCEF),
(0xD66, 0xD6F),
(0xDE6, 0xDEF),
(0xE50, 0xE59),
(0xED0, 0xED9),
(0xF20, 0xF29),
(0x1040, 0x1049),
(0x1090, 0x1099),
(0x17E0, 0x17E9),
(0x1810, 0x1819),
(0x1946, 0x194F),
(0x19D0, 0x19D9),
(0x1A80, 0x1A89),
(0x1A90, 0x1A99),
(0x1B50, 0x1B59),
(0x1BB0, 0x1BB9),
(0x1C40, 0x1C49),
(0x1C50, 0x1C59),
(0xA620, 0xA629),
(0xA8D0, 0xA8D9),
(0xA900, 0xA909),
(0xA9D0, 0xA9D9),
(0xA9F0, 0xA9F9),
(0xAA50, 0xAA59),
(0xABF0, 0xABF9),
(0xFF10, 0xFF19),
(0x104A0, 0x104A9),
(0x10D30, 0x10D39),
(0x11066, 0x1106F),
(0x110F0, 0x110F9),
(0x11136, 0x1113F),
(0x111D0, 0x111D9),
(0x112F0, 0x112F9),
(0x11450, 0x11459),
(0x114D0, 0x114D9),
(0x11650, 0x11659),
(0x116C0, 0x116C9),
(0x11730, 0x11739),
(0x118E0, 0x118E9),
(0x11950, 0x11959),
(0x11C50, 0x11C59),
(0x11D50, 0x11D59),
(0x11DA0, 0x11DA9),
(0x11F50, 0x11F59),
(0x16A60, 0x16A69),
(0x16AC0, 0x16AC9),
(0x16B50, 0x16B59),
(0x1D7CE, 0x1D7D7),
(0x1D7D8, 0x1D7E1),
(0x1D7E2, 0x1D7EB),
(0x1D7EC, 0x1D7F5),
(0x1D7F6, 0x1D7FF),
(0x1E140, 0x1E149),
(0x1E2F0, 0x1E2F9),
(0x1E4F0, 0x1E4F9),
(0x1E950, 0x1E959),
(0x1FBF0, 0x1FBF9),
];
pub(crate) const NON_DECIMAL_DIGITS: &[u32] = &[
0xB2, 0xB3, 0xB9, 0x1369, 0x136A, 0x136B, 0x136C, 0x136D, 0x136E, 0x136F, 0x1370, 0x1371,
0x19DA, 0x2070, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079, 0x2080, 0x2081, 0x2082, 0x2083,
0x2084, 0x2085, 0x2086, 0x2087, 0x2088, 0x2089, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465,
0x2466, 0x2467, 0x2468, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247A, 0x247B, 0x247C,
0x2488, 0x2489, 0x248A, 0x248B, 0x248C, 0x248D, 0x248E, 0x248F, 0x2490, 0x24EA, 0x24F5, 0x24F6,
0x24F7, 0x24F8, 0x24F9, 0x24FA, 0x24FB, 0x24FC, 0x24FD, 0x24FF, 0x2776, 0x2777, 0x2778, 0x2779,
0x277A, 0x277B, 0x277C, 0x277D, 0x277E, 0x2780, 0x2781, 0x2782, 0x2783, 0x2784, 0x2785, 0x2786,
0x2787, 0x2788, 0x278A, 0x278B, 0x278C, 0x278D, 0x278E, 0x278F, 0x2790, 0x2791, 0x2792,
0x10A40, 0x10A41, 0x10A42, 0x10A43, 0x10E60, 0x10E61, 0x10E62, 0x10E63, 0x10E64, 0x10E65,
0x10E66, 0x10E67, 0x10E68, 0x11052, 0x11053, 0x11054, 0x11055, 0x11056, 0x11057, 0x11058,
0x11059, 0x1105A, 0x1F100, 0x1F101, 0x1F102, 0x1F103, 0x1F104, 0x1F105, 0x1F106, 0x1F107,
0x1F108, 0x1F109, 0x1F10A,
];
pub(crate) fn decimal_digit_value(c: char) -> Option<u32> {
let cp = c as u32;
DECIMAL_RUNS
.iter()
.find(|(zero, end)| cp >= *zero && cp <= *end)
.map(|(zero, _)| cp - zero)
}
pub(crate) fn is_python_digit(c: char) -> bool {
decimal_digit_value(c).is_some() || NON_DECIMAL_DIGITS.binary_search(&(c as u32)).is_ok()
}