sn_ffi_utils/
repr_c.rs

1// Copyright 2019 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under the MIT license <LICENSE-MIT
4// http://opensource.org/licenses/MIT> or the Modified BSD license <LICENSE-BSD
5// https://opensource.org/licenses/BSD-3-Clause>, at your option. This file may not be copied,
6// modified, or distributed except according to those terms. Please review the Licences for the
7// specific language governing permissions and limitations relating to use of the SAFE Network
8// Software.
9
10//! FFI tools.
11//!
12//! We implement all primitive types that have been needed in SAFE projects so far. More can be
13//! implemented if needed, with the following exceptions, which should not be implemented:
14//!
15//! + `bool`: This doesn't seem to be safe to pass over the FFI directly. Should be converted to a
16//! type such as `u32` instead.
17//! + `char`: It's not clear why this would be necessary. You'd probably want to convert to `u32`
18//! for better ABI stability.
19//! + `i128` and `u128`: do not have a stable ABI, so they cannot be returned across the FFI.
20
21/// Trait to convert between FFI and Rust representations of types.
22pub trait ReprC {
23    /// C representation of the type.
24    type C;
25    /// Error type.
26    type Error;
27
28    /// Convert from a raw FFI type into a native Rust type by cloning the data.
29    ///
30    /// # Safety
31    ///
32    /// The implementation of this function may be unsafe, as `repr_c` may be a raw pointer that
33    /// needs to be valid.
34    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error>
35    where
36        Self: Sized;
37}
38
39impl ReprC for i32 {
40    type C = i32;
41    type Error = ();
42
43    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
44        Ok(repr_c)
45    }
46}
47
48impl ReprC for i64 {
49    type C = i64;
50    type Error = ();
51
52    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
53        Ok(repr_c)
54    }
55}
56
57impl ReprC for u32 {
58    type C = u32;
59    type Error = ();
60
61    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
62        Ok(repr_c)
63    }
64}
65
66impl ReprC for u64 {
67    type C = u64;
68    type Error = ();
69
70    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
71        Ok(repr_c)
72    }
73}
74
75impl ReprC for usize {
76    type C = usize;
77    type Error = ();
78
79    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
80        Ok(repr_c)
81    }
82}
83
84impl<T> ReprC for *const T {
85    type C = *const T;
86    type Error = ();
87
88    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
89        Ok(repr_c)
90    }
91}
92
93impl<T> ReprC for *mut T {
94    type C = *mut T;
95    type Error = ();
96
97    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
98        Ok(repr_c)
99    }
100}
101
102// TODO: Replace these with a const generic implementation once it is stable.
103// https://github.com/rust-lang/rust/issues/44580
104
105impl ReprC for [u8; 24] {
106    type C = *const [u8; 24];
107    type Error = ();
108
109    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
110        Ok(*repr_c)
111    }
112}
113
114impl ReprC for [u8; 32] {
115    type C = *const [u8; 32];
116    type Error = ();
117
118    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
119        Ok(*repr_c)
120    }
121}
122
123impl ReprC for [u8; 48] {
124    type C = *const [u8; 48];
125    type Error = ();
126
127    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
128        Ok(*repr_c)
129    }
130}
131
132impl ReprC for [u8; 64] {
133    type C = *const [u8; 64];
134    type Error = ();
135
136    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
137        Ok(*repr_c)
138    }
139}
140
141impl ReprC for [u8; 96] {
142    type C = *const [u8; 96];
143    type Error = ();
144
145    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
146        Ok(*repr_c)
147    }
148}
149
150impl ReprC for bool {
151    type C = u32;
152    type Error = ();
153
154    unsafe fn clone_from_repr_c(repr_c: Self::C) -> Result<Self, Self::Error> {
155        Ok(repr_c != 0)
156    }
157}