cpp_utils/
convert.rs

1use crate::ptr::NullPtr;
2use crate::{CppBox, CppDeletable, MutPtr, MutRef, Ptr, Ref, StaticUpcast};
3use std::ffi::CStr;
4use std::os::raw::c_char;
5
6/// Performs some of the conversions that are available implicitly in C++.
7///
8/// `CastInto` is automatically implemented for all `CastFrom` conversions,
9/// similar to `From` and `Into` traits from `std`.
10pub trait CastFrom<T>: Sized {
11    /// Performs the conversion.
12    ///
13    /// ### Safety
14    ///
15    /// This operation is safe as long as `value` is valid.
16    unsafe fn cast_from(value: T) -> Self;
17}
18
19/// Performs some of the conversions that are available implicitly in C++.
20///
21/// `CastInto` is automatically implemented for all `CastFrom` conversions,
22/// similar to `From` and `Into` traits from `std`.
23pub trait CastInto<T>: Sized {
24    /// Performs the conversion.
25    ///
26    /// ### Safety
27    ///
28    /// This operation is safe as long as `self` is valid.
29    unsafe fn cast_into(self) -> T;
30}
31
32impl<T, U: CastFrom<T>> CastInto<U> for T {
33    unsafe fn cast_into(self) -> U {
34        U::cast_from(self)
35    }
36}
37
38impl<T, U> CastFrom<MutPtr<U>> for Ptr<T>
39where
40    U: StaticUpcast<T>,
41{
42    unsafe fn cast_from(value: MutPtr<U>) -> Self {
43        <U as StaticUpcast<T>>::static_upcast_mut(value).as_ptr()
44    }
45}
46
47impl<T, U> CastFrom<MutRef<U>> for MutPtr<T>
48where
49    U: StaticUpcast<T>,
50{
51    unsafe fn cast_from(value: MutRef<U>) -> Self {
52        StaticUpcast::static_upcast_mut(value.as_mut_ptr())
53    }
54}
55
56impl<T, U> CastFrom<Ref<U>> for Ptr<T>
57where
58    U: StaticUpcast<T>,
59{
60    unsafe fn cast_from(value: Ref<U>) -> Self {
61        StaticUpcast::static_upcast(value.as_ptr())
62    }
63}
64
65impl<T, U> CastFrom<MutRef<U>> for Ref<T>
66where
67    U: StaticUpcast<T>,
68{
69    unsafe fn cast_from(value: MutRef<U>) -> Self {
70        StaticUpcast::static_upcast(value.as_ptr())
71            .as_ref()
72            .expect("StaticUpcast returned null on Ref input")
73    }
74}
75
76impl<T, U> CastFrom<MutRef<U>> for Ptr<T>
77where
78    U: StaticUpcast<T>,
79{
80    unsafe fn cast_from(value: MutRef<U>) -> Self {
81        StaticUpcast::static_upcast(value.as_ptr())
82    }
83}
84
85impl<'a, T, U: CppDeletable> CastFrom<&'a CppBox<U>> for Ptr<T>
86where
87    U: StaticUpcast<T>,
88{
89    unsafe fn cast_from(value: &'a CppBox<U>) -> Self {
90        StaticUpcast::static_upcast(value.as_ptr())
91    }
92}
93
94impl<'a, T, U: CppDeletable> CastFrom<&'a mut CppBox<U>> for MutPtr<T>
95where
96    U: StaticUpcast<T>,
97{
98    unsafe fn cast_from(value: &'a mut CppBox<U>) -> Self {
99        StaticUpcast::static_upcast_mut(value.as_mut_ptr())
100    }
101}
102
103impl<'a, T, U: CppDeletable> CastFrom<&'a CppBox<U>> for Ref<T>
104where
105    U: StaticUpcast<T>,
106{
107    unsafe fn cast_from(value: &'a CppBox<U>) -> Self {
108        StaticUpcast::static_upcast(value.as_ptr())
109            .as_ref()
110            .expect("StaticUpcast returned null on CppBox input")
111    }
112}
113
114impl<'a, T, U: CppDeletable> CastFrom<&'a mut CppBox<U>> for MutRef<T>
115where
116    U: StaticUpcast<T>,
117{
118    unsafe fn cast_from(value: &'a mut CppBox<U>) -> Self {
119        StaticUpcast::static_upcast_mut(value.as_mut_ptr())
120            .as_mut_ref()
121            .expect("StaticUpcast returned null on CppBox input")
122    }
123}
124
125impl<T, U> CastFrom<Ptr<U>> for Ptr<T>
126where
127    U: StaticUpcast<T>,
128{
129    unsafe fn cast_from(value: Ptr<U>) -> Self {
130        StaticUpcast::static_upcast(value)
131    }
132}
133
134impl<T, U> CastFrom<MutPtr<U>> for MutPtr<T>
135where
136    U: StaticUpcast<T>,
137{
138    unsafe fn cast_from(value: MutPtr<U>) -> Self {
139        StaticUpcast::static_upcast_mut(value)
140    }
141}
142
143impl<T, U> CastFrom<Ref<U>> for Ref<T>
144where
145    U: StaticUpcast<T>,
146{
147    unsafe fn cast_from(value: Ref<U>) -> Self {
148        StaticUpcast::static_upcast(value.as_ptr())
149            .as_ref()
150            .expect("StaticUpcast returned null on Ref input")
151    }
152}
153
154impl<T, U> CastFrom<MutRef<U>> for MutRef<T>
155where
156    U: StaticUpcast<T>,
157{
158    unsafe fn cast_from(value: MutRef<U>) -> Self {
159        StaticUpcast::static_upcast_mut(value.as_mut_ptr())
160            .as_mut_ref()
161            .expect("StaticUpcast returned null on Ref input")
162    }
163}
164
165impl<T> CastFrom<NullPtr> for Ptr<T> {
166    unsafe fn cast_from(_value: NullPtr) -> Self {
167        Self::null()
168    }
169}
170
171impl<T> CastFrom<NullPtr> for MutPtr<T> {
172    unsafe fn cast_from(_value: NullPtr) -> Self {
173        Self::null()
174    }
175}
176
177impl<'a> CastFrom<&'a CStr> for MutPtr<c_char> {
178    unsafe fn cast_from(value: &'a CStr) -> Self {
179        MutPtr::from_c_str(value)
180    }
181}
182
183impl<'a> CastFrom<&'a CStr> for Ptr<c_char> {
184    unsafe fn cast_from(value: &'a CStr) -> Self {
185        Ptr::from_c_str(value)
186    }
187}
188
189impl<T, U> CastFrom<*const U> for Ptr<T>
190where
191    U: StaticUpcast<T>,
192{
193    unsafe fn cast_from(value: *const U) -> Self {
194        Self::cast_from(Ptr::from_raw(value))
195    }
196}
197
198impl<T, U> CastFrom<*mut U> for Ptr<T>
199where
200    U: StaticUpcast<T>,
201{
202    unsafe fn cast_from(value: *mut U) -> Self {
203        Self::cast_from(Ptr::from_raw(value as *const U))
204    }
205}
206
207impl<T, U> CastFrom<*mut U> for MutPtr<T>
208where
209    U: StaticUpcast<T>,
210{
211    unsafe fn cast_from(value: *mut U) -> Self {
212        Self::cast_from(MutPtr::from_raw(value))
213    }
214}