abi_stable/erased_types/dyn_trait.rs
1//! Contains the `DynTrait` type, and related traits/type aliases.
2
3use std::{
4 fmt::{self, Write as fmtWrite},
5 io,
6 mem::ManuallyDrop,
7 ptr,
8 rc::Rc,
9};
10
11use serde::{de, ser, Deserialize, Deserializer};
12
13use crate::{
14 abi_stability::StableAbi,
15 marker_type::{ErasedObject, NonOwningPhantom, UnsafeIgnoredType},
16 pointer_trait::{
17 AsMutPtr, AsPtr, CanTransmuteElement, GetPointerKind, OwnedPointer, PK_Reference,
18 PK_SmartPointer, PointerKind, TransmuteElement,
19 },
20 prefix_type::PrefixRef,
21 sabi_types::{MovePtr, RMut, RRef},
22 std_types::{RBox, RIoError, RStr, RVec},
23 type_level::{
24 downcasting::{TD_CanDowncast, TD_Opaque},
25 impl_enum::{Implemented, Unimplemented},
26 trait_marker,
27 },
28};
29
30#[allow(unused_imports)]
31use crate::std_types::Tuple2;
32
33use super::{
34 c_functions::adapt_std_fmt,
35 trait_objects::*,
36 traits::{DeserializeDyn, GetSerializeProxyType},
37 type_info::TypeInfoFor,
38 vtable::{MakeVTable, VTable_Ref},
39 IteratorItemOrDefault, *,
40};
41
42// #[cfg(test)]
43#[cfg(all(test, not(feature = "only_new_tests")))]
44mod tests;
45
46#[cfg(doctest)]
47pub mod doctests;
48
49mod priv_ {
50 use super::*;
51
52 /// DynTrait implements ffi-safe trait objects, for a selection of traits.
53 ///
54 /// # Passing opaque values around with `DynTrait<_>`
55 ///
56 /// One can pass non-StableAbi types around by using type erasure, using this type.
57 ///
58 /// It generally looks like `DynTrait<'borrow, Pointer<()>, Interface>`, where:
59 ///
60 /// - `'borrow` is the borrow that the type that was erased had.
61 ///
62 /// - `Pointer` is a pointer type that implements [`AsPtr`].
63 ///
64 /// - `Interface` is an [`InterfaceType`], which describes what traits are
65 /// required when constructing the `DynTrait<_>` and which ones it implements.
66 ///
67 /// ### Construction
68 ///
69 /// To construct a `DynTrait<_>` one can use these associated functions:
70 ///
71 /// - [`from_value`](#method.from_value):
72 /// Can be constructed from the value directly.Requires a `'static` value.
73 ///
74 /// - [`from_ptr`](#method.from_ptr)
75 /// Can be constructed from a pointer of a value.Requires a `'static` value.
76 ///
77 /// - [`from_borrowing_value`](#method.from_borrowing_value):
78 /// Can be constructed from the value directly.Cannot downcast the DynTrait afterwards.
79 ///
80 /// - [`from_borrowing_ptr`](#method.from_borrowing_ptr)
81 /// Can be constructed from a pointer of a value.Cannot downcast the DynTrait afterwards.
82 ///
83 /// DynTrait uses the impls of the value in methods,
84 /// which means that the pointer itself does not have to implement those traits,
85 ///
86 /// ### Trait object
87 ///
88 /// `DynTrait<'borrow, Pointer<()>, Interface>`
89 /// can be used as a trait object for any combination of
90 /// the traits listed below.
91 ///
92 /// These are the traits:
93 ///
94 /// - [`Send`]
95 ///
96 /// - [`Sync`]
97 ///
98 /// - [`Unpin`]
99 ///
100 /// - [`Iterator`]
101 ///
102 /// - [`DoubleEndedIterator`]
103 ///
104 /// - [`std::fmt::Write`]
105 ///
106 /// - [`std::io::Write`]
107 ///
108 /// - [`std::io::Seek`]
109 ///
110 /// - [`std::io::Read`]
111 ///
112 /// - [`std::io::BufRead`]
113 ///
114 /// - [`Clone`]
115 ///
116 /// - [`Display`]
117 ///
118 /// - [`Debug`]
119 ///
120 /// - [`std::error::Error`]
121 ///
122 /// - [`Default`]: Can only be called as an inherent method.
123 ///
124 /// - [`Eq`]
125 ///
126 /// - [`PartialEq`]
127 ///
128 /// - [`Ord`]
129 ///
130 /// - [`PartialOrd`]
131 ///
132 /// - [`Hash`]
133 ///
134 /// - [`serde::Deserialize`]:
135 /// first deserializes from a string, and then calls the objects' Deserialize impl.
136 ///
137 /// - [`serde::Serialize`]:
138 /// first calls the objects' Deserialize impl, then serializes that as a string.
139 ///
140 /// ### Deconstruction
141 ///
142 /// `DynTrait<_>` can then be unwrapped into a concrete type,
143 /// within the same dynamic library/executable that constructed it,
144 /// using these (fallible) conversion methods:
145 ///
146 /// - [`downcast_into`](#method.downcast_into):
147 /// Unwraps into a pointer to `T`.Requires `T:'static`.
148 ///
149 /// - [`downcast_as`](#method.downcast_as):
150 /// Unwraps into a `&T`.Requires `T:'static`.
151 ///
152 /// - [`downcast_as_mut`](#method.downcast_as_mut):
153 /// Unwraps into a `&mut T`.Requires `T:'static`.
154 ///
155 ///
156 /// `DynTrait` cannot be converted back if it was created
157 /// using `DynTrait::from_borrowing_*`.
158 ///
159 /// # Passing DynTrait between dynamic libraries
160 ///
161 /// Passing DynTrait between dynamic libraries
162 /// (as in between the dynamic libraries directly loaded by the same binary/dynamic library)
163 /// may cause the program to panic at runtime with an error message stating that
164 /// the trait is not implemented for the specific interface.
165 ///
166 /// This can only happen if you are passing DynTrait between dynamic libraries,
167 /// or if DynTrait was instantiated in the parent passed to a child,
168 /// a DynTrait instantiated in a child dynamic library passed to the parent
169 /// should not cause a panic, it would be a bug.
170 ///
171 /// ```text
172 /// binary
173 /// _________|___________
174 /// lib0 lib1 lib2
175 /// | | |
176 /// lib00 lib10 lib20
177 /// ```
178 ///
179 /// In this diagram passing a DynTrait constructed in lib00 to anything other than
180 /// the binary or lib0 will cause the panic to happen if:
181 ///
182 /// - The [`InterfaceType`] requires extra traits in the version of the Interface
183 /// that lib1 and lib2 know about (that the binary does not require).
184 ///
185 /// - lib1 or lib2 attempt to call methods that require the traits that were added
186 /// to the [`InterfaceType`], in versions of that interface that only they know about.
187 ///
188 /// # Examples
189 ///
190 /// ### In the Readme
191 ///
192 /// The primary example using `DynTrait<_>` is in the readme.
193 ///
194 /// Readme is in
195 /// [the repository for this crate](https://github.com/rodrimati1992/abi_stable_crates),
196 /// [crates.io](https://crates.io/crates/abi_stable),
197 /// [lib.rs](https://lib.rs/crates/abi_stable).
198 ///
199 /// ### Serialization/Deserialization
200 ///
201 /// The [`DeserializeDyn`] and [`SerializeType`] demonstrate how `DynTrait`
202 /// can be de/serialized.
203 ///
204 /// ### Comparing DynTraits
205 ///
206 /// This is only possible if the erased types don't contain borrows,
207 /// and they are not constructed using `DynTrait::from_borrowing_*` methods.
208 ///
209 /// DynTraits wrapping different pointer types can be compared with each other,
210 /// it simply uses the values' implementation of PartialEq.
211 ///
212 /// ```
213 /// use abi_stable::{
214 /// erased_types::interfaces::PartialEqInterface,
215 /// std_types::{RArc, RBox},
216 /// DynTrait, RMut, RRef,
217 /// };
218 ///
219 /// {
220 /// // `DynTrait`s constructed from `&` are `DynTrait<'_, RRef<'_, ()>, _>`
221 /// // since `&T` can't soundly be transmuted back and forth into `&()`
222 /// let left: DynTrait<'static, RRef<'_, ()>, PartialEqInterface> =
223 /// DynTrait::from_ptr(&100);
224 ///
225 /// let mut n100 = 100;
226 /// // `DynTrait`s constructed from `&mut` are `DynTrait<'_, RMut<'_, ()>, _>`
227 /// // since `&mut T` can't soundly be transmuted back and forth into `&mut ()`
228 /// let right: DynTrait<'static, RMut<'_, ()>, PartialEqInterface> =
229 /// DynTrait::from_ptr(&mut n100).interface(PartialEqInterface);
230 ///
231 /// assert_eq!(left, right);
232 /// }
233 /// {
234 /// let left: DynTrait<'static, RBox<()>, PartialEqInterface> =
235 /// DynTrait::from_value(200);
236 ///
237 /// let right: DynTrait<'static, RArc<()>, _> =
238 /// DynTrait::from_ptr(RArc::new(200)).interface(PartialEqInterface);
239 ///
240 /// assert_eq!(left, right);
241 /// }
242 ///
243 /// ```
244 ///
245 /// ### Writing to a DynTrait
246 ///
247 /// This is an example of using the `write!()` macro with DynTrait.
248 ///
249 /// ```
250 /// use abi_stable::{erased_types::interfaces::FmtWriteInterface, DynTrait, RMut};
251 ///
252 /// use std::fmt::Write;
253 ///
254 /// let mut buffer = String::new();
255 ///
256 /// let mut wrapped: DynTrait<'static, RMut<'_, ()>, FmtWriteInterface> =
257 /// DynTrait::from_ptr(&mut buffer);
258 ///
259 /// write!(wrapped, "Foo").unwrap();
260 /// write!(wrapped, "Bar").unwrap();
261 /// write!(wrapped, "Baz").unwrap();
262 ///
263 /// drop(wrapped);
264 ///
265 /// assert_eq!(&buffer[..], "FooBarBaz");
266 ///
267 ///
268 /// ```
269 ///
270 ///
271 /// ### Iteration
272 ///
273 /// Using `DynTrait` as an `Iterator` and `DoubleEndedIterator`.
274 ///
275 /// ```
276 /// use abi_stable::{erased_types::interfaces::DEIteratorInterface, DynTrait};
277 ///
278 /// let mut wrapped = DynTrait::from_value(0..=10).interface(DEIteratorInterface::NEW);
279 ///
280 /// assert_eq!(
281 /// wrapped.by_ref().take(5).collect::<Vec<_>>(),
282 /// vec![0, 1, 2, 3, 4]
283 /// );
284 ///
285 /// assert_eq!(wrapped.rev().collect::<Vec<_>>(), vec![10, 9, 8, 7, 6, 5]);
286 ///
287 /// ```
288 ///
289 ///
290 /// # Making pointers compatible with DynTrait
291 ///
292 /// To make pointers compatible with DynTrait, they must imlement the
293 /// `abi_stable::pointer_trait::{`
294 /// [`GetPointerKind`]`, `[`AsPtr`]`, `[`AsMutPtr`]`, `[`CanTransmuteElement`]`}`
295 /// traits as shown in the example.
296 ///
297 /// [`GetPointerKind`] should generally be implemented with
298 /// `type Kind = `[`PK_SmartPointer`].
299 /// The exception is in the case that it is a `#[repr(transparent)]`
300 /// wrapper around a [`RRef`]/[`RMut`]/`*const T`/`*mut T`/[`NonNull`],
301 /// in which case it should implement [`GetPointerKind`]`<Kind = `[`PK_Reference`]`>`
302 /// (when it has shared reference semantics)
303 /// or [`GetPointerKind`]`<Kind = `[`PK_MutReference`]`>`
304 /// (when it has mutable reference semantics).
305 ///
306 /// ### Example
307 ///
308 /// This is an example of a newtype wrapping an [`RBox`],
309 /// demonstrating that the pointer type doesn't have to implement
310 /// the traits in the [`InterfaceType`], it's the value it points to.
311 ///
312 /// ```rust
313 ///
314 /// use abi_stable::DynTrait;
315 ///
316 /// fn main() {
317 /// let lines = "line0\nline1\nline2";
318 /// let mut iter = NewtypeBox::new(lines.lines());
319 ///
320 /// // The type annotation here is just to show the type, it's not necessary.
321 /// let mut wrapper: DynTrait<'_, NewtypeBox<()>, IteratorInterface> =
322 /// DynTrait::from_borrowing_ptr(iter);
323 ///
324 /// // You can clone the DynTrait!
325 /// let clone = wrapper.clone();
326 ///
327 /// assert_eq!(wrapper.next(), Some("line0"));
328 /// assert_eq!(wrapper.next(), Some("line1"));
329 /// assert_eq!(wrapper.next(), Some("line2"));
330 /// assert_eq!(wrapper.next(), None);
331 ///
332 /// assert_eq!(
333 /// clone.rev().collect::<Vec<_>>(),
334 /// vec!["line2", "line1", "line0"],
335 /// )
336 /// }
337 ///
338 /// #[repr(C)]
339 /// #[derive(StableAbi)]
340 /// #[sabi(impl_InterfaceType(
341 /// Sync,
342 /// Send,
343 /// Iterator,
344 /// DoubleEndedIterator,
345 /// Clone,
346 /// Debug
347 /// ))]
348 /// pub struct IteratorInterface;
349 ///
350 /// impl<'a> IteratorItem<'a> for IteratorInterface {
351 /// type Item = &'a str;
352 /// }
353 ///
354 /// /////////////////////////////////////////
355 ///
356 /// use std::ops::{Deref, DerefMut};
357 ///
358 /// use abi_stable::{
359 /// erased_types::IteratorItem,
360 /// pointer_trait::{
361 /// AsMutPtr, AsPtr, CanTransmuteElement, GetPointerKind, PK_SmartPointer,
362 /// },
363 /// std_types::RBox,
364 /// type_level::bools::True,
365 /// InterfaceType, StableAbi,
366 /// };
367 ///
368 /// #[repr(transparent)]
369 /// #[derive(Default, Clone, StableAbi)]
370 /// pub struct NewtypeBox<T> {
371 /// box_: RBox<T>,
372 /// }
373 ///
374 /// impl<T> NewtypeBox<T> {
375 /// pub fn new(value: T) -> Self {
376 /// Self {
377 /// box_: RBox::new(value),
378 /// }
379 /// }
380 /// }
381 ///
382 /// unsafe impl<T> GetPointerKind for NewtypeBox<T> {
383 /// // This is a smart pointer because `RBox` is one.
384 /// type Kind = PK_SmartPointer;
385 /// type PtrTarget = T;
386 /// }
387 ///
388 /// // safety: Does not create an intermediate `&T` to get a pointer to `T`.
389 /// unsafe impl<T> AsPtr for NewtypeBox<T> {
390 /// fn as_ptr(&self) -> *const T {
391 /// self.box_.as_ptr()
392 /// }
393 /// }
394 ///
395 /// // safety: Does not create an intermediate `&mut T` to get a pointer to `T`
396 /// unsafe impl<T> AsMutPtr for NewtypeBox<T> {
397 /// fn as_mut_ptr(&mut self) -> *mut T {
398 /// self.box_.as_mut_ptr()
399 /// }
400 /// }
401 ///
402 /// // safety:
403 /// // NewtypeBox is safe to transmute, because RBox (the pointer type it wraps)
404 /// // is safe to transmute
405 /// unsafe impl<T, O> CanTransmuteElement<O> for NewtypeBox<T> {
406 /// type TransmutedPtr = NewtypeBox<O>;
407 ///
408 /// unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
409 /// let box_: RBox<O> = self.box_.transmute_element_();
410 /// NewtypeBox { box_ }
411 /// }
412 /// }
413 ///
414 /// ```
415 ///
416 /// [`AsPtr`]: crate::pointer_trait::AsPtr
417 /// [`InterfaceType`]: crate::InterfaceType
418 /// [`NonNull`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html
419 /// [`SerializeProxyType`]: crate::erased_types::SerializeProxyType
420 /// [`DeserializeDyn`]: crate::erased_types::DeserializeDyn
421 /// [`AsMutPtr`]: crate::pointer_trait::AsMutPtr
422 /// [`CanTransmuteElement`]: crate::pointer_trait::CanTransmuteElement
423 /// [`GetPointerKind`]: crate::pointer_trait::GetPointerKind
424 /// [`RRef`]: crate::sabi_types::RRef
425 /// [`RMut`]: crate::sabi_types::RMut
426 /// [`RBox`]: crate::std_types::RBox
427 /// [`PK_Reference`]: crate::pointer_trait::PK_Reference
428 /// [`PK_MutReference`]: crate::pointer_trait::PK_MutReference
429 /// [`PK_SmartPointer`]: crate::pointer_trait::PK_SmartPointer
430 /// [`SerializeType`]: crate::erased_types::SerializeType
431 ///
432 #[repr(C)]
433 #[derive(StableAbi)]
434 #[sabi(
435 // debug_print,
436 bound(I: InterfaceType),
437 bound(VTable_Ref<'borr, P, I>: StableAbi),
438 extra_checks = <I as MakeRequiredTraits>::MAKE,
439 )]
440 pub struct DynTrait<'borr, P, I, EV = ()>
441 where
442 P: GetPointerKind,
443 {
444 pub(super) object: ManuallyDrop<P>,
445 vtable: VTable_Ref<'borr, P, I>,
446 extra_value: EV,
447 _marker: NonOwningPhantom<(I, RStr<'borr>)>,
448 _marker2: UnsafeIgnoredType<Rc<()>>,
449 }
450
451 impl<I> DynTrait<'static, RBox<()>, I> {
452 /// Constructs the `DynTrait<_>` from a type that doesn't borrow anything.
453 ///
454 /// # Example
455 ///
456 /// ```rust
457 /// use abi_stable::{
458 /// erased_types::interfaces::DebugDisplayInterface, std_types::RBox, DynTrait,
459 /// };
460 ///
461 /// // DebugDisplayInterface is `Debug + Display + Sync + Send`
462 /// let to: DynTrait<'static, RBox<()>, DebugDisplayInterface> =
463 /// DynTrait::from_value(3u8);
464 ///
465 /// assert_eq!(format!("{}", to), "3");
466 /// assert_eq!(format!("{:?}", to), "3");
467 ///
468 /// ```
469 pub fn from_value<T>(object: T) -> Self
470 where
471 T: 'static,
472 VTable_Ref<'static, RBox<()>, I>: MakeVTable<'static, T, RBox<T>, TD_CanDowncast>,
473 {
474 let object = RBox::new(object);
475 DynTrait::from_ptr(object)
476 }
477 }
478
479 impl<P, I> DynTrait<'static, P, I>
480 where
481 P: GetPointerKind,
482 {
483 /// Constructs the `DynTrait<_>` from a pointer to a
484 /// type that doesn't borrow anything.
485 ///
486 /// # Example
487 ///
488 /// ```rust
489 /// use abi_stable::{
490 /// erased_types::interfaces::DebugDisplayInterface,
491 /// std_types::{RArc, RBox},
492 /// DynTrait, RMut, RRef,
493 /// };
494 ///
495 /// // Constructing a DynTrait from a `&T`
496 /// {
497 /// // `DynTrait`s constructed from `&` are `DynTrait<'_, RRef<'_, ()>, _>`
498 /// // since `&T` can't soundly be transmuted back and forth into `&()`
499 /// let rref: DynTrait<'static, RRef<'_, ()>, DebugDisplayInterface> =
500 /// DynTrait::from_ptr(&21i32);
501 ///
502 /// assert_eq!(format!("{:?}", rref), "21");
503 /// assert_eq!(format!("{}", rref), "21");
504 /// }
505 /// // Constructing a DynTrait from a `&mut T`
506 /// {
507 /// let mmut = &mut "hello";
508 /// // `DynTrait`s constructed from `&mut` are `DynTrait<'_, RMut<'_, ()>, _>`
509 /// // since `&mut T` can't soundly be transmuted back and forth into `&mut ()`
510 /// let rmut: DynTrait<'static, RMut<'_, ()>, DebugDisplayInterface> =
511 /// DynTrait::from_ptr(mmut).interface(DebugDisplayInterface);
512 ///
513 /// assert_eq!(format!("{:?}", rmut), r#""hello""#);
514 /// assert_eq!(format!("{}", rmut), "hello");
515 /// }
516 /// // Constructing a DynTrait from a `RBox<T>`
517 /// {
518 /// let boxed: DynTrait<'static, RBox<()>, DebugDisplayInterface> =
519 /// DynTrait::from_ptr(RBox::new(false));
520 ///
521 /// assert_eq!(format!("{:?}", boxed), "false");
522 /// assert_eq!(format!("{}", boxed), "false");
523 /// }
524 /// // Constructing a DynTrait from an `RArc<T>`
525 /// {
526 /// let arc: DynTrait<'static, RArc<()>, DebugDisplayInterface> =
527 /// DynTrait::from_ptr(RArc::new(30u32)).interface(DebugDisplayInterface);
528 ///
529 /// assert_eq!(format!("{:?}", arc), "30");
530 /// }
531 ///
532 /// ```
533 pub fn from_ptr<OrigPtr>(object: OrigPtr) -> Self
534 where
535 OrigPtr: GetPointerKind,
536 OrigPtr::PtrTarget: 'static,
537 OrigPtr: CanTransmuteElement<(), TransmutedPtr = P>,
538 VTable_Ref<'static, P, I>:
539 MakeVTable<'static, OrigPtr::PtrTarget, OrigPtr, TD_CanDowncast>,
540 {
541 DynTrait {
542 object: unsafe { ManuallyDrop::new(object.transmute_element::<()>()) },
543 vtable: VTable_Ref::VTABLE_REF,
544 extra_value: (),
545 _marker: NonOwningPhantom::NEW,
546 _marker2: UnsafeIgnoredType::DEFAULT,
547 }
548 }
549 }
550
551 impl<'borr, I> DynTrait<'borr, RBox<()>, I> {
552 /// Constructs the `DynTrait<_>` from a value with a `'borr` borrow.
553 ///
554 /// Cannot downcast the DynTrait afterwards.
555 ///
556 /// # Example
557 ///
558 /// ```rust
559 /// use abi_stable::{
560 /// erased_types::interfaces::DebugDisplayInterface, std_types::RBox, DynTrait,
561 /// };
562 ///
563 /// // DebugDisplayInterface is `Debug + Display + Sync + Send`
564 /// let to: DynTrait<'static, RBox<()>, DebugDisplayInterface> =
565 /// DynTrait::from_borrowing_value(3u8);
566 ///
567 /// assert_eq!(format!("{}", to), "3");
568 /// assert_eq!(format!("{:?}", to), "3");
569 ///
570 /// // `DynTrait`s constructed using the `from_borrowing_*` constructors
571 /// // can't be downcasted.
572 /// assert_eq!(to.downcast_as::<u8>().ok(), None);
573 ///
574 /// ```
575 pub fn from_borrowing_value<T>(object: T) -> Self
576 where
577 T: 'borr,
578 VTable_Ref<'borr, RBox<()>, I>: MakeVTable<'borr, T, RBox<T>, TD_Opaque>,
579 {
580 let object = RBox::new(object);
581 DynTrait::from_borrowing_ptr(object)
582 }
583 }
584
585 impl<'borr, P, I> DynTrait<'borr, P, I>
586 where
587 P: GetPointerKind,
588 {
589 /// Constructs the `DynTrait<_>` from a pointer to the erased type
590 /// with a `'borr` borrow.
591 ///
592 /// Cannot downcast the DynTrait afterwards.
593 ///
594 /// # Example
595 ///
596 /// ```rust
597 /// use abi_stable::{
598 /// erased_types::interfaces::DebugDisplayInterface,
599 /// std_types::{RArc, RBox},
600 /// DynTrait, RMut, RRef,
601 /// };
602 ///
603 /// // Constructing a DynTrait from a `&T`
604 /// {
605 /// // `DynTrait`s constructed from `&` are `DynTrait<'_, RRef<'_, ()>, _>`
606 /// // since `&T` can't soundly be transmuted back and forth into `&()`
607 /// let rref: DynTrait<'_, RRef<'_, ()>, DebugDisplayInterface> =
608 /// DynTrait::from_borrowing_ptr(&34i32);
609 ///
610 /// assert_eq!(format!("{:?}", rref), "34");
611 /// assert_eq!(format!("{}", rref), "34");
612 /// }
613 /// // Constructing a DynTrait from a `&mut T`
614 /// {
615 /// let mmut = &mut "world";
616 /// // `DynTrait`s constructed from `&mut` are `DynTrait<'_, RMut<'_, ()>, _>`
617 /// // since `&mut T` can't soundly be transmuted back and forth into `&mut ()`
618 /// let rmut: DynTrait<'_, RMut<'_, ()>, DebugDisplayInterface> =
619 /// DynTrait::from_borrowing_ptr(mmut).interface(DebugDisplayInterface);
620 ///
621 /// assert_eq!(format!("{:?}", rmut), r#""world""#);
622 /// assert_eq!(format!("{}", rmut), "world");
623 /// }
624 /// // Constructing a DynTrait from a `RBox<T>`
625 /// {
626 /// let boxed: DynTrait<'_, RBox<()>, DebugDisplayInterface> =
627 /// DynTrait::from_borrowing_ptr(RBox::new(true));
628 ///
629 /// assert_eq!(format!("{:?}", boxed), "true");
630 /// assert_eq!(format!("{}", boxed), "true");
631 /// }
632 /// // Constructing a DynTrait from an `RArc<T>`
633 /// {
634 /// let arc: DynTrait<'_, RArc<()>, _> =
635 /// DynTrait::from_borrowing_ptr(RArc::new('a')).interface(DebugDisplayInterface);
636 ///
637 /// assert_eq!(format!("{:?}", arc), "'a'");
638 /// assert_eq!(format!("{}", arc), "a");
639 /// }
640 ///
641 /// ```
642 pub fn from_borrowing_ptr<OrigPtr>(object: OrigPtr) -> Self
643 where
644 OrigPtr: GetPointerKind + 'borr,
645 OrigPtr::PtrTarget: 'borr,
646 OrigPtr: CanTransmuteElement<(), TransmutedPtr = P>,
647 VTable_Ref<'borr, P, I>: MakeVTable<'borr, OrigPtr::PtrTarget, OrigPtr, TD_Opaque>,
648 {
649 DynTrait {
650 object: unsafe { ManuallyDrop::new(object.transmute_element::<()>()) },
651 vtable: VTable_Ref::VTABLE_REF,
652 extra_value: (),
653 _marker: NonOwningPhantom::NEW,
654 _marker2: UnsafeIgnoredType::DEFAULT,
655 }
656 }
657 }
658
659 impl<'borr, P, I, EV> DynTrait<'borr, P, I, EV>
660 where
661 P: AsPtr<PtrTarget = ()>,
662 {
663 /// Constructs an DynTrait from an erasable pointer and an extra value.
664 ///
665 /// # Example
666 ///
667 /// ```rust
668 /// use abi_stable::{
669 /// erased_types::{interfaces::DebugDisplayInterface, TD_Opaque},
670 /// DynTrait, RRef,
671 /// };
672 ///
673 /// // DebugDisplayInterface is `Debug + Display + Sync + Send`
674 /// let to: DynTrait<'static, RRef<()>, DebugDisplayInterface, usize> =
675 /// DynTrait::with_extra_value::<_, TD_Opaque>(&55u8, 100usize);
676 ///
677 /// assert_eq!(format!("{}", to), "55");
678 /// assert_eq!(format!("{:?}", to), "55");
679 ///
680 /// assert_eq!(to.sabi_extra_value(), &100);
681 ///
682 /// ```
683 pub fn with_extra_value<OrigPtr, Downcasting>(
684 ptr: OrigPtr,
685 extra_value: EV,
686 ) -> DynTrait<'borr, P, I, EV>
687 where
688 OrigPtr: GetPointerKind,
689 OrigPtr::PtrTarget: 'borr,
690 OrigPtr: CanTransmuteElement<(), TransmutedPtr = P>,
691 VTable_Ref<'borr, P, I>: MakeVTable<'borr, OrigPtr::PtrTarget, OrigPtr, Downcasting>,
692 {
693 DynTrait {
694 object: unsafe { ManuallyDrop::new(ptr.transmute_element::<()>()) },
695 vtable: VTable_Ref::VTABLE_REF,
696 extra_value,
697 _marker: NonOwningPhantom::NEW,
698 _marker2: UnsafeIgnoredType::DEFAULT,
699 }
700 }
701
702 #[doc(hidden)]
703 pub fn with_vtable<OrigPtr, Downcasting>(
704 ptr: OrigPtr,
705 extra_vtable: EV,
706 ) -> DynTrait<'borr, P, I, EV>
707 where
708 OrigPtr: GetPointerKind,
709 OrigPtr::PtrTarget: 'borr,
710 I: InterfaceType,
711 OrigPtr: CanTransmuteElement<(), TransmutedPtr = P>,
712 VTable_Ref<'borr, P, I>: MakeVTable<'borr, OrigPtr::PtrTarget, OrigPtr, Downcasting>,
713 {
714 Self::with_extra_value(ptr, extra_vtable)
715 }
716 }
717
718 impl<'borr, 'a, I, EV> DynTrait<'borr, RRef<'a, ()>, I, EV> {
719 /// This function allows constructing a DynTrait in a constant/static.
720 ///
721 /// # Parameters
722 ///
723 /// `ptr`: a reference to the value.
724 ///
725 /// <br>
726 ///
727 /// `can_it_downcast` can be either:
728 ///
729 /// - [`TD_CanDowncast`]:
730 /// Which allows the trait object to be downcasted, requires that the value implements any.
731 ///
732 /// - [`TD_Opaque`]:
733 /// Which does not allow the trait object to be downcasted.
734 ///
735 /// <br>
736 ///
737 /// `extra_value`:
738 /// This is used by [`#[sabi_trait]`](macro@crate::sabi_trait)
739 /// trait objects to store their vtable inside DynTrait.
740 ///
741 ///
742 /// # Example
743 ///
744 /// ```
745 /// use abi_stable::{
746 /// erased_types::{
747 /// interfaces::DebugDisplayInterface, DynTrait, TD_Opaque,
748 /// },
749 /// sabi_types::RRef,
750 /// };
751 ///
752 /// static STRING: &str = "What the heck";
753 ///
754 /// static DYN: DynTrait<'static, RRef<'static, ()>, DebugDisplayInterface, ()> =
755 /// DynTrait::from_const(&STRING, TD_Opaque, ());
756 ///
757 /// fn main() {
758 /// assert_eq!(format!("{}", DYN), format!("{}", STRING));
759 /// assert_eq!(format!("{:?}", DYN), format!("{:?}", STRING));
760 /// }
761 ///
762 /// ```
763 ///
764 /// [`TD_CanDowncast`]: ./type_level/downcasting/struct.TD_CanDowncast.html
765 /// [`TD_Opaque`]: ./type_level/downcasting/struct.TD_Opaque.html
766 pub const fn from_const<T, Downcasting>(
767 ptr: &'a T,
768 can_it_downcast: Downcasting,
769 extra_value: EV,
770 ) -> Self
771 where
772 VTable_Ref<'borr, RRef<'a, ()>, I>: MakeVTable<'borr, T, &'a T, Downcasting>,
773 T: 'borr,
774 {
775 // Must wrap can_it_downcast in a ManuallyDrop because otherwise this
776 // errors with `constant functions cannot evaluate destructors`.
777 let _ = ManuallyDrop::new(can_it_downcast);
778 DynTrait {
779 object: unsafe {
780 let x = RRef::from_raw(ptr as *const T as *const ());
781 ManuallyDrop::new(x)
782 },
783 vtable: VTable_Ref::VTABLE_REF,
784 extra_value,
785 _marker: NonOwningPhantom::NEW,
786 _marker2: UnsafeIgnoredType::DEFAULT,
787 }
788 }
789 }
790
791 impl<'borr, P, I, EV> DynTrait<'borr, P, I, EV>
792 where
793 P: GetPointerKind,
794 {
795 /// For inferring the `I` type parameter.
796 pub const fn interface(self, _interface: I) -> Self
797 where
798 I: InterfaceType,
799 {
800 std::mem::forget(_interface);
801 self
802 }
803 }
804
805 impl<P, I, EV> DynTrait<'static, P, I, EV>
806 where
807 P: GetPointerKind,
808 {
809 /// Allows checking whether 2 `DynTrait<_>`s have a value of the same type.
810 ///
811 /// Notes:
812 ///
813 /// - Types from different dynamic libraries/executables are
814 /// never considered equal.
815 ///
816 /// - `DynTrait`s constructed using `DynTrait::from_borrowing_*`
817 /// are never considered to wrap the same type.
818 pub fn sabi_is_same_type<Other, I2, EV2>(
819 &self,
820 other: &DynTrait<'static, Other, I2, EV2>,
821 ) -> bool
822 where
823 I2: InterfaceType,
824 Other: GetPointerKind,
825 {
826 self.sabi_vtable_address() == other.sabi_vtable_address()
827 || self
828 .sabi_vtable()
829 .type_info()
830 .is_compatible(other.sabi_vtable().type_info())
831 }
832 }
833
834 impl<'borr, P, I, EV> DynTrait<'borr, P, I, PrefixRef<EV>>
835 where
836 P: GetPointerKind,
837 {
838 /// A vtable used by `#[sabi_trait]` derived trait objects.
839 #[inline]
840 pub const fn sabi_et_vtable(&self) -> PrefixRef<EV> {
841 self.extra_value
842 }
843 }
844
845 impl<'borr, P, I, EV> DynTrait<'borr, P, I, EV>
846 where
847 P: GetPointerKind,
848 {
849 /// Gets access to the extra value that was stored in this DynTrait in the
850 /// `with_extra_value` constructor.
851 ///
852 /// # Example
853 ///
854 /// ```rust
855 /// use abi_stable::{erased_types::TD_Opaque, DynTrait, RRef};
856 ///
857 /// let to: DynTrait<'static, RRef<()>, (), char> =
858 /// DynTrait::with_extra_value::<_, TD_Opaque>(&55u8, 'Z');
859 ///
860 /// assert_eq!(to.sabi_extra_value(), &'Z');
861 ///
862 /// ```
863 #[inline]
864 pub const fn sabi_extra_value(&self) -> &EV {
865 &self.extra_value
866 }
867
868 #[inline]
869 pub(super) const fn sabi_vtable(&self) -> VTable_Ref<'borr, P, I> {
870 self.vtable
871 }
872
873 #[inline]
874 pub(super) fn sabi_vtable_address(&self) -> usize {
875 self.vtable.0.to_raw_ptr() as usize
876 }
877
878 /// Returns the address of the wrapped object.
879 ///
880 /// # Example
881 ///
882 /// ```rust
883 /// use abi_stable::{erased_types::TD_Opaque, DynTrait, RRef};
884 ///
885 /// let reff = &55u8;
886 ///
887 /// let to: DynTrait<'static, RRef<()>, ()> = DynTrait::from_ptr(reff);
888 ///
889 /// assert_eq!(to.sabi_object_address(), reff as *const _ as usize);
890 ///
891 /// ```
892 pub fn sabi_object_address(&self) -> usize
893 where
894 P: AsPtr,
895 {
896 self.object.as_ptr() as *const () as usize
897 }
898
899 // Safety: Only call this in unerasure functions
900 unsafe fn sabi_object_as<T>(&self) -> &T
901 where
902 P: AsPtr,
903 {
904 unsafe { &*(self.object.as_ptr() as *const P::PtrTarget as *const T) }
905 }
906
907 // Safety: Only call this in unerasure functions
908 unsafe fn sabi_object_as_mut<T>(&mut self) -> &mut T
909 where
910 P: AsMutPtr,
911 {
912 unsafe { &mut *(self.object.as_mut_ptr() as *mut P::PtrTarget as *mut T) }
913 }
914
915 /// Gets a reference pointing to the erased object.
916 ///
917 /// # Example
918 ///
919 /// ```rust
920 /// use abi_stable::{std_types::RBox, DynTrait};
921 ///
922 /// let to: DynTrait<'static, RBox<()>, ()> = DynTrait::from_value(66u8);
923 ///
924 /// unsafe {
925 /// assert_eq!(to.sabi_erased_ref().transmute_into_ref::<u8>(), &66);
926 /// }
927 /// ```
928 pub fn sabi_erased_ref(&self) -> RRef<'_, ErasedObject>
929 where
930 P: AsPtr,
931 {
932 unsafe { RRef::from_raw(self.object.as_ptr() as *const ErasedObject) }
933 }
934
935 pub(super) unsafe fn sabi_erased_ref_unbounded_lifetime<'a>(&self) -> RRef<'a, ErasedObject>
936 where
937 P: AsPtr,
938 {
939 unsafe { RRef::from_raw(self.object.as_ptr() as *const ErasedObject) }
940 }
941
942 /// Gets a mutable reference pointing to the erased object.
943 ///
944 /// # Example
945 ///
946 /// ```rust
947 /// use abi_stable::{std_types::RBox, DynTrait};
948 ///
949 /// let mut to: DynTrait<'static, RBox<()>, ()> = DynTrait::from_value("hello");
950 ///
951 /// unsafe {
952 /// assert_eq!(
953 /// to.sabi_erased_mut().transmute_into_mut::<&str>(),
954 /// &mut "hello"
955 /// );
956 /// }
957 /// ```
958 #[inline]
959 pub fn sabi_erased_mut(&mut self) -> RMut<'_, ErasedObject>
960 where
961 P: AsMutPtr,
962 {
963 unsafe { RMut::from_raw(self.object.as_mut_ptr() as *mut ErasedObject) }
964 }
965
966 /// Gets an `RRef` pointing to the erased object.
967 ///
968 /// # Example
969 ///
970 /// ```rust
971 /// use abi_stable::{std_types::RBox, DynTrait};
972 ///
973 /// let to: DynTrait<'static, RBox<()>, ()> = DynTrait::from_value(66u8);
974 ///
975 /// unsafe {
976 /// assert_eq!(to.sabi_as_rref().transmute_into_ref::<u8>(), &66);
977 /// }
978 /// ```
979 pub fn sabi_as_rref(&self) -> RRef<'_, ()>
980 where
981 P: AsPtr,
982 {
983 unsafe { RRef::from_raw(self.object.as_ptr() as *const ()) }
984 }
985
986 /// Gets an `RMut` pointing to the erased object.
987 ///
988 /// # Example
989 ///
990 /// ```rust
991 /// use abi_stable::{std_types::RBox, DynTrait};
992 ///
993 /// let mut to: DynTrait<'static, RBox<()>, ()> = DynTrait::from_value("hello");
994 ///
995 /// unsafe {
996 /// assert_eq!(to.sabi_as_rmut().transmute_into_mut::<&str>(), &mut "hello");
997 /// }
998 /// ```
999 pub fn sabi_as_rmut(&mut self) -> RMut<'_, ()>
1000 where
1001 P: AsMutPtr,
1002 {
1003 unsafe { RMut::from_raw(self.object.as_mut_ptr() as *mut ()) }
1004 }
1005
1006 #[inline]
1007 fn sabi_into_erased_ptr(self) -> ManuallyDrop<P> {
1008 let this = ManuallyDrop::new(self);
1009 unsafe { ptr::read(&this.object) }
1010 }
1011
1012 /// Calls the `f` callback with an `MovePtr` pointing to the erased object.
1013 ///
1014 /// # Example
1015 ///
1016 /// ```rust
1017 /// use abi_stable::{
1018 /// sabi_types::MovePtr,
1019 /// std_types::{RBox, RString, RVec},
1020 /// DynTrait,
1021 /// };
1022 ///
1023 /// let to: DynTrait<'static, RBox<()>, ()> =
1024 /// DynTrait::from_value(RString::from("foobarbaz"));
1025 ///
1026 /// let string = to.sabi_with_value(|x| {
1027 /// // SAFETY: the erased object is an RString constructed in the current binary.
1028 /// unsafe {
1029 /// MovePtr::into_inner(MovePtr::transmute::<RString>(x))
1030 /// }
1031 /// });
1032 ///
1033 /// assert_eq!(string, "foobarbaz");
1034 /// ```
1035 #[inline]
1036 pub fn sabi_with_value<F, R>(self, f: F) -> R
1037 where
1038 P: OwnedPointer<PtrTarget = ()>,
1039 F: FnOnce(MovePtr<'_, ()>) -> R,
1040 {
1041 OwnedPointer::with_move_ptr(self.sabi_into_erased_ptr(), f)
1042 }
1043 }
1044
1045 impl<'borr, P, I, EV> DynTrait<'borr, P, I, EV>
1046 where
1047 P: GetPointerKind,
1048 {
1049 /// The uid in the vtable has to be the same as the one for T,
1050 /// otherwise it was not created from that T in the library that declared the opaque type.
1051 pub(super) fn sabi_check_same_destructor<T>(&self) -> Result<(), UneraseError<()>>
1052 where
1053 T: 'static,
1054 {
1055 let t_info = &TypeInfoFor::<T, (), TD_CanDowncast>::INFO;
1056 if self.sabi_vtable().type_info().is_compatible(t_info) {
1057 Ok(())
1058 } else {
1059 Err(UneraseError {
1060 dyn_trait: (),
1061 expected_type_info: t_info,
1062 found_type_info: self.sabi_vtable().type_info(),
1063 })
1064 }
1065 }
1066
1067 /// Unwraps the `DynTrait<_>` into a pointer of
1068 /// the concrete type that it was constructed with.
1069 ///
1070 /// `T` is required to not borrow anything.
1071 ///
1072 /// # Errors
1073 ///
1074 /// This will return an error in any of these conditions:
1075 ///
1076 /// - It is called in a dynamic library/binary outside
1077 /// the one from which this `DynTrait<_>` was constructed.
1078 ///
1079 /// - The DynTrait was constructed using a `from_borrowing_*` method
1080 ///
1081 /// - `T` is not the concrete type this `DynTrait<_>` was constructed with.
1082 ///
1083 ///
1084 /// # Example
1085 ///
1086 /// ```rust
1087 /// use abi_stable::{
1088 /// std_types::{RArc, RBox},
1089 /// DynTrait,
1090 /// };
1091 ///
1092 /// {
1093 /// fn to() -> DynTrait<'static, RBox<()>, ()> {
1094 /// DynTrait::from_value(b'A')
1095 /// }
1096 ///
1097 /// assert_eq!(to().downcast_into::<u8>().ok(), Some(RBox::new(b'A')));
1098 /// assert_eq!(to().downcast_into::<u16>().ok(), None);
1099 /// }
1100 /// {
1101 /// fn to() -> DynTrait<'static, RArc<()>, ()> {
1102 /// DynTrait::from_ptr(RArc::new(b'B'))
1103 /// }
1104 ///
1105 /// assert_eq!(to().downcast_into::<u8>().ok(), Some(RArc::new(b'B')));
1106 /// assert_eq!(to().downcast_into::<u16>().ok(), None);
1107 /// }
1108 ///
1109 /// ```
1110 pub fn downcast_into<T>(self) -> Result<P::TransmutedPtr, UneraseError<Self>>
1111 where
1112 T: 'static,
1113 P: CanTransmuteElement<T>,
1114 {
1115 check_unerased!(self, self.sabi_check_same_destructor::<T>());
1116 unsafe {
1117 let this = ManuallyDrop::new(self);
1118 Ok(ptr::read(&*this.object).transmute_element::<T>())
1119 }
1120 }
1121
1122 /// Unwraps the `DynTrait<_>` into a reference of
1123 /// the concrete type that it was constructed with.
1124 ///
1125 /// `T` is required to not borrow anything.
1126 ///
1127 /// # Errors
1128 ///
1129 /// This will return an error in any of these conditions:
1130 ///
1131 /// - It is called in a dynamic library/binary outside
1132 /// the one from which this `DynTrait<_>` was constructed.
1133 ///
1134 /// - The DynTrait was constructed using a `from_borrowing_*` method
1135 ///
1136 /// - `T` is not the concrete type this `DynTrait<_>` was constructed with.
1137 ///
1138 ///
1139 /// # Example
1140 ///
1141 /// ```rust
1142 /// use abi_stable::{std_types::RArc, DynTrait, RMut, RRef};
1143 ///
1144 /// {
1145 /// let to: DynTrait<'static, RRef<'_, ()>, ()> = DynTrait::from_ptr(&9u8);
1146 ///
1147 /// assert_eq!(to.downcast_as::<u8>().ok(), Some(&9u8));
1148 /// assert_eq!(to.downcast_as::<u16>().ok(), None);
1149 /// }
1150 /// {
1151 /// let mut val = 7u8;
1152 ///
1153 /// let to: DynTrait<'static, RMut<'_, ()>, ()> =
1154 /// DynTrait::from_ptr(&mut val);
1155 ///
1156 /// assert_eq!(to.downcast_as::<u8>().ok(), Some(&7));
1157 /// assert_eq!(to.downcast_as::<u16>().ok(), None);
1158 /// }
1159 /// {
1160 /// let to: DynTrait<'static, RArc<()>, ()> =
1161 /// DynTrait::from_ptr(RArc::new(1u8));
1162 ///
1163 /// assert_eq!(to.downcast_as::<u8>().ok(), Some(&1u8));
1164 /// assert_eq!(to.downcast_as::<u16>().ok(), None);
1165 /// }
1166 ///
1167 /// ```
1168 pub fn downcast_as<T>(&self) -> Result<&T, UneraseError<&Self>>
1169 where
1170 T: 'static,
1171 P: AsPtr,
1172 {
1173 check_unerased!(self, self.sabi_check_same_destructor::<T>());
1174 unsafe { Ok(self.sabi_object_as()) }
1175 }
1176
1177 /// Unwraps the `DynTrait<_>` into a mutable reference of
1178 /// the concrete type that it was constructed with.
1179 ///
1180 /// `T` is required to not borrow anything.
1181 ///
1182 /// # Errors
1183 ///
1184 /// This will return an error in any of these conditions:
1185 ///
1186 /// - It is called in a dynamic library/binary outside
1187 /// the one from which this `DynTrait<_>` was constructed.
1188 ///
1189 /// - The DynTrait was constructed using a `from_borrowing_*` method
1190 ///
1191 /// - `T` is not the concrete type this `DynTrait<_>` was constructed with.
1192 ///
1193 /// # Example
1194 ///
1195 /// ```rust
1196 /// use abi_stable::{std_types::RBox, DynTrait, RMut};
1197 ///
1198 /// {
1199 /// let mut val = 7u8;
1200 ///
1201 /// let mut to: DynTrait<'static, RMut<'_, ()>, ()> =
1202 /// DynTrait::from_ptr(&mut val);
1203 ///
1204 /// assert_eq!(to.downcast_as_mut::<u8>().ok(), Some(&mut 7));
1205 /// assert_eq!(to.downcast_as_mut::<u16>().ok(), None);
1206 /// }
1207 /// {
1208 /// let mut to: DynTrait<'static, RBox<()>, ()> =
1209 /// DynTrait::from_ptr(RBox::new(1u8));
1210 ///
1211 /// assert_eq!(to.downcast_as_mut::<u8>().ok(), Some(&mut 1u8));
1212 /// assert_eq!(to.downcast_as_mut::<u16>().ok(), None);
1213 /// }
1214 ///
1215 /// ```
1216 pub fn downcast_as_mut<T>(&mut self) -> Result<&mut T, UneraseError<&mut Self>>
1217 where
1218 T: 'static,
1219 P: AsMutPtr,
1220 {
1221 check_unerased!(self, self.sabi_check_same_destructor::<T>());
1222 unsafe { Ok(self.sabi_object_as_mut()) }
1223 }
1224
1225 /// Unwraps the `DynTrait<_>` into a pointer to T,
1226 /// without checking whether `T` is the type that the DynTrait was constructed with.
1227 ///
1228 /// # Safety
1229 ///
1230 /// You must check that `T` is the type that DynTrait was constructed
1231 /// with through other means.
1232 ///
1233 /// # Example
1234 ///
1235 /// ```rust
1236 /// use abi_stable::{
1237 /// std_types::{RArc, RBox},
1238 /// DynTrait,
1239 /// };
1240 ///
1241 /// unsafe {
1242 /// fn to() -> DynTrait<'static, RBox<()>, ()> {
1243 /// DynTrait::from_value(b'A')
1244 /// }
1245 ///
1246 /// assert_eq!(to().unchecked_downcast_into::<u8>(), RBox::new(b'A'));
1247 /// }
1248 /// unsafe {
1249 /// fn to() -> DynTrait<'static, RArc<()>, ()> {
1250 /// DynTrait::from_ptr(RArc::new(b'B'))
1251 /// }
1252 ///
1253 /// assert_eq!(to().unchecked_downcast_into::<u8>(), RArc::new(b'B'));
1254 /// }
1255 ///
1256 /// ```
1257 #[inline]
1258 pub unsafe fn unchecked_downcast_into<T>(self) -> P::TransmutedPtr
1259 where
1260 P: AsPtr + CanTransmuteElement<T>,
1261 {
1262 let this = ManuallyDrop::new(self);
1263 unsafe { ptr::read(&*this.object).transmute_element::<T>() }
1264 }
1265
1266 /// Unwraps the `DynTrait<_>` into a reference to T,
1267 /// without checking whether `T` is the type that the DynTrait was constructed with.
1268 ///
1269 /// # Safety
1270 ///
1271 /// You must check that `T` is the type that DynTrait was constructed
1272 /// with through other means.
1273 ///
1274 /// # Example
1275 ///
1276 /// ```rust
1277 /// use abi_stable::{std_types::RArc, DynTrait, RMut, RRef};
1278 ///
1279 /// unsafe {
1280 /// let to: DynTrait<'static, RRef<'_, ()>, ()> = DynTrait::from_ptr(&9u8);
1281 ///
1282 /// assert_eq!(to.unchecked_downcast_as::<u8>(), &9u8);
1283 /// }
1284 /// unsafe {
1285 /// let mut val = 7u8;
1286 ///
1287 /// let to: DynTrait<'static, RMut<'_, ()>, ()> =
1288 /// DynTrait::from_ptr(&mut val);
1289 ///
1290 /// assert_eq!(to.unchecked_downcast_as::<u8>(), &7);
1291 /// }
1292 /// unsafe {
1293 /// let to: DynTrait<'static, RArc<()>, ()> =
1294 /// DynTrait::from_ptr(RArc::new(1u8));
1295 ///
1296 /// assert_eq!(to.unchecked_downcast_as::<u8>(), &1u8);
1297 /// }
1298 ///
1299 /// ```
1300 #[inline]
1301 pub unsafe fn unchecked_downcast_as<T>(&self) -> &T
1302 where
1303 P: AsPtr,
1304 {
1305 unsafe { self.sabi_object_as() }
1306 }
1307
1308 /// Unwraps the `DynTrait<_>` into a mutable reference to T,
1309 /// without checking whether `T` is the type that the DynTrait was constructed with.
1310 ///
1311 /// # Safety
1312 ///
1313 /// You must check that `T` is the type that DynTrait was constructed
1314 /// with through other means.
1315 ///
1316 /// # Example
1317 ///
1318 /// ```rust
1319 /// use abi_stable::{std_types::RBox, DynTrait, RMut};
1320 ///
1321 /// unsafe {
1322 /// let mut val = 7u8;
1323 ///
1324 /// let mut to: DynTrait<'static, RMut<'_, ()>, ()> =
1325 /// DynTrait::from_ptr(&mut val);
1326 ///
1327 /// assert_eq!(to.unchecked_downcast_as_mut::<u8>(), &mut 7);
1328 /// }
1329 /// unsafe {
1330 /// let mut to: DynTrait<'static, RBox<()>, ()> =
1331 /// DynTrait::from_ptr(RBox::new(1u8));
1332 ///
1333 /// assert_eq!(to.unchecked_downcast_as_mut::<u8>(), &mut 1u8);
1334 /// }
1335 ///
1336 /// ```
1337 #[inline]
1338 pub unsafe fn unchecked_downcast_as_mut<T>(&mut self) -> &mut T
1339 where
1340 P: AsMutPtr,
1341 {
1342 unsafe { self.sabi_object_as_mut() }
1343 }
1344 }
1345
1346 mod private_struct {
1347 pub struct PrivStruct;
1348 }
1349 use self::private_struct::PrivStruct;
1350
1351 /// This is used to make sure that reborrowing does not change
1352 /// the Send-ness or Sync-ness of the pointer.
1353 pub trait ReborrowBounds<SendNess, SyncNess> {}
1354
1355 // If it's reborrowing, it must have either both Sync+Send or neither.
1356 impl ReborrowBounds<Unimplemented<trait_marker::Send>, Unimplemented<trait_marker::Sync>>
1357 for PrivStruct
1358 {
1359 }
1360
1361 impl ReborrowBounds<Implemented<trait_marker::Send>, Implemented<trait_marker::Sync>>
1362 for PrivStruct
1363 {
1364 }
1365
1366 impl<'borr, P, I, EV> DynTrait<'borr, P, I, EV>
1367 where
1368 P: GetPointerKind,
1369 I: InterfaceType,
1370 {
1371 /// Creates a shared reborrow of this DynTrait.
1372 ///
1373 /// The reborrowed DynTrait cannot use these methods:
1374 ///
1375 /// - DynTrait::default
1376 ///
1377 /// This is only callable if `DynTrait` is either `Send + Sync` or `!Send + !Sync`.
1378 ///
1379 /// # Example
1380 ///
1381 /// ```rust
1382 /// use abi_stable::{
1383 /// erased_types::interfaces::DebugDisplayInterface,
1384 /// std_types::RBox,
1385 /// type_level::{impl_enum::Implemented, trait_marker},
1386 /// DynTrait, InterfaceType, RRef,
1387 /// };
1388 ///
1389 /// let to: DynTrait<'static, RBox<()>, DebugDisplayInterface> =
1390 /// DynTrait::from_value(1337_u16);
1391 ///
1392 /// assert_eq!(debug_string(to.reborrow()), "1337");
1393 ///
1394 /// fn debug_string<I>(to: DynTrait<'_, RRef<'_, ()>, I>) -> String
1395 /// where
1396 /// I: InterfaceType<Debug = Implemented<trait_marker::Debug>>,
1397 /// {
1398 /// format!("{:?}", to)
1399 /// }
1400 ///
1401 /// ```
1402 pub fn reborrow<'re>(&'re self) -> DynTrait<'borr, RRef<'re, ()>, I, EV>
1403 where
1404 P: AsPtr<PtrTarget = ()>,
1405 PrivStruct: ReborrowBounds<I::Send, I::Sync>,
1406 EV: Copy,
1407 {
1408 // Reborrowing will break if I add extra functions that operate on `P`.
1409 DynTrait {
1410 object: ManuallyDrop::new(self.object.as_rref()),
1411 vtable: unsafe { VTable_Ref(self.vtable.0.cast()) },
1412 extra_value: *self.sabi_extra_value(),
1413 _marker: NonOwningPhantom::NEW,
1414 _marker2: UnsafeIgnoredType::DEFAULT,
1415 }
1416 }
1417
1418 /// Creates a mutable reborrow of this DynTrait.
1419 ///
1420 /// The reborrowed DynTrait cannot use these methods:
1421 ///
1422 /// - DynTrait::default
1423 ///
1424 /// - DynTrait::clone
1425 ///
1426 /// This is only callable if `DynTrait` is either `Send + Sync` or `!Send + !Sync`.
1427 ///
1428 /// # Example
1429 ///
1430 /// ```rust
1431 /// use abi_stable::{
1432 /// erased_types::interfaces::DEIteratorInterface, std_types::RBox, DynTrait,
1433 /// };
1434 ///
1435 /// let mut to = DynTrait::from_value(0_u8..=255).interface(DEIteratorInterface::NEW);
1436 ///
1437 /// assert_eq!(both_ends(to.reborrow_mut()), (Some(0), Some(255)));
1438 /// assert_eq!(both_ends(to.reborrow_mut()), (Some(1), Some(254)));
1439 /// assert_eq!(both_ends(to.reborrow_mut()), (Some(2), Some(253)));
1440 /// assert_eq!(both_ends(to.reborrow_mut()), (Some(3), Some(252)));
1441 ///
1442 /// fn both_ends<I>(mut to: I) -> (Option<I::Item>, Option<I::Item>)
1443 /// where
1444 /// I: DoubleEndedIterator,
1445 /// {
1446 /// (to.next(), to.next_back())
1447 /// }
1448 ///
1449 /// ```
1450 pub fn reborrow_mut<'re>(&'re mut self) -> DynTrait<'borr, RMut<'re, ()>, I, EV>
1451 where
1452 P: AsMutPtr<PtrTarget = ()>,
1453 PrivStruct: ReborrowBounds<I::Send, I::Sync>,
1454 EV: Copy,
1455 {
1456 let extra_value = *self.sabi_extra_value();
1457 // Reborrowing will break if I add extra functions that operate on `P`.
1458 DynTrait {
1459 object: ManuallyDrop::new(self.object.as_rmut()),
1460 vtable: unsafe { VTable_Ref(self.vtable.0.cast()) },
1461 extra_value,
1462 _marker: NonOwningPhantom::NEW,
1463 _marker2: UnsafeIgnoredType::DEFAULT,
1464 }
1465 }
1466 }
1467
1468 impl<'borr, P, I, EV> DynTrait<'borr, P, I, EV>
1469 where
1470 P: AsPtr,
1471 {
1472 /// Constructs a DynTrait<P, I> with a `P`, using the same vtable.
1473 ///
1474 /// `P` must come from a function in the vtable,
1475 /// or come from a copy of `P: Copy+GetPointerKind<Kind = PK_Reference>`,
1476 /// to ensure that it is compatible with the functions in it.
1477 #[allow(clippy::wrong_self_convention)]
1478 pub(super) const fn from_new_ptr(&self, object: P, extra_value: EV) -> Self {
1479 Self {
1480 object: ManuallyDrop::new(object),
1481 vtable: self.vtable,
1482 extra_value,
1483 _marker: NonOwningPhantom::NEW,
1484 _marker2: UnsafeIgnoredType::DEFAULT,
1485 }
1486 }
1487 }
1488
1489 impl<'borr, P, I, EV> DynTrait<'borr, P, I, EV>
1490 where
1491 I: InterfaceType + 'borr,
1492 EV: 'borr,
1493 P: AsPtr,
1494 {
1495 /// Constructs a `DynTrait<P, I>` with the default value for `P`.
1496 ///
1497 /// # Reborrowing
1498 ///
1499 /// This cannot be called with a reborrowed DynTrait:
1500 ///
1501 /// ```compile_fail
1502 /// # use abi_stable::{
1503 /// # DynTrait,
1504 /// # erased_types::interfaces::DefaultInterface,
1505 /// # };
1506 /// let object = DynTrait::from_value(()).interface(DefaultInterface);
1507 /// let borrow = object.reborrow();
1508 /// let _ = borrow.default();
1509 ///
1510 /// ```
1511 ///
1512 /// ```compile_fail
1513 /// # use abi_stable::{
1514 /// # DynTrait,
1515 /// # erased_types::interfaces::DefaultInterface,
1516 /// # };
1517 /// let object = DynTrait::from_value(()).interface(DefaultInterface);
1518 /// let borrow = object.reborrow_mut();
1519 /// let _ = borrow.default();
1520 ///
1521 /// ```
1522 ///
1523 /// # Example
1524 ///
1525 /// ```rust
1526 /// use abi_stable::{erased_types::interfaces::DebugDefEqInterface, DynTrait};
1527 ///
1528 /// {
1529 /// let object = DynTrait::from_value(true).interface(DebugDefEqInterface);
1530 ///
1531 /// assert_eq!(
1532 /// object.default(),
1533 /// DynTrait::from_value(false).interface(DebugDefEqInterface)
1534 /// );
1535 /// }
1536 /// {
1537 /// let object = DynTrait::from_value(123u8).interface(DebugDefEqInterface);
1538 ///
1539 /// assert_eq!(
1540 /// object.default(),
1541 /// DynTrait::from_value(0u8).interface(DebugDefEqInterface)
1542 /// );
1543 /// }
1544 ///
1545 /// ```
1546 pub fn default(&self) -> Self
1547 where
1548 P: AsPtr + GetPointerKind<Kind = PK_SmartPointer>,
1549 I: InterfaceType<Default = Implemented<trait_marker::Default>>,
1550 EV: Copy,
1551 {
1552 unsafe {
1553 let new = self.sabi_vtable().default_ptr()();
1554 self.from_new_ptr(new, *self.sabi_extra_value())
1555 }
1556 }
1557
1558 /// It serializes a `DynTrait<_>` into a string by using
1559 /// `<ConcreteType as SerializeType>::serialize_impl`.
1560 // I'm using the lifetime in the where clause, clippy <_<
1561 #[allow(clippy::needless_lifetimes)]
1562 pub fn serialize_into_proxy<'a>(&'a self) -> Result<I::ProxyType, RBoxError>
1563 where
1564 P: AsPtr,
1565 I: InterfaceType<Serialize = Implemented<trait_marker::Serialize>>,
1566 I: GetSerializeProxyType<'a>,
1567 {
1568 unsafe { self.sabi_vtable().serialize()(self.sabi_erased_ref()).into_result() }
1569 }
1570 /// Deserializes a `DynTrait<'borr, _>` from a proxy type, by using
1571 /// `<I as DeserializeDyn<'borr, Self>>::deserialize_dyn`.
1572 pub fn deserialize_from_proxy<'de>(proxy: I::Proxy) -> Result<Self, RBoxError>
1573 where
1574 P: 'borr + AsPtr,
1575 I: DeserializeDyn<'de, Self>,
1576 {
1577 I::deserialize_dyn(proxy)
1578 }
1579 }
1580
1581 impl<'lt, I, EV: Clone> DynTrait<'lt, crate::std_types::RArc<()>, I, EV> {
1582 /// Does a shallow clone of the object, just incrementing the reference counter
1583 pub fn shallow_clone(&self) -> Self {
1584 Self {
1585 object: self.object.clone(),
1586 vtable: self.vtable,
1587 extra_value: self.extra_value.clone(),
1588 _marker: self._marker,
1589 _marker2: self._marker2,
1590 }
1591 }
1592 }
1593
1594 impl<'borr, P, I, EV> Drop for DynTrait<'borr, P, I, EV>
1595 where
1596 P: GetPointerKind,
1597 {
1598 fn drop(&mut self) {
1599 unsafe {
1600 let vtable = self.sabi_vtable();
1601
1602 if <P as GetPointerKind>::KIND == PointerKind::SmartPointer {
1603 vtable.drop_ptr()(RMut::<P>::new(&mut self.object));
1604 }
1605 }
1606 }
1607 }
1608}
1609
1610pub use self::priv_::DynTrait;
1611
1612//////////////////////
1613
1614mod clone_impl {
1615 pub trait CloneImpl<PtrKind> {
1616 fn clone_impl(&self) -> Self;
1617 }
1618}
1619use self::clone_impl::CloneImpl;
1620
1621/// This impl is for smart pointers.
1622impl<'borr, P, I, EV> CloneImpl<PK_SmartPointer> for DynTrait<'borr, P, I, EV>
1623where
1624 P: AsPtr,
1625 I: InterfaceType<Clone = Implemented<trait_marker::Clone>> + 'borr,
1626 EV: Copy + 'borr,
1627{
1628 fn clone_impl(&self) -> Self {
1629 unsafe {
1630 let vtable = self.sabi_vtable();
1631 let new = vtable.clone_ptr()(RRef::<P>::new(&*self.object));
1632 self.from_new_ptr(new, *self.sabi_extra_value())
1633 }
1634 }
1635}
1636
1637/// This impl is for references.
1638impl<'borr, P, I, EV> CloneImpl<PK_Reference> for DynTrait<'borr, P, I, EV>
1639where
1640 P: AsPtr + Copy,
1641 I: InterfaceType<Clone = Implemented<trait_marker::Clone>> + 'borr,
1642 EV: Copy + 'borr,
1643{
1644 fn clone_impl(&self) -> Self {
1645 self.from_new_ptr(*self.object, *self.sabi_extra_value())
1646 }
1647}
1648
1649/// Clone is implemented for references and smart pointers,
1650/// using `GetPointerKind` to decide whether `P` is a smart pointer or a reference.
1651///
1652/// DynTrait does not implement Clone if P ==`RMut<'_, ()>` :
1653///
1654/// ```compile_fail
1655/// # use abi_stable::{
1656/// # DynTrait,
1657/// # erased_types::interfaces::CloneInterface,
1658/// # };
1659///
1660/// let mut object = DynTrait::from_value(()).interface(());
1661/// let borrow = object.reborrow_mut();
1662/// let _ = borrow.clone();
1663///
1664/// ```
1665///
1666impl<'borr, P, I, EV> Clone for DynTrait<'borr, P, I, EV>
1667where
1668 P: AsPtr,
1669 I: InterfaceType,
1670 Self: CloneImpl<<P as GetPointerKind>::Kind>,
1671{
1672 fn clone(&self) -> Self {
1673 self.clone_impl()
1674 }
1675}
1676
1677//////////////////////
1678
1679impl<'borr, P, I, EV> Display for DynTrait<'borr, P, I, EV>
1680where
1681 P: AsPtr,
1682 I: InterfaceType<Display = Implemented<trait_marker::Display>>,
1683{
1684 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1685 unsafe {
1686 adapt_std_fmt::<ErasedObject>(self.sabi_erased_ref(), self.sabi_vtable().display(), f)
1687 }
1688 }
1689}
1690
1691impl<'borr, P, I, EV> Debug for DynTrait<'borr, P, I, EV>
1692where
1693 P: AsPtr,
1694 I: InterfaceType<Debug = Implemented<trait_marker::Debug>>,
1695{
1696 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1697 unsafe {
1698 adapt_std_fmt::<ErasedObject>(self.sabi_erased_ref(), self.sabi_vtable().debug(), f)
1699 }
1700 }
1701}
1702
1703impl<'borr, P, I, EV> std::error::Error for DynTrait<'borr, P, I, EV>
1704where
1705 P: AsPtr,
1706 I: InterfaceType<
1707 Display = Implemented<trait_marker::Display>,
1708 Debug = Implemented<trait_marker::Debug>,
1709 Error = Implemented<trait_marker::Error>,
1710 >,
1711{
1712}
1713
1714/// For an example of how to serialize DynTrait,
1715/// [look here](crate::erased_types::SerializeType#example)
1716///
1717impl<'borr, P, I, EV> Serialize for DynTrait<'borr, P, I, EV>
1718where
1719 P: AsPtr,
1720 I: InterfaceType<Serialize = Implemented<trait_marker::Serialize>>,
1721 I: GetSerializeProxyType<'borr>,
1722 I::ProxyType: Serialize,
1723{
1724 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1725 where
1726 S: Serializer,
1727 {
1728 unsafe {
1729 self.sabi_vtable().serialize()(self.sabi_erased_ref_unbounded_lifetime())
1730 .into_result()
1731 .map_err(ser::Error::custom)?
1732 .serialize(serializer)
1733 }
1734 }
1735}
1736
1737/// For an example of how to deserialize DynTrait,
1738/// [look here](crate::erased_types::DeserializeDyn#example)
1739///
1740impl<'de, 'borr: 'de, P, I, EV> Deserialize<'de> for DynTrait<'borr, P, I, EV>
1741where
1742 EV: 'borr,
1743 P: AsPtr + 'borr,
1744 I: InterfaceType + 'borr,
1745 I: DeserializeDyn<'de, Self>,
1746 <I as DeserializeDyn<'de, Self>>::Proxy: Deserialize<'de>,
1747{
1748 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1749 where
1750 D: Deserializer<'de>,
1751 {
1752 let s = <<I as DeserializeDyn<'de, Self>>::Proxy>::deserialize(deserializer)?;
1753 I::deserialize_dyn(s).map_err(de::Error::custom)
1754 }
1755}
1756
1757impl<P, I, EV> Eq for DynTrait<'static, P, I, EV>
1758where
1759 Self: PartialEq,
1760 P: AsPtr,
1761 I: InterfaceType<Eq = Implemented<trait_marker::Eq>>,
1762{
1763}
1764
1765impl<P, P2, I, EV, EV2> PartialEq<DynTrait<'static, P2, I, EV2>> for DynTrait<'static, P, I, EV>
1766where
1767 P: AsPtr,
1768 P2: AsPtr,
1769 I: InterfaceType<PartialEq = Implemented<trait_marker::PartialEq>>,
1770{
1771 fn eq(&self, other: &DynTrait<'static, P2, I, EV2>) -> bool {
1772 // unsafe: must check that the vtable is the same, otherwise return a sensible value.
1773 if !self.sabi_is_same_type(other) {
1774 return false;
1775 }
1776
1777 unsafe { self.sabi_vtable().partial_eq()(self.sabi_erased_ref(), other.sabi_erased_ref()) }
1778 }
1779}
1780
1781impl<P, I, EV> Ord for DynTrait<'static, P, I, EV>
1782where
1783 P: AsPtr,
1784 I: InterfaceType<Ord = Implemented<trait_marker::Ord>>,
1785 Self: PartialOrd + Eq,
1786{
1787 fn cmp(&self, other: &Self) -> Ordering {
1788 // unsafe: must check that the vtable is the same, otherwise return a sensible value.
1789 if !self.sabi_is_same_type(other) {
1790 return self.sabi_vtable_address().cmp(&other.sabi_vtable_address());
1791 }
1792
1793 unsafe { self.sabi_vtable().cmp()(self.sabi_erased_ref(), other.sabi_erased_ref()).into() }
1794 }
1795}
1796
1797impl<P, P2, I, EV, EV2> PartialOrd<DynTrait<'static, P2, I, EV2>> for DynTrait<'static, P, I, EV>
1798where
1799 P: AsPtr,
1800 P2: AsPtr,
1801 I: InterfaceType<PartialOrd = Implemented<trait_marker::PartialOrd>>,
1802 Self: PartialEq<DynTrait<'static, P2, I, EV2>>,
1803{
1804 fn partial_cmp(&self, other: &DynTrait<'static, P2, I, EV2>) -> Option<Ordering> {
1805 // unsafe: must check that the vtable is the same, otherwise return a sensible value.
1806 if !self.sabi_is_same_type(other) {
1807 return Some(self.sabi_vtable_address().cmp(&other.sabi_vtable_address()));
1808 }
1809
1810 unsafe {
1811 self.sabi_vtable().partial_cmp()(self.sabi_erased_ref(), other.sabi_erased_ref())
1812 .map(IntoReprRust::into_rust)
1813 .into()
1814 }
1815 }
1816}
1817
1818impl<'borr, P, I, EV> Hash for DynTrait<'borr, P, I, EV>
1819where
1820 P: AsPtr,
1821 I: InterfaceType<Hash = Implemented<trait_marker::Hash>>,
1822{
1823 fn hash<H>(&self, state: &mut H)
1824 where
1825 H: Hasher,
1826 {
1827 unsafe { self.sabi_vtable().hash()(self.sabi_erased_ref(), HasherObject::new(state)) }
1828 }
1829}
1830
1831//////////////////////////////////////////////////////////////////
1832
1833impl<'borr, P, I, Item, EV> Iterator for DynTrait<'borr, P, I, EV>
1834where
1835 P: AsMutPtr,
1836 I: IteratorItemOrDefault<'borr, Item = Item>,
1837 I: InterfaceType<Iterator = Implemented<trait_marker::Iterator>>,
1838 Item: 'borr,
1839{
1840 type Item = Item;
1841
1842 fn next(&mut self) -> Option<Item> {
1843 unsafe {
1844 let vtable = self.sabi_vtable();
1845 (vtable.iter().next)(self.sabi_erased_mut()).into_rust()
1846 }
1847 }
1848
1849 fn nth(&mut self, nth: usize) -> Option<Item> {
1850 unsafe {
1851 let vtable = self.sabi_vtable();
1852 (vtable.iter().nth)(self.sabi_erased_mut(), nth).into_rust()
1853 }
1854 }
1855
1856 fn size_hint(&self) -> (usize, Option<usize>) {
1857 unsafe {
1858 let vtable = self.sabi_vtable();
1859 let tuple = (vtable.iter().size_hint)(self.sabi_erased_ref()).into_rust();
1860 (tuple.0, tuple.1.into_rust())
1861 }
1862 }
1863
1864 fn count(mut self) -> usize {
1865 unsafe {
1866 let vtable = self.sabi_vtable();
1867 (vtable.iter().count)(self.sabi_erased_mut())
1868 }
1869 }
1870
1871 fn last(mut self) -> Option<Item> {
1872 unsafe {
1873 let vtable = self.sabi_vtable();
1874 (vtable.iter().last)(self.sabi_erased_mut()).into_rust()
1875 }
1876 }
1877}
1878
1879impl<'borr, P, I, Item, EV> DynTrait<'borr, P, I, EV>
1880where
1881 P: AsMutPtr,
1882 I: IteratorItemOrDefault<'borr, Item = Item>,
1883 I: InterfaceType<Iterator = Implemented<trait_marker::Iterator>>,
1884 Item: 'borr,
1885{
1886 /// Eagerly skips n elements from the iterator.
1887 ///
1888 /// This method is faster than using `Iterator::skip`.
1889 ///
1890 /// # Example
1891 ///
1892 /// ```
1893 /// # use abi_stable::{
1894 /// # DynTrait,
1895 /// # erased_types::interfaces::IteratorInterface,
1896 /// # std_types::RVec,
1897 /// # traits::IntoReprC,
1898 /// # };
1899 ///
1900 /// let mut iter = 0..20;
1901 /// let mut wrapped = DynTrait::from_ptr(&mut iter).interface(IteratorInterface::NEW);
1902 ///
1903 /// assert_eq!(wrapped.next(), Some(0));
1904 ///
1905 /// wrapped.skip_eager(2);
1906 ///
1907 /// assert_eq!(wrapped.next(), Some(3));
1908 /// assert_eq!(wrapped.next(), Some(4));
1909 /// assert_eq!(wrapped.next(), Some(5));
1910 ///
1911 /// wrapped.skip_eager(2);
1912 ///
1913 /// assert_eq!(wrapped.next(), Some(8));
1914 /// assert_eq!(wrapped.next(), Some(9));
1915 ///
1916 /// wrapped.skip_eager(9);
1917 ///
1918 /// assert_eq!(wrapped.next(), Some(19));
1919 /// assert_eq!(wrapped.next(), None);
1920 ///
1921 ///
1922 /// ```
1923 ///
1924 pub fn skip_eager(&mut self, n: usize) {
1925 unsafe {
1926 let vtable = self.sabi_vtable();
1927 (vtable.iter().skip_eager)(self.sabi_erased_mut(), n);
1928 }
1929 }
1930
1931 /// Extends the `RVec<Item>` with the `self` Iterator.
1932 ///
1933 /// Extends `buffer` with as many elements of the iterator as `taking` specifies:
1934 ///
1935 /// - RNone: Yields all elements.Use this with care, since Iterators can be infinite.
1936 ///
1937 /// - RSome(n): Yields n elements.
1938 ///
1939 /// ### Example
1940 ///
1941 /// ```
1942 /// # use abi_stable::{
1943 /// # DynTrait,
1944 /// # erased_types::interfaces::IteratorInterface,
1945 /// # std_types::{RVec, RSome},
1946 /// # traits::IntoReprC,
1947 /// # };
1948 ///
1949 /// let mut wrapped = DynTrait::from_value(0..).interface(IteratorInterface::NEW);
1950 ///
1951 /// let mut buffer = vec![101, 102, 103].into_c();
1952 /// wrapped.extending_rvec(&mut buffer, RSome(5));
1953 /// assert_eq!(&buffer[..], &*vec![101, 102, 103, 0, 1, 2, 3, 4]);
1954 ///
1955 /// assert_eq!(wrapped.next(), Some(5));
1956 /// assert_eq!(wrapped.next(), Some(6));
1957 /// assert_eq!(wrapped.next(), Some(7));
1958 ///
1959 /// ```
1960 pub fn extending_rvec(&mut self, buffer: &mut RVec<Item>, taking: ROption<usize>) {
1961 unsafe {
1962 let vtable = self.sabi_vtable();
1963 (vtable.iter().extending_rvec)(self.sabi_erased_mut(), buffer, taking);
1964 }
1965 }
1966}
1967
1968//////////////////////////////////////////////////////////////////
1969
1970impl<'borr, P, I, Item, EV> DoubleEndedIterator for DynTrait<'borr, P, I, EV>
1971where
1972 Self: Iterator<Item = Item>,
1973 P: AsMutPtr,
1974 I: IteratorItemOrDefault<'borr, Item = Item>,
1975 I: InterfaceType<DoubleEndedIterator = Implemented<trait_marker::DoubleEndedIterator>>,
1976 Item: 'borr,
1977{
1978 fn next_back(&mut self) -> Option<Item> {
1979 unsafe {
1980 let vtable = self.sabi_vtable();
1981 (vtable.back_iter().next_back)(self.sabi_erased_mut()).into_rust()
1982 }
1983 }
1984}
1985
1986impl<'borr, P, I, Item, EV> DynTrait<'borr, P, I, EV>
1987where
1988 Self: Iterator<Item = Item>,
1989 P: AsMutPtr,
1990 I: IteratorItemOrDefault<'borr, Item = Item>,
1991 I: InterfaceType<DoubleEndedIterator = Implemented<trait_marker::DoubleEndedIterator>>,
1992 Item: 'borr,
1993{
1994 /// Gets teh `nth` element from the back of the iterator.
1995 ///
1996 /// # Example
1997 ///
1998 /// ```rust
1999 /// use abi_stable::{erased_types::interfaces::DEIteratorCloneInterface, DynTrait};
2000 ///
2001 /// let to = || DynTrait::from_value(7..=10).interface(DEIteratorCloneInterface::NEW);
2002 ///
2003 /// assert_eq!(to().nth_back_(0), Some(10));
2004 /// assert_eq!(to().nth_back_(1), Some(9));
2005 /// assert_eq!(to().nth_back_(2), Some(8));
2006 /// assert_eq!(to().nth_back_(3), Some(7));
2007 /// assert_eq!(to().nth_back_(4), None);
2008 /// assert_eq!(to().nth_back_(5), None);
2009 ///
2010 /// ```
2011 ///
2012 pub fn nth_back_(&mut self, nth: usize) -> Option<Item> {
2013 unsafe {
2014 let vtable = self.sabi_vtable();
2015 (vtable.back_iter().nth_back)(self.sabi_erased_mut(), nth).into_rust()
2016 }
2017 }
2018
2019 /// Extends the `RVec<Item>` with the back of the `self` DoubleEndedIterator.
2020 ///
2021 /// Extends `buffer` with as many elements of the iterator as `taking` specifies:
2022 ///
2023 /// - RNone: Yields all elements.Use this with care, since Iterators can be infinite.
2024 ///
2025 /// - RSome(n): Yields n elements.
2026 ///
2027 /// ### Example
2028 ///
2029 /// ```
2030 /// # use abi_stable::{
2031 /// # DynTrait,
2032 /// # erased_types::interfaces::DEIteratorInterface,
2033 /// # std_types::{RVec, RNone},
2034 /// # traits::IntoReprC,
2035 /// # };
2036 ///
2037 /// let mut wrapped = DynTrait::from_value(0..=3).interface(DEIteratorInterface::NEW);
2038 ///
2039 /// let mut buffer = vec![101, 102, 103].into_c();
2040 /// wrapped.extending_rvec_back(&mut buffer, RNone);
2041 /// assert_eq!(&buffer[..], &*vec![101, 102, 103, 3, 2, 1, 0])
2042 ///
2043 /// ```
2044 ///
2045 pub fn extending_rvec_back(&mut self, buffer: &mut RVec<Item>, taking: ROption<usize>) {
2046 unsafe {
2047 let vtable = self.sabi_vtable();
2048 (vtable.back_iter().extending_rvec_back)(self.sabi_erased_mut(), buffer, taking);
2049 }
2050 }
2051}
2052
2053//////////////////////////////////////////////////////////////////
2054
2055impl<'borr, P, I, EV> fmtWrite for DynTrait<'borr, P, I, EV>
2056where
2057 P: AsMutPtr,
2058 I: InterfaceType<FmtWrite = Implemented<trait_marker::FmtWrite>>,
2059{
2060 fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
2061 let vtable = self.sabi_vtable();
2062
2063 unsafe {
2064 match vtable.fmt_write_str()(self.sabi_erased_mut(), s.into()) {
2065 ROk(_) => Ok(()),
2066 RErr(_) => Err(fmt::Error),
2067 }
2068 }
2069 }
2070}
2071
2072//////////////////////////////////////////////////////////////////
2073
2074#[inline]
2075fn to_io_result<T, U>(res: RResult<T, RIoError>) -> io::Result<U>
2076where
2077 T: Into<U>,
2078{
2079 match res {
2080 ROk(v) => Ok(v.into()),
2081 RErr(e) => Err(e.into()),
2082 }
2083}
2084
2085/////////////
2086
2087impl<'borr, P, I, EV> io::Write for DynTrait<'borr, P, I, EV>
2088where
2089 P: AsMutPtr,
2090 I: InterfaceType<IoWrite = Implemented<trait_marker::IoWrite>>,
2091{
2092 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
2093 let vtable = self.sabi_vtable().io_write();
2094
2095 unsafe { to_io_result((vtable.write)(self.sabi_erased_mut(), buf.into())) }
2096 }
2097 fn flush(&mut self) -> io::Result<()> {
2098 let vtable = self.sabi_vtable().io_write();
2099
2100 unsafe { to_io_result((vtable.flush)(self.sabi_erased_mut())) }
2101 }
2102 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
2103 let vtable = self.sabi_vtable().io_write();
2104
2105 unsafe { to_io_result((vtable.write_all)(self.sabi_erased_mut(), buf.into())) }
2106 }
2107}
2108
2109/////////////
2110
2111impl<'borr, P, I, EV> io::Read for DynTrait<'borr, P, I, EV>
2112where
2113 P: AsMutPtr,
2114 I: InterfaceType<IoRead = Implemented<trait_marker::IoRead>>,
2115{
2116 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
2117 unsafe {
2118 let vtable = self.sabi_vtable().io_read();
2119
2120 to_io_result((vtable.read)(self.sabi_erased_mut(), buf.into()))
2121 }
2122 }
2123
2124 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
2125 unsafe {
2126 let vtable = self.sabi_vtable().io_read();
2127
2128 to_io_result((vtable.read_exact)(self.sabi_erased_mut(), buf.into()))
2129 }
2130 }
2131}
2132
2133/////////////
2134
2135impl<'borr, P, I, EV> io::BufRead for DynTrait<'borr, P, I, EV>
2136where
2137 P: AsMutPtr,
2138 I: InterfaceType<
2139 IoRead = Implemented<trait_marker::IoRead>,
2140 IoBufRead = Implemented<trait_marker::IoBufRead>,
2141 >,
2142{
2143 fn fill_buf(&mut self) -> io::Result<&[u8]> {
2144 unsafe {
2145 let vtable = self.sabi_vtable().io_bufread();
2146
2147 to_io_result((vtable.fill_buf)(self.sabi_erased_mut()))
2148 }
2149 }
2150
2151 fn consume(&mut self, amount: usize) {
2152 unsafe {
2153 let vtable = self.sabi_vtable().io_bufread();
2154
2155 (vtable.consume)(self.sabi_erased_mut(), amount)
2156 }
2157 }
2158}
2159
2160/////////////
2161
2162impl<'borr, P, I, EV> io::Seek for DynTrait<'borr, P, I, EV>
2163where
2164 P: AsMutPtr,
2165 I: InterfaceType<IoSeek = Implemented<trait_marker::IoSeek>>,
2166{
2167 fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
2168 unsafe {
2169 let vtable = self.sabi_vtable();
2170
2171 to_io_result(vtable.io_seek()(self.sabi_erased_mut(), pos.into()))
2172 }
2173 }
2174}
2175
2176//////////////////////////////////////////////////////////////////
2177
2178unsafe impl<'borr, P, I, EV> Send for DynTrait<'borr, P, I, EV>
2179where
2180 P: Send + GetPointerKind,
2181 I: InterfaceType<Send = Implemented<trait_marker::Send>>,
2182{
2183}
2184
2185unsafe impl<'borr, P, I, EV> Sync for DynTrait<'borr, P, I, EV>
2186where
2187 P: Sync + GetPointerKind,
2188 I: InterfaceType<Sync = Implemented<trait_marker::Sync>>,
2189{
2190}
2191
2192impl<'borr, P, I, EV> Unpin for DynTrait<'borr, P, I, EV>
2193where
2194 // `Unpin` is a property of the referent
2195 P: GetPointerKind,
2196 I: InterfaceType<Unpin = Implemented<trait_marker::Unpin>>,
2197{
2198}
2199
2200//////////////////////////////////////////////////////////////////
2201
2202/// Error for `DynTrait<_>` being downcasted into the wrong type
2203/// with one of the `*downcasted*` methods.
2204#[derive(Copy, Clone)]
2205pub struct UneraseError<T> {
2206 dyn_trait: T,
2207 expected_type_info: &'static TypeInfo,
2208 found_type_info: &'static TypeInfo,
2209}
2210
2211#[allow(clippy::missing_const_for_fn)]
2212impl<T> UneraseError<T> {
2213 fn map<F, U>(self, f: F) -> UneraseError<U>
2214 where
2215 F: FnOnce(T) -> U,
2216 {
2217 UneraseError {
2218 dyn_trait: f(self.dyn_trait),
2219 expected_type_info: self.expected_type_info,
2220 found_type_info: self.found_type_info,
2221 }
2222 }
2223
2224 /// Extracts the DynTrait, to handle the failure to downcast it.
2225 #[must_use]
2226 pub fn into_inner(self) -> T {
2227 self.dyn_trait
2228 }
2229}
2230
2231impl<D> fmt::Debug for UneraseError<D> {
2232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2233 f.debug_struct("UneraseError")
2234 .field("dyn_trait", &"<not shown>")
2235 .field("expected_type_info", &self.expected_type_info)
2236 .field("found_type_info", &self.found_type_info)
2237 .finish()
2238 }
2239}
2240
2241impl<D> fmt::Display for UneraseError<D> {
2242 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2243 fmt::Debug::fmt(self, f)
2244 }
2245}
2246
2247impl<D> ::std::error::Error for UneraseError<D> {}
2248
2249//////////////////////////////////////////////////////////////////