1#[derive(Debug, thiserror::Error)]
5#[non_exhaustive]
6pub enum CoreError {
7 #[error("integer {0} exceeds the 2^53 JCS-safe bound")]
10 UnsafeInteger(u64),
11 #[error("arithmetic overflow in {context}")]
13 Overflow {
14 context: &'static str,
16 },
17 #[error("invalid identifier: {0}")]
19 InvalidId(String),
20}
21
22pub const JCS_SAFE_MAX: u64 = 1 << 53;
27
28pub fn check_jcs_safe(n: u64) -> Result<u64, CoreError> {
30 if n > JCS_SAFE_MAX {
31 Err(CoreError::UnsafeInteger(n))
32 } else {
33 Ok(n)
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn jcs_bound_accepts_max() {
43 assert!(check_jcs_safe(JCS_SAFE_MAX).is_ok());
44 assert!(check_jcs_safe(0).is_ok());
45 }
46
47 #[test]
48 fn jcs_bound_rejects_above_max() {
49 assert!(check_jcs_safe(JCS_SAFE_MAX + 1).is_err());
50 assert!(check_jcs_safe(u64::MAX).is_err());
51 }
52}
53
54#[cfg(test)]
55mod const_tests {
56 #[test]
60 fn jcs_safe_max_is_two_to_the_53rd() {
61 assert_eq!(super::JCS_SAFE_MAX, 9_007_199_254_740_992);
62 assert_eq!(super::JCS_SAFE_MAX, 2u64.pow(53));
63 }
64}