Skip to main content

miniextendr_api/
into_r_error.rs

1//! Error types for fallible [`IntoR`](crate::into_r::IntoR) conversions.
2//!
3//! [`IntoRError`] is returned by `try_into_sexp` when conversion fails
4//! (e.g., string exceeds R's `i32` length limit).
5
6/// Error returned by [`IntoR::try_into_sexp`](crate::into_r::IntoR::try_into_sexp)
7/// for types whose conversion to R can fail.
8///
9/// # Variants
10///
11/// - `StringTooLong` — a Rust string exceeds R's `i32` length limit (~2 GB)
12/// - `LengthOverflow` — a collection length exceeds R's `R_xlen_t` capacity
13/// - `Inner` — a sub-conversion failed (wraps the inner error message)
14#[derive(Debug, Clone)]
15pub enum IntoRError {
16    /// A string's byte length exceeds `i32::MAX`.
17    StringTooLong {
18        /// Actual byte length of the string.
19        len: usize,
20    },
21    /// A collection's element count exceeds the target R vector capacity.
22    LengthOverflow {
23        /// Actual element count.
24        len: usize,
25    },
26    /// A nested conversion failed.
27    Inner(String),
28}
29
30impl std::fmt::Display for IntoRError {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        match self {
33            IntoRError::StringTooLong { len } => {
34                write!(
35                    f,
36                    "string byte length {} exceeds R's i32 limit ({})",
37                    len,
38                    i32::MAX
39                )
40            }
41            IntoRError::LengthOverflow { len } => {
42                write!(f, "collection length {} overflows R vector capacity", len)
43            }
44            IntoRError::Inner(msg) => write!(f, "{}", msg),
45        }
46    }
47}
48
49impl std::error::Error for IntoRError {}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn display_string_too_long() {
57        let e = IntoRError::StringTooLong { len: 3_000_000_000 };
58        assert!(e.to_string().contains("3000000000"));
59        assert!(e.to_string().contains("i32 limit"));
60    }
61
62    #[test]
63    fn display_length_overflow() {
64        let e = IntoRError::LengthOverflow { len: 42 };
65        assert!(e.to_string().contains("42"));
66    }
67
68    #[test]
69    fn display_inner() {
70        let e = IntoRError::Inner("nested failure".to_string());
71        assert_eq!(e.to_string(), "nested failure");
72    }
73}