abi_stable/erased_types/traits.rs
1//! Traits for types wrapped in `DynTrait<_>`
2
3use crate::std_types::RBoxError;
4
5#[allow(unused_imports)]
6use crate::type_level::{
7 bools::{False, True},
8 impl_enum::{Implementability, Implemented, Unimplemented},
9 trait_marker,
10};
11
12macro_rules! declare_InterfaceType {
13 (
14
15 $(#[$attrs:meta])*
16
17 assoc_types[
18 $(
19 $(#[$assoc_attrs:meta])*
20 type $trait_:ident ;
21 )*
22 ]
23 ) => (
24 $(#[$attrs])*
25 pub trait InterfaceType: Sized {
26 $(
27 $(#[$assoc_attrs])*
28 type $trait_: Implementability;
29 )*
30
31 #[doc(hidden)]
32 type define_this_in_the_impl_InterfaceType_macro;
33 }
34
35
36 )
37}
38
39declare_InterfaceType! {
40 /// Defines the usable/required traits when creating a
41 /// [`DynTrait<Pointer<()>, ThisInterfaceType>`](crate::DynTrait).
42 ///
43 /// This trait can only be implemented using the
44 /// [`#[derive(StableAbi)]`](derive@crate::StableAbi)
45 /// derive with the
46 /// [`#[sabi(impl_InterfaceType(...))]`](derive@crate::StableAbi#sabiimpl_interfacetype)
47 /// helper attribute,
48 /// defaulting associated types to `Unimplemented<_>`.
49 ///
50 /// The value of every associated type can be:
51 ///
52 /// - [`Implemented<_>`](crate::type_level::impl_enum::Implemented):
53 /// the trait would be required by, and be usable in `DynTrait`.
54 ///
55 /// - [`Unimplemented<_>`](crate::type_level::impl_enum::Unimplemented):
56 /// the trait would not be required by, and not be usable in `DynTrait`.
57 ///
58 /// # Example
59 ///
60 /// ```
61 ///
62 /// use abi_stable::{erased_types::InterfaceType, type_level::bools::*, StableAbi};
63 ///
64 /// #[repr(C)]
65 /// #[derive(StableAbi)]
66 /// #[sabi(impl_InterfaceType(Clone, Debug))]
67 /// pub struct FooInterface;
68 ///
69 /// /*
70 /// The `#[sabi(impl_InterfaceType(Clone, Debug))]` helper attribute
71 /// (as part of #[derive(StableAbi)]) above is roughly equivalent to this impl:
72 ///
73 /// impl InterfaceType for FooInterface {
74 /// type Clone = Implemented<trait_marker::Clone>;
75 ///
76 /// type Debug = Implemented<trait_marker::Debug>;
77 ///
78 /// /////////////////////////////////////
79 /// //// defaulted associated types
80 /// /////////////////////////////////////
81 ///
82 /// // Changing this to require/unrequire in minor versions, is an abi breaking change.
83 /// // type Send = Unimplemented<trait_marker::Send>;
84 ///
85 /// // Changing this to require/unrequire in minor versions, is an abi breaking change.
86 /// // type Sync = Unimplemented<trait_marker::Sync>;
87 ///
88 /// // Changing this to require/unrequire in minor versions, is an abi breaking change.
89 /// // type Unpin = Unimplemented<trait_marker::Unpin>;
90 ///
91 /// // type Iterator = Unimplemented<trait_marker::Iterator>;
92 ///
93 /// // type DoubleEndedIterator = Unimplemented<trait_marker::DoubleEndedIterator>;
94 ///
95 /// // type Default = Unimplemented<trait_marker::Default>;
96 ///
97 /// // type Display = Unimplemented<trait_marker::Display>;
98 ///
99 /// // type Serialize = Unimplemented<trait_marker::Serialize>;
100 ///
101 /// // type Eq = Unimplemented<trait_marker::Eq>;
102 ///
103 /// // type PartialEq = Unimplemented<trait_marker::PartialEq>;
104 ///
105 /// // type Ord = Unimplemented<trait_marker::Ord>;
106 ///
107 /// // type PartialOrd = Unimplemented<trait_marker::PartialOrd>;
108 ///
109 /// // type Hash = Unimplemented<trait_marker::Hash>;
110 ///
111 /// // type Deserialize = Unimplemented<trait_marker::Deserialize>;
112 ///
113 /// // type FmtWrite = Unimplemented<trait_marker::FmtWrite>;
114 ///
115 /// // type IoWrite = Unimplemented<trait_marker::IoWrite>;
116 ///
117 /// // type IoSeek = Unimplemented<trait_marker::IoSeek>;
118 ///
119 /// // type IoRead = Unimplemented<trait_marker::IoRead>;
120 ///
121 /// // type IoBufRead = Unimplemented<trait_marker::IoBufRead>;
122 ///
123 /// // type Error = Unimplemented<trait_marker::Error>;
124 /// }
125 /// */
126 ///
127 /// # fn main(){}
128 ///
129 ///
130 /// ```
131 ///
132 ///
133 ///
134 ///
135 assoc_types[
136 /// Changing this to require/unrequire in minor versions, is an abi breaking change.
137 type Send;
138
139 /// Changing this to require/unrequire in minor versions, is an abi breaking change.
140 type Sync;
141
142 /// Changing this to require/unrequire in minor versions, is an abi breaking change.
143 type Unpin;
144
145 ///
146 type Clone;
147
148 ///
149 type Default;
150
151 ///
152 type Display;
153
154 ///
155 type Debug;
156
157 ///
158 type Serialize;
159
160 ///
161 type Eq;
162
163 ///
164 type PartialEq;
165
166 ///
167 type Ord;
168
169 ///
170 type PartialOrd;
171
172 ///
173 type Hash;
174
175 ///
176 type Deserialize;
177
178 ///
179 type Iterator;
180
181 ///
182 type DoubleEndedIterator;
183
184 /// For the `std::fmt::Write` trait
185 type FmtWrite;
186
187 /// For the `std::io::Write` trait
188 type IoWrite;
189
190 /// For the `std::io::Seek` trait
191 type IoSeek;
192
193 /// For the `std::io::Read` trait
194 type IoRead;
195
196 /// For the `std::io::BufRead` trait
197 type IoBufRead;
198
199 /// For the `std::error::Error` trait
200 type Error;
201 ]
202
203
204}
205
206///////////////////////////////////////////////////////////////////////////////
207
208/// Describes how a type is serialized by [`DynTrait`].
209///
210/// # Example
211///
212/// ```rust
213/// use abi_stable::{
214/// erased_types::{SerializeType, SerializeProxyType, DynTrait},
215/// external_types::RawValueBox,
216/// std_types::{RBox, RBoxError, RErr, ROk, RResult, RStr},
217/// StableAbi,
218/// };
219///
220/// let boxed = make_foo_box(1234);
221/// let serialized = serde_json::to_string(&boxed).unwrap();
222/// assert_eq!(serialized, r#"{"field":1234}"#);
223///
224///
225/// type FooBox = DynTrait<'static, RBox<()>, FooInterface>;
226///
227/// /// Implements `InterfaceType`, requiring `Send + Sync + Debug + Eq`
228/// #[repr(C)]
229/// #[derive(StableAbi)]
230/// #[sabi(impl_InterfaceType(Send, Sync, Debug, Eq, Serialize))]
231/// pub struct FooInterface;
232///
233/// impl SerializeProxyType<'_> for FooInterface {
234/// type Proxy = RawValueBox;
235/// }
236///
237/// /////////////
238/// // everything below could be defined in an implementation crate
239///
240/// #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
241/// struct Foo {
242/// field: u32,
243/// }
244///
245/// impl<'a> SerializeType<'a> for Foo {
246/// type Interface = FooInterface;
247///
248/// fn serialize_impl(&'a self) -> Result<RawValueBox, RBoxError> {
249/// match serde_json::value::to_raw_value::<Foo>(self) {
250/// Ok(x) => Ok(x.into()),
251/// Err(e) => Err(RBoxError::new(e)),
252/// }
253/// }
254/// }
255///
256/// extern "C" fn make_foo_box(field: u32) -> FooBox {
257/// abi_stable::extern_fn_panic_handling!{
258/// FooBox::from_value(Foo{field})
259/// }
260/// }
261/// ```
262///
263///
264/// [`DynTrait`]: ../struct.DynTrait.html
265pub trait SerializeType<'s> {
266 /// An [`InterfaceType`] implementor which determines the
267 /// intermediate type through which this is serialized.
268 ///
269 /// [`InterfaceType`]: ./trait.InterfaceType.html
270 type Interface: SerializeProxyType<'s>;
271
272 /// Performs the serialization into the proxy.
273 fn serialize_impl(
274 &'s self,
275 ) -> Result<<Self::Interface as SerializeProxyType<'s>>::Proxy, RBoxError>;
276}
277
278/// Determines the intermediate type a [`SerializeType`] implementor is converted into,
279/// and is then serialized.
280///
281/// [`SerializeType`]: ./trait.SerializeType.html
282pub trait SerializeProxyType<'borr>: InterfaceType {
283 /// The intermediate type.
284 type Proxy: 'borr;
285}
286
287#[doc(hidden)]
288pub trait GetSerializeProxyType<'borr>: InterfaceType {
289 type ProxyType;
290}
291
292impl<'borr, I, PT> GetSerializeProxyType<'borr> for I
293where
294 I: InterfaceType,
295 I: GetSerializeProxyTypeHelper<'borr, <I as InterfaceType>::Serialize, ProxyType = PT>,
296{
297 type ProxyType = PT;
298}
299
300#[doc(hidden)]
301pub trait GetSerializeProxyTypeHelper<'borr, IS>: InterfaceType {
302 type ProxyType;
303}
304
305impl<'borr, I> GetSerializeProxyTypeHelper<'borr, Implemented<trait_marker::Serialize>> for I
306where
307 I: SerializeProxyType<'borr>,
308{
309 type ProxyType = <I as SerializeProxyType<'borr>>::Proxy;
310}
311
312impl<'borr, I> GetSerializeProxyTypeHelper<'borr, Unimplemented<trait_marker::Serialize>> for I
313where
314 I: InterfaceType,
315{
316 type ProxyType = ();
317}
318
319///////////////////////////////////////
320
321/// Describes how `D` is deserialized, using a proxy to do so.
322///
323/// Generally this delegates to a library function,
324/// so that the implementation can be delegated
325/// to the `implementation crate`.
326///
327/// # Example
328///
329/// ```rust
330/// use abi_stable::{
331/// erased_types::{DeserializeDyn, DynTrait},
332/// external_types::RawValueRef,
333/// std_types::{RBox, RBoxError, RErr, ROk, RResult, RStr},
334/// StableAbi,
335/// };
336///
337/// let boxed = serde_json::from_str::<FooBox>(r#"{"field": 10}"#).unwrap();
338///
339/// assert_eq!(*boxed.downcast_as::<Foo>().unwrap(), Foo{field: 10});
340///
341///
342///
343/// type FooBox = DynTrait<'static, RBox<()>, FooInterface>;
344///
345/// /// Implements `InterfaceType`, requiring `Send + Sync + Debug + Eq`
346/// #[repr(C)]
347/// #[derive(StableAbi)]
348/// #[sabi(impl_InterfaceType(Send, Sync, Debug, Eq, Deserialize))]
349/// pub struct FooInterface;
350///
351/// impl<'a> DeserializeDyn<'a, FooBox> for FooInterface {
352/// type Proxy = RawValueRef<'a>;
353///
354/// fn deserialize_dyn(s: Self::Proxy) -> Result<FooBox, RBoxError> {
355/// deserialize_foo(s.get_rstr()).into_result()
356/// }
357/// }
358///
359/// /////////////
360/// // everything below could be defined in an implementation crate
361///
362/// #[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
363/// struct Foo {
364/// field: u32,
365/// }
366///
367/// extern "C" fn deserialize_foo(s: RStr<'_>) -> RResult<FooBox, RBoxError> {
368/// abi_stable::extern_fn_panic_handling!{
369/// match serde_json::from_str::<Foo>(s.into()) {
370/// Ok(x) => ROk(DynTrait::from_value(x)),
371/// Err(e) => RErr(RBoxError::new(e)),
372/// }
373/// }
374/// }
375/// ```
376///
377pub trait DeserializeDyn<'borr, D>:
378 InterfaceType<Deserialize = Implemented<trait_marker::Deserialize>>
379{
380 /// The type that is deserialized and then converted into `D`,
381 /// with `DeserializeDyn::deserialize_dyn`.
382 type Proxy;
383
384 /// Converts the proxy type into `D`.
385 fn deserialize_dyn(s: Self::Proxy) -> Result<D, RBoxError>;
386}
387
388/// The way to specify the expected `Iterator::Item` type for an `InterfaceType`.
389///
390/// This is a separate trait to allow iterators that yield borrowed elements.
391pub trait IteratorItem<'a>: InterfaceType {
392 /// The iterator item type.
393 type Item;
394}
395
396/// Gets the expected `Iterator::Item` type for an `InterfaceType`,
397/// defaulting to `()` if it doesn't require `Iterator` to be implemented.
398///
399/// Used by `DynTrait`'s vtable to give its iterator methods a defaulted return type.
400pub trait IteratorItemOrDefault<'borr>: InterfaceType {
401 /// The iterator item type.
402 type Item;
403}
404
405impl<'borr, I, Item> IteratorItemOrDefault<'borr> for I
406where
407 I: InterfaceType,
408 I: IteratorItemOrDefaultHelper<'borr, <I as InterfaceType>::Iterator, Item = Item>,
409{
410 type Item = Item;
411}
412
413#[doc(hidden)]
414pub trait IteratorItemOrDefaultHelper<'borr, ImplIsRequired> {
415 type Item;
416}
417
418impl<'borr, I, Item> IteratorItemOrDefaultHelper<'borr, Implemented<trait_marker::Iterator>> for I
419where
420 I: IteratorItem<'borr, Item = Item>,
421{
422 type Item = Item;
423}
424
425impl<'borr, I> IteratorItemOrDefaultHelper<'borr, Unimplemented<trait_marker::Iterator>> for I {
426 type Item = ();
427}
428
429/////////////////////////////////////////////////////////////////////
430
431crate::impl_InterfaceType! {
432 impl crate::erased_types::InterfaceType for () {
433 type Send= True;
434 type Sync= True;
435 }
436}