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(#[automatically_derived]
impl ::core::fmt::Debug for IntoRError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::StringTooLong { len: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "StringTooLong", "len", &__self_0),
            Self::LengthOverflow { len: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "LengthOverflow", "len", &__self_0),
            Self::Inner(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Inner",
                    &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for IntoRError {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::StringTooLong { len: __self_0 } =>
                IntoRError::StringTooLong {
                    len: ::core::clone::Clone::clone(__self_0),
                },
            Self::LengthOverflow { len: __self_0 } =>
                IntoRError::LengthOverflow {
                    len: ::core::clone::Clone::clone(__self_0),
                },
            Self::Inner(__self_0) =>
                IntoRError::Inner(::core::clone::Clone::clone(__self_0)),
        }
    }
}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                f.write_fmt(format_args!("string byte length {0} exceeds R\'s i32 limit ({1})",
        len, i32::MAX))write!(
35                    f,
36                    "string byte length {} exceeds R's i32 limit ({})",
37                    len,
38                    i32::MAX
39                )
40            }
41            IntoRError::LengthOverflow { len } => {
42                f.write_fmt(format_args!("collection length {0} overflows R vector capacity",
        len))write!(f, "collection length {} overflows R vector capacity", len)
43            }
44            IntoRError::Inner(msg) => f.write_fmt(format_args!("{0}", 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}