Skip to main content

miniextendr_api/
adapter_traits.rs

1//! Built-in adapter traits for common Rust standard library traits.
2//!
3//! These traits provide blanket implementations that allow any Rust type
4//! implementing standard traits to be exposed to R without boilerplate.
5//!
6//! # Example
7//!
8//! ```rust,ignore
9//! use miniextendr_api::prelude::*;
10//! use miniextendr_api::adapter_traits::RDebug;
11//!
12//! #[derive(Debug, ExternalPtr)]
13//! struct MyData {
14//!     values: Vec<i32>,
15//! }
16//!
17//! // RDebug is automatically available for any Debug type
18//! #[miniextendr]
19//! impl RDebug for MyData {}
20//! ```
21//!
22//! In R:
23//! ```r
24//! data <- MyData$new(...)
25//! data$debug_str()        # "MyData { values: [1, 2, 3] }"
26//! data$debug_str_pretty() # Pretty-printed with newlines
27//! ```
28
29use crate::miniextendr;
30use std::collections::hash_map::DefaultHasher;
31use std::fmt::{Debug, Display};
32use std::hash::{Hash, Hasher};
33use std::str::FromStr;
34
35/// Adapter trait for [`std::fmt::Debug`].
36///
37/// Provides string representations for debugging and inspection in R.
38/// Automatically implemented for any type that implements `Debug`.
39///
40/// # Methods
41///
42/// - `debug_str()` - Returns compact debug string (`:?` format)
43/// - `debug_str_pretty()` - Returns pretty-printed debug string (`:#?` format)
44///
45/// # Example
46///
47/// ```rust,ignore
48/// #[derive(Debug, ExternalPtr)]
49/// struct Config { name: String, value: i32 }
50///
51/// #[miniextendr]
52/// impl RDebug for Config {}
53/// ```
54#[miniextendr]
55pub trait RDebug {
56    /// Get a compact debug string representation.
57    fn debug_str(&self) -> String;
58
59    /// Get a pretty-printed debug string with indentation.
60    fn debug_str_pretty(&self) -> String;
61}
62
63impl<T: Debug> RDebug for T {
64    fn debug_str(&self) -> String {
65        format!("{:?}", self)
66    }
67
68    fn debug_str_pretty(&self) -> String {
69        format!("{:#?}", self)
70    }
71}
72
73/// Adapter trait for [`std::fmt::Display`].
74///
75/// Provides user-friendly string conversion for R.
76/// Automatically implemented for any type that implements `Display`.
77///
78/// # Methods
79///
80/// - `as_r_string()` - Returns the Display representation
81///
82/// # Example
83///
84/// ```rust,ignore
85/// struct Version(u32, u32, u32);
86///
87/// impl Display for Version {
88///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89///         write!(f, "{}.{}.{}", self.0, self.1, self.2)
90///     }
91/// }
92///
93/// #[miniextendr]
94/// impl RDisplay for Version {}
95/// ```
96#[miniextendr]
97pub trait RDisplay {
98    /// Convert to a user-friendly string.
99    fn as_r_string(&self) -> String;
100}
101
102impl<T: Display> RDisplay for T {
103    fn as_r_string(&self) -> String {
104        self.to_string()
105    }
106}
107
108/// Adapter trait for [`std::hash::Hash`].
109///
110/// Provides hashing for deduplication and environment keys in R.
111/// Automatically implemented for any type that implements `Hash`.
112///
113/// # Methods
114///
115/// - `hash()` - Returns a 64-bit hash as i64
116///
117/// # Note
118///
119/// Hash values are deterministic within a single R session but may vary
120/// between sessions due to Rust's hasher implementation.
121///
122/// # Example
123///
124/// ```rust,ignore
125/// #[derive(Hash, ExternalPtr)]
126/// struct Record { id: String, value: i64 }
127///
128/// #[miniextendr]
129/// impl RHash for Record {}
130/// ```
131#[miniextendr]
132pub trait RHash {
133    /// Compute a hash of this value.
134    fn hash(&self) -> i64;
135}
136
137impl<T: Hash> RHash for T {
138    fn hash(&self) -> i64 {
139        let mut hasher = DefaultHasher::new();
140        self.hash(&mut hasher);
141        hasher.finish() as i64
142    }
143}
144
145/// Adapter trait for [`std::cmp::Ord`].
146///
147/// Provides total ordering comparison for R sorting operations.
148/// Automatically implemented for any type that implements `Ord`.
149///
150/// # Methods
151///
152/// - `cmp(&self, other: &Self)` - Returns -1, 0, or 1
153///
154/// # Example
155///
156/// ```rust,ignore
157/// #[derive(Ord, PartialOrd, Eq, PartialEq, ExternalPtr)]
158/// struct Priority(u32);
159///
160/// #[miniextendr]
161/// impl ROrd for Priority {}
162/// ```
163#[miniextendr]
164pub trait ROrd {
165    /// Compare with another value.
166    ///
167    /// Returns:
168    /// - `-1` if `self < other`
169    /// - `0` if `self == other`
170    /// - `1` if `self > other`
171    fn cmp(&self, other: &Self) -> i32;
172}
173
174impl<T: Ord> ROrd for T {
175    fn cmp(&self, other: &Self) -> i32 {
176        match self.cmp(other) {
177            std::cmp::Ordering::Less => -1,
178            std::cmp::Ordering::Equal => 0,
179            std::cmp::Ordering::Greater => 1,
180        }
181    }
182}
183
184/// Adapter trait for [`std::cmp::PartialOrd`].
185///
186/// Provides partial ordering comparison for R, handling incomparable values.
187/// Automatically implemented for any type that implements `PartialOrd`.
188///
189/// # Methods
190///
191/// - `partial_cmp(&self, other: &Self)` - Returns Some(-1/0/1) or None
192///
193/// # Example
194///
195/// ```rust,ignore
196/// // f64 has partial ordering (NaN is not comparable)
197/// #[derive(PartialOrd, PartialEq, ExternalPtr)]
198/// struct MyFloat(f64);
199///
200/// #[miniextendr]
201/// impl RPartialOrd for MyFloat {}
202/// ```
203#[miniextendr]
204pub trait RPartialOrd {
205    /// Compare with another value, returning None if incomparable.
206    ///
207    /// Returns:
208    /// - `Some(-1)` if `self < other`
209    /// - `Some(0)` if `self == other`
210    /// - `Some(1)` if `self > other`
211    /// - `None` if values are incomparable (maps to NA in R)
212    fn partial_cmp(&self, other: &Self) -> Option<i32>;
213}
214
215impl<T: PartialOrd> RPartialOrd for T {
216    fn partial_cmp(&self, other: &Self) -> Option<i32> {
217        self.partial_cmp(other).map(|ord| match ord {
218            std::cmp::Ordering::Less => -1,
219            std::cmp::Ordering::Equal => 0,
220            std::cmp::Ordering::Greater => 1,
221        })
222    }
223}
224
225/// Adapter trait for [`std::error::Error`].
226///
227/// Provides error message extraction and error chain walking for R.
228/// Automatically implemented for any type that implements `Error`.
229///
230/// # Methods
231///
232/// - `error_message()` - Returns the error's display message
233/// - `error_chain()` - Returns all messages in the error chain
234///
235/// # Example
236///
237/// ```rust,ignore
238/// use std::error::Error;
239/// use std::fmt;
240///
241/// #[derive(Debug)]
242/// struct MyError { msg: String, source: Option<Box<dyn Error + Send + Sync>> }
243///
244/// impl fmt::Display for MyError {
245///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
246///         write!(f, "{}", self.msg)
247///     }
248/// }
249///
250/// impl Error for MyError {
251///     fn source(&self) -> Option<&(dyn Error + 'static)> {
252///         self.source.as_ref().map(|e| e.as_ref() as _)
253///     }
254/// }
255///
256/// // Wrap in ExternalPtr for R access
257/// #[derive(ExternalPtr)]
258/// struct MyErrorWrapper(MyError);
259///
260/// #[miniextendr]
261/// impl RError for MyErrorWrapper {}
262/// ```
263#[miniextendr]
264pub trait RError {
265    /// Get the error message (Display representation).
266    fn error_message(&self) -> String;
267
268    /// Get all error messages in the chain, from outermost to innermost.
269    fn error_chain(&self) -> Vec<String>;
270
271    /// Get the number of errors in the chain.
272    fn error_chain_length(&self) -> i32;
273}
274
275impl<T: std::error::Error> RError for T {
276    fn error_message(&self) -> String {
277        self.to_string()
278    }
279
280    fn error_chain(&self) -> Vec<String> {
281        let mut chain = vec![self.to_string()];
282        let mut current: &dyn std::error::Error = self;
283        while let Some(source) = current.source() {
284            chain.push(source.to_string());
285            current = source;
286        }
287        chain
288    }
289
290    fn error_chain_length(&self) -> i32 {
291        let mut count = 1i32;
292        let mut current: &dyn std::error::Error = self;
293        while let Some(source) = current.source() {
294            count += 1;
295            current = source;
296        }
297        count
298    }
299}
300
301/// Adapter trait for [`std::str::FromStr`].
302///
303/// Provides string parsing for R, allowing R strings to be parsed into Rust types.
304/// Automatically implemented for any type that implements `FromStr`.
305///
306/// # Methods
307///
308/// - `from_str(s: &str)` - Parse a string into this type, returning None on failure
309///
310/// # Example
311///
312/// ```rust,ignore
313/// use std::net::IpAddr;
314///
315/// // IpAddr implements FromStr
316/// #[derive(ExternalPtr)]
317/// struct IpAddress(IpAddr);
318///
319/// #[miniextendr]
320/// impl RFromStr for IpAddress {}
321/// ```
322///
323/// In R:
324/// ```r
325/// ip <- IpAddress$from_str("192.168.1.1")
326/// ```
327#[miniextendr]
328pub trait RFromStr: Sized {
329    /// Parse a string into this type.
330    ///
331    /// Returns `Some(value)` on success, `None` on parse failure.
332    /// The None case maps to NULL in R.
333    fn from_str(s: &str) -> Option<Self>;
334}
335
336impl<T: FromStr> RFromStr for T {
337    fn from_str(s: &str) -> Option<Self> {
338        s.parse().ok()
339    }
340}
341
342/// Adapter trait for [`std::clone::Clone`].
343///
344/// Provides explicit deep copying for R. This is useful when R users need
345/// to create independent copies of Rust objects (which normally use reference
346/// semantics via `ExternalPtr`).
347///
348/// # Methods
349///
350/// - `clone()` - Create a deep copy of this value
351///
352/// # Example
353///
354/// ```rust,ignore
355/// #[derive(Clone, ExternalPtr)]
356/// struct Buffer { data: Vec<u8> }
357///
358/// #[miniextendr]
359/// impl RClone for Buffer {}
360/// ```
361///
362/// In R:
363/// ```r
364/// buf1 <- Buffer$new(...)
365/// buf2 <- buf1$clone()  # Independent copy
366/// ```
367#[miniextendr]
368pub trait RClone {
369    /// Create a deep copy of this value.
370    fn clone(&self) -> Self;
371}
372
373impl<T: Clone> RClone for T {
374    fn clone(&self) -> Self {
375        self.clone()
376    }
377}
378
379/// Adapter trait for [`std::default::Default`].
380///
381/// Provides default value construction for R. This allows R users to create
382/// instances with default values without needing to specify all parameters.
383///
384/// # Methods
385///
386/// - `default()` - Create a new instance with default values
387///
388/// # Example
389///
390/// ```rust,ignore
391/// #[derive(Default, ExternalPtr)]
392/// struct Config {
393///     timeout: u32,     // defaults to 0
394///     retries: u32,     // defaults to 0
395///     verbose: bool,    // defaults to false
396/// }
397///
398/// #[miniextendr]
399/// impl RDefault for Config {}
400/// ```
401///
402/// In R:
403/// ```r
404/// config <- Config$default()  # All fields have default values
405/// ```
406#[miniextendr]
407pub trait RDefault {
408    /// Create a new instance with default values.
409    fn default() -> Self;
410}
411
412impl<T: Default> RDefault for T {
413    fn default() -> Self {
414        Self::default()
415    }
416}
417
418/// Adapter trait for [`std::marker::Copy`].
419///
420/// Indicates that a type can be cheaply copied (bitwise copy, no heap allocation).
421/// This is useful for R users to know that copying is O(1) and doesn't involve
422/// deep cloning of heap data.
423///
424/// # Methods
425///
426/// - `copy()` - Create a bitwise copy of this value
427/// - `is_copy()` - Returns true (useful for runtime type checking in R)
428///
429/// # Difference from RClone
430///
431/// Both `RCopy` and `RClone` create copies, but:
432/// - `RCopy`: Only for types where copying is cheap (stack-only, no heap)
433/// - `RClone`: For any clonable type (may involve heap allocation)
434///
435/// If a type implements both, prefer `copy()` when you know copies are frequent.
436///
437/// # Example
438///
439/// ```rust,ignore
440/// #[derive(Copy, Clone, ExternalPtr)]
441/// struct Point { x: f64, y: f64 }
442///
443/// #[miniextendr]
444/// impl RCopy for Point {}
445/// ```
446///
447/// In R:
448/// ```r
449/// p1 <- Point$new(1.0, 2.0)
450/// p2 <- p1$copy()  # Cheap bitwise copy
451/// p1$is_copy()       # TRUE
452/// ```
453#[miniextendr]
454pub trait RCopy {
455    /// Create a bitwise copy of this value.
456    ///
457    /// For Copy types, this is always cheap (O(1), no heap allocation).
458    fn copy(&self) -> Self;
459
460    /// Check if this type implements Copy.
461    ///
462    /// Always returns true for types implementing this trait.
463    /// Useful for runtime type checking in R.
464    fn is_copy(&self) -> bool;
465}
466
467impl<T: Copy> RCopy for T {
468    fn copy(&self) -> Self {
469        *self
470    }
471
472    fn is_copy(&self) -> bool {
473        true
474    }
475}
476
477/// Adapter trait for [`std::iter::Iterator`].
478///
479/// Provides iterator operations for R, allowing Rust iterators to be consumed
480/// element-by-element from R code. Since iterators are stateful, the wrapper
481/// type should use interior mutability (e.g., `RefCell`).
482///
483/// # Methods
484///
485/// - `next()` - Get the next element, or None if exhausted
486/// - `size_hint()` - Get estimated remaining elements as `c(lower, upper)`
487/// - `count()` - Consume and count remaining elements
488/// - `collect_n(n)` - Collect up to n elements into a vector
489/// - `skip(n)` - Skip n elements
490/// - `nth(n)` - Get the nth element (0-indexed)
491///
492/// # Example
493///
494/// ```rust,ignore
495/// use std::cell::RefCell;
496///
497/// #[derive(ExternalPtr)]
498/// struct MyIter(RefCell<std::vec::IntoIter<i32>>);
499///
500/// impl MyIter {
501///     fn new(data: Vec<i32>) -> Self {
502///         Self(RefCell::new(data.into_iter()))
503///     }
504/// }
505///
506/// impl RIterator for MyIter {
507///     type Item = i32;
508///
509///     fn next(&self) -> Option<Self::Item> {
510///         self.0.borrow_mut().next()
511///     }
512///
513///     fn size_hint(&self) -> (i64, Option<i64>) {
514///         let (lo, hi) = self.0.borrow().size_hint();
515///         (lo as i64, hi.map(|h| h as i64))
516///     }
517/// }
518///
519/// #[miniextendr]
520/// impl RIterator for MyIter {}
521/// ```
522///
523/// In R (note: `next` is a reserved word, so expose as `next_item` or similar):
524/// ```r
525/// it <- MyIter$new(c(1L, 2L, 3L))
526/// it$next_item()   # 1L
527/// it$next_item()   # 2L
528/// it$size_hint()   # c(1, 1) - one element remaining
529/// it$next_item()   # 3L
530/// it$next_item()   # NULL (exhausted)
531/// ```
532///
533/// # Design Note
534///
535/// Unlike other adapter traits, `RIterator` does NOT have a blanket impl
536/// because iterators require `&mut self` for `next()`, but R's ExternalPtr
537/// pattern typically provides `&self`. Users must implement this trait
538/// manually using interior mutability (RefCell, Mutex, etc.).
539#[miniextendr]
540pub trait RIterator {
541    /// The type of elements yielded by this iterator.
542    type Item;
543
544    /// Get the next element from the iterator.
545    ///
546    /// Returns `Some(item)` if there are more elements, `None` if exhausted.
547    /// None maps to NULL in R.
548    #[miniextendr(r_name = "next_item")]
549    fn next(&self) -> Option<Self::Item>;
550
551    /// Get the estimated number of remaining elements.
552    ///
553    /// Returns `(lower_bound, upper_bound)` where upper_bound is None if unknown.
554    /// In R, this becomes `c(lower, upper)` where upper is NA if unknown.
555    ///
556    /// Skipped from trait ABI because tuples don't have R conversions.
557    /// Expose via manual forwarding or custom wrapper methods.
558    #[miniextendr(skip)]
559    fn size_hint(&self) -> (i64, Option<i64>);
560
561    /// Consume the iterator and count remaining elements.
562    ///
563    /// **Warning:** This exhausts the iterator.
564    fn count(&self) -> i64 {
565        let mut count = 0i64;
566        while self.next().is_some() {
567            count += 1;
568        }
569        count
570    }
571
572    /// Collect up to `n` elements into a vector.
573    ///
574    /// Returns fewer than `n` elements if the iterator is exhausted first.
575    fn collect_n(&self, n: i32) -> Vec<Self::Item> {
576        let mut result = Vec::with_capacity(n.max(0) as usize);
577        for _ in 0..n {
578            match self.next() {
579                Some(item) => result.push(item),
580                None => break,
581            }
582        }
583        result
584    }
585
586    /// Skip `n` elements from the iterator.
587    ///
588    /// Returns the number of elements actually skipped (may be less than `n`
589    /// if the iterator is exhausted).
590    fn skip(&self, n: i32) -> i32 {
591        let mut skipped = 0i32;
592        for _ in 0..n {
593            if self.next().is_none() {
594                break;
595            }
596            skipped += 1;
597        }
598        skipped
599    }
600
601    /// Get the `n`th element (0-indexed), consuming elements up to and including it.
602    ///
603    /// Returns None if the iterator has fewer than `n + 1` elements.
604    fn nth(&self, n: i32) -> Option<Self::Item> {
605        if n < 0 {
606            return None;
607        }
608        for _ in 0..n {
609            self.next()?;
610        }
611        self.next()
612    }
613}
614
615// Note: No blanket impl because Iterator::next() requires &mut self,
616// but ExternalPtr methods receive &self. Users must use interior mutability.
617
618/// Adapter trait for [`std::iter::Extend`].
619///
620/// Provides collection extension operations for R, allowing Rust collections
621/// to be extended with R vectors. Since extension requires mutation, the
622/// wrapper type should use interior mutability (e.g., `RefCell`).
623///
624/// # Methods
625///
626/// - `extend_from_vec(items)` - Extend the collection with items from a vector
627/// - `extend_from_slice(items)` - Extend from a slice (for Clone items)
628///
629/// # Example
630///
631/// ```rust,ignore
632/// use std::cell::RefCell;
633///
634/// #[derive(ExternalPtr)]
635/// struct MyVec(RefCell<Vec<i32>>);
636///
637/// impl MyVec {
638///     fn new() -> Self {
639///         Self(RefCell::new(Vec::new()))
640///     }
641/// }
642///
643/// impl RExtend<i32> for MyVec {
644///     fn extend_from_vec(&self, items: Vec<i32>) {
645///         self.0.borrow_mut().extend(items);
646///     }
647/// }
648///
649/// #[miniextendr]
650/// impl RExtend<i32> for MyVec {}
651/// ```
652///
653/// In R:
654/// ```r
655/// v <- MyVec$new()
656/// v$extend_from_vec(c(1L, 2L, 3L))  # Add items
657/// v$extend_from_vec(c(4L, 5L))      # Add more items
658/// ```
659///
660/// # Design Note
661///
662/// Like `RIterator`, `RExtend` does NOT have a blanket impl because `Extend::extend()`
663/// requires `&mut self`, but R's ExternalPtr pattern provides `&self`. Users must
664/// implement this trait manually using interior mutability (RefCell, Mutex, etc.).
665#[miniextendr]
666pub trait RExtend<T> {
667    /// Extend the collection with items from a vector.
668    ///
669    /// The items are moved into the collection.
670    fn extend_from_vec(&self, items: Vec<T>);
671
672    /// Extend the collection with cloned items from a slice.
673    ///
674    /// Default implementation clones items into a Vec and calls `extend_from_vec`.
675    ///
676    /// Skipped from trait ABI because `&[T]` doesn't have TryFromSexp.
677    #[miniextendr(skip)]
678    fn extend_from_slice(&self, items: &[T])
679    where
680        T: Clone,
681    {
682        self.extend_from_vec(items.to_vec());
683    }
684
685    /// Get the current length of the collection.
686    ///
687    /// Optional - returns -1 if not implemented.
688    fn len(&self) -> i64 {
689        -1 // Indicates "unknown" - implementers can override
690    }
691
692    /// Check if the collection is empty.
693    ///
694    /// Returns false when length is unknown.
695    fn is_empty(&self) -> bool {
696        self.len() == 0
697    }
698}
699
700// Note: No blanket impl because Extend::extend() requires &mut self,
701// but ExternalPtr methods receive &self. Users must use interior mutability.
702
703/// Adapter trait for [`std::iter::FromIterator`].
704///
705/// Provides collection construction from iterators/vectors for R.
706/// Unlike `RExtend`, this creates a new collection from items.
707///
708/// # Methods
709///
710/// - `from_vec(items)` - Create a new collection from a vector
711///
712/// # Example
713///
714/// ```rust,ignore
715/// #[derive(ExternalPtr)]
716/// struct MySet(std::collections::HashSet<i32>);
717///
718/// impl RFromIter<i32> for MySet {
719///     fn from_vec(items: Vec<i32>) -> Self {
720///         Self(items.into_iter().collect())
721///     }
722/// }
723///
724/// #[miniextendr]
725/// impl RFromIter<i32> for MySet {}
726/// ```
727///
728/// In R:
729/// ```r
730/// set <- MySet$from_vec(c(1L, 2L, 2L, 3L))  # Creates {1, 2, 3}
731/// ```
732#[miniextendr]
733pub trait RFromIter<T>: Sized {
734    /// Create a new collection from a vector of items.
735    fn from_vec(items: Vec<T>) -> Self;
736}
737
738impl<C, T> RFromIter<T> for C
739where
740    C: FromIterator<T>,
741{
742    fn from_vec(items: Vec<T>) -> Self {
743        items.into_iter().collect()
744    }
745}
746
747/// Adapter trait for collections that can be converted to vectors.
748///
749/// This is the complement to [`RFromIter`]: while `RFromIter` creates collections
750/// from vectors, `RToVec` extracts vectors from collections.
751///
752/// # Methods
753///
754/// - `to_vec()` - Collect all elements into a vector (cloning elements)
755/// - `len()` - Get the number of elements
756/// - `is_empty()` - Check if the collection is empty
757///
758/// # Design Note
759///
760/// Unlike Rust's `IntoIterator::into_iter()` which consumes the collection,
761/// this trait borrows the collection and clones elements. This is necessary
762/// because R's `ExternalPtr` pattern provides `&self`, not owned `self`.
763///
764/// For consuming iteration, use [`RIterator`] with interior mutability.
765///
766/// # Example
767///
768/// ```rust,ignore
769/// use std::collections::HashSet;
770///
771/// #[derive(ExternalPtr)]
772/// struct MySet(HashSet<i32>);
773///
774/// // RToVec is automatically available via blanket impl
775/// #[miniextendr]
776/// impl RToVec<i32> for MySet {}
777/// ```
778///
779/// In R:
780/// ```r
781/// set <- MySet$new(...)
782/// vec <- set$to_vec()    # Get all elements as vector
783/// set$len()              # Number of elements
784/// set$is_empty()         # Check if empty
785/// ```
786#[miniextendr]
787pub trait RToVec<T> {
788    /// Collect all elements into a vector.
789    ///
790    /// Elements are cloned from the collection.
791    fn to_vec(&self) -> Vec<T>;
792
793    /// Get the number of elements in the collection.
794    fn len(&self) -> i64;
795
796    /// Check if the collection is empty.
797    fn is_empty(&self) -> bool {
798        self.len() == 0
799    }
800}
801
802// Blanket impl for any collection where:
803// - &C can be iterated over (yielding &T references)
804// - T: Clone (so we can clone elements into the Vec)
805// - The iterator knows its exact size
806//
807// Note: Using HRTB (higher-ranked trait bounds) to express that &C
808// can be iterated for any lifetime.
809impl<C, T> RToVec<T> for C
810where
811    T: Clone,
812    for<'a> &'a C: IntoIterator<Item = &'a T>,
813    for<'a> <&'a C as IntoIterator>::IntoIter: ExactSizeIterator,
814{
815    fn to_vec(&self) -> Vec<T> {
816        self.into_iter().cloned().collect()
817    }
818
819    fn len(&self) -> i64 {
820        self.into_iter().len() as i64
821    }
822}
823
824/// Adapter trait for creating iterator wrappers from collections.
825///
826/// This trait provides a way to create an [`RIterator`] wrapper from a collection.
827/// Since `ExternalPtr` methods receive `&self`, this trait clones the underlying
828/// data to create an independent iterator.
829///
830/// # Type Parameters
831///
832/// - `T`: The element type yielded by the iterator
833/// - `I`: The iterator type returned (must implement [`RIterator`])
834///
835/// # Design Note
836///
837/// The returned iterator is independent from the source collection. Modifications
838/// to the original collection after calling `make_iter()` won't affect the
839/// iterator's output.
840///
841/// # Example
842///
843/// ```rust,ignore
844/// use std::cell::RefCell;
845///
846/// #[derive(ExternalPtr)]
847/// struct MyVec(Vec<i32>);
848///
849/// #[derive(ExternalPtr)]
850/// struct MyVecIter(RefCell<std::vec::IntoIter<i32>>);
851///
852/// impl RIterator for MyVecIter {
853///     type Item = i32;
854///     fn next(&self) -> Option<i32> {
855///         self.0.borrow_mut().next()
856///     }
857///     fn size_hint(&self) -> (i64, Option<i64>) {
858///         let (lo, hi) = self.0.borrow().size_hint();
859///         (lo as i64, hi.map(|h| h as i64))
860///     }
861/// }
862///
863/// impl RMakeIter<i32, MyVecIter> for MyVec {
864///     fn make_iter(&self) -> MyVecIter {
865///         MyVecIter(RefCell::new(self.0.clone().into_iter()))
866///     }
867/// }
868///
869/// #[miniextendr]
870/// impl RMakeIter<i32, MyVecIter> for MyVec {}
871/// ```
872///
873/// In R (note: expose `next` as `next_item` since `next` is reserved):
874/// ```r
875/// v <- MyVec$new(c(1L, 2L, 3L))
876/// it <- v$make_iter()   # Create iterator
877/// it$next_item()        # 1L
878/// it$next_item()        # 2L
879/// v$to_vec()            # c(1L, 2L, 3L) - original unchanged
880/// ```
881#[miniextendr]
882pub trait RMakeIter<T, I>
883where
884    I: RIterator<Item = T>,
885{
886    /// Create a new iterator wrapper.
887    ///
888    /// The iterator is independent from this collection (typically by cloning
889    /// the underlying data).
890    fn make_iter(&self) -> I;
891}
892
893// Note: No blanket impl because:
894// 1. The iterator type I must be a concrete type that implements RIterator
895// 2. RIterator requires interior mutability (RefCell/Mutex)
896// 3. Users must define their own iterator wrapper type
897
898#[cfg(test)]
899mod tests {
900    use super::*;
901
902    #[test]
903    fn test_rdebug() {
904        let v = vec![1, 2, 3];
905        assert_eq!(v.debug_str(), "[1, 2, 3]");
906        assert!(v.debug_str_pretty().contains('\n') || v.debug_str_pretty() == "[1, 2, 3]");
907    }
908
909    #[test]
910    fn test_rdisplay() {
911        let s = "hello";
912        assert_eq!(s.as_r_string(), "hello");
913
914        let n = 42i32;
915        assert_eq!(n.as_r_string(), "42");
916    }
917
918    #[test]
919    fn test_rhash() {
920        let a = "test";
921        let b = "test";
922        let c = "other";
923
924        assert_eq!(RHash::hash(&a), RHash::hash(&b));
925        assert_ne!(RHash::hash(&a), RHash::hash(&c));
926    }
927
928    #[test]
929    fn test_rord() {
930        assert_eq!(ROrd::cmp(&1i32, &2), -1);
931        assert_eq!(ROrd::cmp(&2i32, &2), 0);
932        assert_eq!(ROrd::cmp(&3i32, &2), 1);
933    }
934
935    #[test]
936    fn test_rpartialord() {
937        assert_eq!(RPartialOrd::partial_cmp(&1.0f64, &2.0), Some(-1));
938        assert_eq!(RPartialOrd::partial_cmp(&2.0f64, &2.0), Some(0));
939        assert_eq!(RPartialOrd::partial_cmp(&3.0f64, &2.0), Some(1));
940        assert_eq!(RPartialOrd::partial_cmp(&f64::NAN, &1.0), None);
941    }
942
943    #[test]
944    fn test_rerror_simple() {
945        use std::io;
946        let err = io::Error::new(io::ErrorKind::NotFound, "file not found");
947        assert_eq!(err.error_message(), "file not found");
948        assert_eq!(err.error_chain().len(), 1);
949        assert_eq!(err.error_chain_length(), 1);
950    }
951
952    #[test]
953    fn test_rerror_chain() {
954        use std::fmt;
955
956        #[derive(Debug)]
957        struct OuterError {
958            msg: &'static str,
959            source: InnerError,
960        }
961
962        #[derive(Debug)]
963        struct InnerError {
964            msg: &'static str,
965        }
966
967        impl fmt::Display for OuterError {
968            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
969                write!(f, "{}", self.msg)
970            }
971        }
972
973        impl fmt::Display for InnerError {
974            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
975                write!(f, "{}", self.msg)
976            }
977        }
978
979        impl std::error::Error for InnerError {}
980
981        impl std::error::Error for OuterError {
982            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
983                Some(&self.source)
984            }
985        }
986
987        let err = OuterError {
988            msg: "outer error",
989            source: InnerError { msg: "inner error" },
990        };
991
992        assert_eq!(err.error_message(), "outer error");
993        let chain = err.error_chain();
994        assert_eq!(chain.len(), 2);
995        assert_eq!(chain[0], "outer error");
996        assert_eq!(chain[1], "inner error");
997        assert_eq!(err.error_chain_length(), 2);
998    }
999
1000    #[test]
1001    fn test_rfromstr_success() {
1002        let result: Option<i32> = RFromStr::from_str("42");
1003        assert_eq!(result, Some(42));
1004
1005        let result: Option<f64> = RFromStr::from_str("3.141592653589793");
1006        assert_eq!(result, Some(f64::consts::PI));
1007
1008        let result: Option<bool> = RFromStr::from_str("true");
1009        assert_eq!(result, Some(true));
1010    }
1011
1012    #[test]
1013    fn test_rfromstr_failure() {
1014        let result: Option<i32> = RFromStr::from_str("not a number");
1015        assert_eq!(result, None);
1016
1017        let result: Option<f64> = RFromStr::from_str("abc");
1018        assert_eq!(result, None);
1019    }
1020
1021    #[test]
1022    fn test_rclone() {
1023        let v = vec![1, 2, 3];
1024        let cloned = RClone::clone(&v);
1025        assert_eq!(v, cloned);
1026
1027        // Verify it's a deep copy
1028        let s = String::from("hello");
1029        let cloned_s = RClone::clone(&s);
1030        assert_eq!(s, cloned_s);
1031    }
1032
1033    #[test]
1034    fn test_rdefault() {
1035        let default_i32: i32 = RDefault::default();
1036        assert_eq!(default_i32, 0);
1037
1038        let default_vec: Vec<i32> = RDefault::default();
1039        assert!(default_vec.is_empty());
1040
1041        let default_string: String = RDefault::default();
1042        assert_eq!(default_string, "");
1043
1044        let default_bool: bool = RDefault::default();
1045        assert!(!default_bool);
1046    }
1047
1048    #[test]
1049    fn test_rcopy() {
1050        // Primitives are Copy
1051        let x = 42i32;
1052        let y = RCopy::copy(&x);
1053        assert_eq!(x, y);
1054        assert!(x.is_copy());
1055
1056        // Tuples of Copy types are Copy
1057        let point = (1.0f64, 2.0f64);
1058        let point2 = RCopy::copy(&point);
1059        assert_eq!(point, point2);
1060        assert!(point.is_copy());
1061
1062        // Arrays of Copy types are Copy
1063        let arr = [1, 2, 3];
1064        let arr2 = RCopy::copy(&arr);
1065        assert_eq!(arr, arr2);
1066    }
1067
1068    use core::f64;
1069    // Tests for RIterator
1070    use std::cell::RefCell;
1071
1072    /// Test iterator wrapper using RefCell for interior mutability.
1073    struct TestIter(RefCell<std::vec::IntoIter<i32>>);
1074
1075    impl TestIter {
1076        fn new(data: Vec<i32>) -> Self {
1077            Self(RefCell::new(data.into_iter()))
1078        }
1079    }
1080
1081    impl RIterator for TestIter {
1082        type Item = i32;
1083
1084        fn next(&self) -> Option<Self::Item> {
1085            self.0.borrow_mut().next()
1086        }
1087
1088        fn size_hint(&self) -> (i64, Option<i64>) {
1089            let (lo, hi) = self.0.borrow().size_hint();
1090            (lo as i64, hi.map(|h| h as i64))
1091        }
1092    }
1093
1094    #[test]
1095    fn test_riterator_next() {
1096        let it = TestIter::new(vec![1, 2, 3]);
1097        assert_eq!(it.next(), Some(1));
1098        assert_eq!(it.next(), Some(2));
1099        assert_eq!(it.next(), Some(3));
1100        assert_eq!(it.next(), None);
1101        assert_eq!(it.next(), None); // Stays exhausted
1102    }
1103
1104    #[test]
1105    fn test_riterator_size_hint() {
1106        let it = TestIter::new(vec![1, 2, 3, 4, 5]);
1107        assert_eq!(it.size_hint(), (5, Some(5)));
1108        it.next();
1109        assert_eq!(it.size_hint(), (4, Some(4)));
1110        it.next();
1111        it.next();
1112        assert_eq!(it.size_hint(), (2, Some(2)));
1113    }
1114
1115    #[test]
1116    fn test_riterator_count() {
1117        let it = TestIter::new(vec![1, 2, 3, 4, 5]);
1118        assert_eq!(it.count(), 5);
1119        // Iterator is now exhausted
1120        assert_eq!(it.next(), None);
1121    }
1122
1123    #[test]
1124    fn test_riterator_collect_n() {
1125        let it = TestIter::new(vec![1, 2, 3, 4, 5]);
1126        let first_three = it.collect_n(3);
1127        assert_eq!(first_three, vec![1, 2, 3]);
1128        let remaining = it.collect_n(10); // Ask for more than available
1129        assert_eq!(remaining, vec![4, 5]);
1130    }
1131
1132    #[test]
1133    fn test_riterator_skip() {
1134        let it = TestIter::new(vec![1, 2, 3, 4, 5]);
1135        let skipped = it.skip(2);
1136        assert_eq!(skipped, 2);
1137        assert_eq!(it.next(), Some(3));
1138
1139        // Skip more than remaining
1140        let skipped = it.skip(10);
1141        assert_eq!(skipped, 2); // Only 2 elements were left
1142    }
1143
1144    #[test]
1145    fn test_riterator_nth() {
1146        let it = TestIter::new(vec![10, 20, 30, 40, 50]);
1147        // Get element at index 2 (third element)
1148        assert_eq!(it.nth(2), Some(30));
1149        // Iterator has consumed 0, 1, 2 - next is index 3
1150        assert_eq!(it.next(), Some(40));
1151
1152        // Negative index returns None
1153        let it2 = TestIter::new(vec![1, 2, 3]);
1154        assert_eq!(it2.nth(-1), None);
1155    }
1156
1157    #[test]
1158    fn test_riterator_empty() {
1159        let it = TestIter::new(vec![]);
1160        assert_eq!(it.next(), None);
1161        assert_eq!(it.size_hint(), (0, Some(0)));
1162        assert_eq!(it.count(), 0);
1163        assert_eq!(it.collect_n(5), Vec::<i32>::new());
1164        assert_eq!(it.skip(5), 0);
1165        assert_eq!(it.nth(0), None);
1166    }
1167
1168    // Tests for RExtend
1169    struct TestExtendVec(RefCell<Vec<i32>>);
1170
1171    impl TestExtendVec {
1172        fn new() -> Self {
1173            Self(RefCell::new(Vec::new()))
1174        }
1175
1176        fn get(&self) -> Vec<i32> {
1177            Clone::clone(&*self.0.borrow())
1178        }
1179    }
1180
1181    impl RExtend<i32> for TestExtendVec {
1182        fn extend_from_vec(&self, items: Vec<i32>) {
1183            self.0.borrow_mut().extend(items);
1184        }
1185
1186        fn len(&self) -> i64 {
1187            self.0.borrow().len() as i64
1188        }
1189    }
1190
1191    #[test]
1192    fn test_rextend_basic() {
1193        let v = TestExtendVec::new();
1194        assert_eq!(v.get(), Vec::<i32>::new());
1195        assert_eq!(v.len(), 0);
1196
1197        v.extend_from_vec(vec![1, 2, 3]);
1198        assert_eq!(v.get(), vec![1, 2, 3]);
1199        assert_eq!(v.len(), 3);
1200
1201        v.extend_from_vec(vec![4, 5]);
1202        assert_eq!(v.get(), vec![1, 2, 3, 4, 5]);
1203        assert_eq!(v.len(), 5);
1204    }
1205
1206    #[test]
1207    fn test_rextend_empty() {
1208        let v = TestExtendVec::new();
1209        v.extend_from_vec(vec![]);
1210        assert_eq!(v.get(), Vec::<i32>::new());
1211        assert_eq!(v.len(), 0);
1212    }
1213
1214    #[test]
1215    fn test_rextend_from_slice() {
1216        let v = TestExtendVec::new();
1217        let data = [1, 2, 3];
1218        v.extend_from_slice(&data);
1219        assert_eq!(v.get(), vec![1, 2, 3]);
1220    }
1221
1222    // Tests for RFromIter
1223    #[test]
1224    fn test_rfromiter_vec() {
1225        let v: Vec<i32> = RFromIter::from_vec(vec![1, 2, 3]);
1226        assert_eq!(v, vec![1, 2, 3]);
1227    }
1228
1229    #[test]
1230    fn test_rfromiter_hashset() {
1231        use std::collections::HashSet;
1232        let set: HashSet<i32> = RFromIter::from_vec(vec![1, 2, 2, 3, 3, 3]);
1233        assert_eq!(set.len(), 3);
1234        assert!(set.contains(&1));
1235        assert!(set.contains(&2));
1236        assert!(set.contains(&3));
1237    }
1238
1239    #[test]
1240    fn test_rfromiter_string() {
1241        let s: String = RFromIter::from_vec(vec!['h', 'e', 'l', 'l', 'o']);
1242        assert_eq!(s, "hello");
1243    }
1244
1245    #[test]
1246    fn test_rfromiter_empty() {
1247        let v: Vec<i32> = RFromIter::from_vec(vec![]);
1248        assert!(v.is_empty());
1249    }
1250
1251    // Tests for RToVec
1252    #[test]
1253    fn test_rtovec_vec() {
1254        let v = vec![1, 2, 3];
1255        let collected: Vec<i32> = RToVec::to_vec(&v);
1256        assert_eq!(collected, vec![1, 2, 3]);
1257        assert_eq!(RToVec::<i32>::len(&v), 3);
1258        assert!(!RToVec::<i32>::is_empty(&v));
1259    }
1260
1261    #[test]
1262    fn test_rtovec_empty() {
1263        let v: Vec<i32> = vec![];
1264        let collected: Vec<i32> = RToVec::to_vec(&v);
1265        assert!(collected.is_empty());
1266        assert_eq!(RToVec::<i32>::len(&v), 0);
1267        assert!(RToVec::<i32>::is_empty(&v));
1268    }
1269
1270    #[test]
1271    fn test_rtovec_hashset() {
1272        use std::collections::HashSet;
1273        let mut set = HashSet::new();
1274        set.insert(1);
1275        set.insert(2);
1276        set.insert(3);
1277
1278        let mut collected: Vec<i32> = RToVec::to_vec(&set);
1279        collected.sort();
1280        assert_eq!(collected, vec![1, 2, 3]);
1281        assert_eq!(RToVec::<i32>::len(&set), 3);
1282    }
1283
1284    #[test]
1285    fn test_rtovec_slice() {
1286        let arr = [10, 20, 30];
1287        let collected: Vec<i32> = RToVec::to_vec(&arr);
1288        assert_eq!(collected, vec![10, 20, 30]);
1289        assert_eq!(RToVec::<i32>::len(&arr), 3);
1290    }
1291
1292    // Tests for RMakeIter
1293    struct TestCollection(Vec<i32>);
1294
1295    struct TestCollectionIter(RefCell<std::vec::IntoIter<i32>>);
1296
1297    impl RIterator for TestCollectionIter {
1298        type Item = i32;
1299
1300        fn next(&self) -> Option<i32> {
1301            self.0.borrow_mut().next()
1302        }
1303
1304        fn size_hint(&self) -> (i64, Option<i64>) {
1305            let (lo, hi) = self.0.borrow().size_hint();
1306            (lo as i64, hi.map(|h| h as i64))
1307        }
1308    }
1309
1310    impl RMakeIter<i32, TestCollectionIter> for TestCollection {
1311        fn make_iter(&self) -> TestCollectionIter {
1312            TestCollectionIter(RefCell::new(Clone::clone(&self.0).into_iter()))
1313        }
1314    }
1315
1316    #[test]
1317    fn test_rmakeiter_basic() {
1318        let coll = TestCollection(vec![1, 2, 3]);
1319        let iter = coll.make_iter();
1320
1321        assert_eq!(iter.next(), Some(1));
1322        assert_eq!(iter.next(), Some(2));
1323        assert_eq!(iter.next(), Some(3));
1324        assert_eq!(iter.next(), None);
1325    }
1326
1327    #[test]
1328    fn test_rmakeiter_independent() {
1329        let coll = TestCollection(vec![1, 2, 3]);
1330
1331        // Create two independent iterators
1332        let iter1 = coll.make_iter();
1333        let iter2 = coll.make_iter();
1334
1335        // Consuming one doesn't affect the other
1336        assert_eq!(iter1.next(), Some(1));
1337        assert_eq!(iter1.next(), Some(2));
1338
1339        assert_eq!(iter2.next(), Some(1)); // iter2 starts fresh
1340        assert_eq!(iter2.size_hint(), (2, Some(2))); // 2 remaining in iter2
1341    }
1342}