Skip to main content

miniextendr_api/into_r/
owned_str.rs

1//! Scalar and vector conversions for owned unsized UTF-8 strings.
2use std::rc::Rc;
3use std::sync::Arc;
4
5use super::{
6    IntoR, opt_str_iter_to_strsxp, opt_str_iter_to_strsxp_unchecked, str_iter_to_strsxp,
7    str_iter_to_strsxp_unchecked,
8};
9use crate::SEXP;
10
11macro_rules! impl_shared_str_scalar {
12    ($owner:ident) => {
13        impl IntoR for $owner<str> {
14            type Error = crate::IntoRError;
15            fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
16                self.as_ref().try_into_sexp()
17            }
18            unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
19                unsafe { self.as_ref().try_into_sexp_unchecked() }
20            }
21        }
22    };
23}
24// Box<str> already reuses its allocation through String::from.
25impl IntoR for Rc<str> {
    type Error = crate::IntoRError;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        self.as_ref().try_into_sexp()
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        unsafe { self.as_ref().try_into_sexp_unchecked() }
    }
}impl_shared_str_scalar!(Rc);
26impl IntoR for Arc<str> {
    type Error = crate::IntoRError;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        self.as_ref().try_into_sexp()
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        unsafe { self.as_ref().try_into_sexp_unchecked() }
    }
}impl_shared_str_scalar!(Arc);
27
28macro_rules! impl_owned_str_vectors {
29    ($owner:ident) => {
30        impl IntoR for Option<$owner<str>> {
31            type Error = <Option<&'static str> as IntoR>::Error;
32            fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
33                self.as_deref().try_into_sexp()
34            }
35            unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
36                unsafe { self.as_deref().try_into_sexp_unchecked() }
37            }
38        }
39        impl IntoR for Vec<$owner<str>> {
40            type Error = std::convert::Infallible;
41            fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
42                Ok(str_iter_to_strsxp(self.iter().map(|s| s.as_ref())))
43            }
44            unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
45                Ok(unsafe { str_iter_to_strsxp_unchecked(self.iter().map(|s| s.as_ref())) })
46            }
47        }
48        impl IntoR for Vec<Option<$owner<str>>> {
49            type Error = std::convert::Infallible;
50            fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
51                Ok(opt_str_iter_to_strsxp(self.iter().map(|s| s.as_deref())))
52            }
53            unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
54                Ok(unsafe { opt_str_iter_to_strsxp_unchecked(self.iter().map(|s| s.as_deref())) })
55            }
56        }
57    };
58}
59impl IntoR for Option<Box<str>> {
    type Error = <Option<&'static str> as IntoR>::Error;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        self.as_deref().try_into_sexp()
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        unsafe { self.as_deref().try_into_sexp_unchecked() }
    }
}
impl IntoR for Vec<Box<str>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        Ok(str_iter_to_strsxp(self.iter().map(|s| s.as_ref())))
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        Ok(unsafe {
                str_iter_to_strsxp_unchecked(self.iter().map(|s| s.as_ref()))
            })
    }
}
impl IntoR for Vec<Option<Box<str>>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        Ok(opt_str_iter_to_strsxp(self.iter().map(|s| s.as_deref())))
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        Ok(unsafe {
                opt_str_iter_to_strsxp_unchecked(self.iter().map(|s|
                            s.as_deref()))
            })
    }
}impl_owned_str_vectors!(Box);
60impl IntoR for Option<Rc<str>> {
    type Error = <Option<&'static str> as IntoR>::Error;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        self.as_deref().try_into_sexp()
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        unsafe { self.as_deref().try_into_sexp_unchecked() }
    }
}
impl IntoR for Vec<Rc<str>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        Ok(str_iter_to_strsxp(self.iter().map(|s| s.as_ref())))
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        Ok(unsafe {
                str_iter_to_strsxp_unchecked(self.iter().map(|s| s.as_ref()))
            })
    }
}
impl IntoR for Vec<Option<Rc<str>>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        Ok(opt_str_iter_to_strsxp(self.iter().map(|s| s.as_deref())))
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        Ok(unsafe {
                opt_str_iter_to_strsxp_unchecked(self.iter().map(|s|
                            s.as_deref()))
            })
    }
}impl_owned_str_vectors!(Rc);
61impl IntoR for Option<Arc<str>> {
    type Error = <Option<&'static str> as IntoR>::Error;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        self.as_deref().try_into_sexp()
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        unsafe { self.as_deref().try_into_sexp_unchecked() }
    }
}
impl IntoR for Vec<Arc<str>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        Ok(str_iter_to_strsxp(self.iter().map(|s| s.as_ref())))
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        Ok(unsafe {
                str_iter_to_strsxp_unchecked(self.iter().map(|s| s.as_ref()))
            })
    }
}
impl IntoR for Vec<Option<Arc<str>>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
        Ok(opt_str_iter_to_strsxp(self.iter().map(|s| s.as_deref())))
    }
    unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error> {
        Ok(unsafe {
                opt_str_iter_to_strsxp_unchecked(self.iter().map(|s|
                            s.as_deref()))
            })
    }
}impl_owned_str_vectors!(Arc);