Skip to content

Commit f0ba8b8

Browse files
committed
make try_convert module public so TryConvertOwned can be named
1 parent 8f5e30d commit f0ba8b8

File tree

6 files changed

+56
-69
lines changed

6 files changed

+56
-69
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
### Added
55

66
### Changed
7+
- `try_convert` module is now public so that `TryConvertOwned` can be
8+
named/implemented.
79

810
### Deprecated
911

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1860,7 +1860,7 @@ pub mod rb_sys;
18601860
pub mod ruby_handle;
18611861
pub mod scan_args;
18621862
mod symbol;
1863-
mod try_convert;
1863+
pub mod try_convert;
18641864
pub mod typed_data;
18651865
pub mod value;
18661866

src/r_array.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -802,12 +802,7 @@ impl RArray {
802802
where
803803
T: TryConvertOwned,
804804
{
805-
unsafe {
806-
self.as_slice()
807-
.iter()
808-
.map(|v| T::try_convert_owned(*v))
809-
.collect()
810-
}
805+
unsafe { self.as_slice().iter().map(|v| T::try_convert(*v)).collect() }
811806
}
812807

813808
/// Convert `self` to a Rust array of [`Value`]s, of length `N`.

src/try_convert.rs

+46-56
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Traits for converting from Ruby [`Value`]s to Rust types.
2+
13
use std::path::PathBuf;
24

35
use rb_sys::{rb_get_path, rb_num2dbl};
@@ -20,20 +22,16 @@ pub trait TryConvert: Sized {
2022
fn try_convert(val: Value) -> Result<Self, Error>;
2123
}
2224

23-
/// Only implemented on Rust types. TryConvert may convert from a
24-
/// Value to another Ruby type. Use this when you need a Rust value that's
25-
/// divorced from the Ruby runtime, safe to put on the heap, etc.
26-
pub trait TryConvertOwned: TryConvert {
27-
/// Convert `val` into `Self`.
28-
fn try_convert_owned(val: Value) -> Result<Self, Error> {
29-
Self::try_convert(val)
30-
}
31-
}
32-
33-
pub trait TryConvertForArg: Sized {
34-
/// Convert `val` into `Self`.
35-
fn try_convert_for_arg(val: Value) -> Result<Self, Error>;
36-
}
25+
/// Conversions from [`Value`] to Rust types that do not contain [`Value`].
26+
///
27+
/// This trait is used as a bound on some implementations of [`TryConvert`]
28+
/// (for example, for [`Vec`]) to prevent heap allocated datastructures
29+
/// containing `Value`, as it is not safe to store a `Value` on the heap.
30+
///
31+
/// # Safety
32+
///
33+
/// This trait must not be implemented for types that contain `Value`.
34+
pub unsafe trait TryConvertOwned: TryConvert {}
3735

3836
impl<T> TryConvert for Option<T>
3937
where
@@ -44,100 +42,91 @@ where
4442
}
4543
}
4644

47-
impl<T> TryConvertOwned for Option<T>
48-
where
49-
T: TryConvertOwned,
50-
{
51-
fn try_convert_owned(val: Value) -> Result<Self, Error> {
52-
(!val.is_nil())
53-
.then(|| T::try_convert_owned(val))
54-
.transpose()
55-
}
56-
}
45+
unsafe impl<T> TryConvertOwned for Option<T> where T: TryConvertOwned {}
5746

5847
impl TryConvert for bool {
5948
fn try_convert(val: Value) -> Result<Self, Error> {
6049
Ok(val.to_bool())
6150
}
6251
}
63-
impl TryConvertOwned for bool {}
52+
unsafe impl TryConvertOwned for bool {}
6453

6554
impl TryConvert for i8 {
6655
fn try_convert(val: Value) -> Result<Self, Error> {
6756
Integer::try_convert(val)?.to_i8()
6857
}
6958
}
70-
impl TryConvertOwned for i8 {}
59+
unsafe impl TryConvertOwned for i8 {}
7160

7261
impl TryConvert for i16 {
7362
fn try_convert(val: Value) -> Result<Self, Error> {
7463
Integer::try_convert(val)?.to_i16()
7564
}
7665
}
77-
impl TryConvertOwned for i16 {}
66+
unsafe impl TryConvertOwned for i16 {}
7867

7968
impl TryConvert for i32 {
8069
fn try_convert(val: Value) -> Result<Self, Error> {
8170
Integer::try_convert(val)?.to_i32()
8271
}
8372
}
84-
impl TryConvertOwned for i32 {}
73+
unsafe impl TryConvertOwned for i32 {}
8574

8675
impl TryConvert for i64 {
8776
fn try_convert(val: Value) -> Result<Self, Error> {
8877
Integer::try_convert(val)?.to_i64()
8978
}
9079
}
91-
impl TryConvertOwned for i64 {}
80+
unsafe impl TryConvertOwned for i64 {}
9281

9382
impl TryConvert for isize {
9483
fn try_convert(val: Value) -> Result<Self, Error> {
9584
Integer::try_convert(val)?.to_isize()
9685
}
9786
}
98-
impl TryConvertOwned for isize {}
87+
unsafe impl TryConvertOwned for isize {}
9988

10089
impl TryConvert for u8 {
10190
fn try_convert(val: Value) -> Result<Self, Error> {
10291
Integer::try_convert(val)?.to_u8()
10392
}
10493
}
105-
impl TryConvertOwned for u8 {}
94+
unsafe impl TryConvertOwned for u8 {}
10695

10796
impl TryConvert for u16 {
10897
fn try_convert(val: Value) -> Result<Self, Error> {
10998
Integer::try_convert(val)?.to_u16()
11099
}
111100
}
112-
impl TryConvertOwned for u16 {}
101+
unsafe impl TryConvertOwned for u16 {}
113102

114103
impl TryConvert for u32 {
115104
fn try_convert(val: Value) -> Result<Self, Error> {
116105
Integer::try_convert(val)?.to_u32()
117106
}
118107
}
119-
impl TryConvertOwned for u32 {}
108+
unsafe impl TryConvertOwned for u32 {}
120109

121110
impl TryConvert for u64 {
122111
fn try_convert(val: Value) -> Result<Self, Error> {
123112
Integer::try_convert(val)?.to_u64()
124113
}
125114
}
126-
impl TryConvertOwned for u64 {}
115+
unsafe impl TryConvertOwned for u64 {}
127116

128117
impl TryConvert for usize {
129118
fn try_convert(val: Value) -> Result<Self, Error> {
130119
Integer::try_convert(val)?.to_usize()
131120
}
132121
}
133-
impl TryConvertOwned for usize {}
122+
unsafe impl TryConvertOwned for usize {}
134123

135124
impl TryConvert for f32 {
136125
fn try_convert(val: Value) -> Result<Self, Error> {
137126
f64::try_convert(val).map(|f| f as f32)
138127
}
139128
}
140-
impl TryConvertOwned for f32 {}
129+
unsafe impl TryConvertOwned for f32 {}
141130

142131
impl TryConvert for f64 {
143132
fn try_convert(val: Value) -> Result<Self, Error> {
@@ -157,15 +146,15 @@ impl TryConvert for f64 {
157146
Ok(res)
158147
}
159148
}
160-
impl TryConvertOwned for f64 {}
149+
unsafe impl TryConvertOwned for f64 {}
161150

162151
impl TryConvert for String {
163152
fn try_convert(val: Value) -> Result<Self, Error> {
164153
debug_assert_value!(val);
165154
RString::try_convert(val)?.to_string()
166155
}
167156
}
168-
impl TryConvertOwned for String {}
157+
unsafe impl TryConvertOwned for String {}
169158

170159
#[cfg(feature = "bytes-crate")]
171160
impl TryConvert for bytes::Bytes {
@@ -176,15 +165,15 @@ impl TryConvert for bytes::Bytes {
176165
}
177166

178167
#[cfg(feature = "bytes-crate")]
179-
impl TryConvertOwned for bytes::Bytes {}
168+
unsafe impl TryConvertOwned for bytes::Bytes {}
180169

181170
impl TryConvert for char {
182171
fn try_convert(val: Value) -> Result<Self, Error> {
183172
debug_assert_value!(val);
184173
RString::try_convert(val)?.to_char()
185174
}
186175
}
187-
impl TryConvertOwned for char {}
176+
unsafe impl TryConvertOwned for char {}
188177

189178
impl<T> TryConvert for Vec<T>
190179
where
@@ -195,7 +184,7 @@ where
195184
RArray::try_convert(val)?.to_vec()
196185
}
197186
}
198-
impl<T> TryConvertOwned for Vec<T> where T: TryConvertOwned {}
187+
unsafe impl<T> TryConvertOwned for Vec<T> where T: TryConvertOwned {}
199188

200189
impl<T, const N: usize> TryConvert for [T; N]
201190
where
@@ -206,7 +195,7 @@ where
206195
RArray::try_convert(val)?.to_array()
207196
}
208197
}
209-
impl<T, const N: usize> TryConvertOwned for [T; N] where T: TryConvert {}
198+
unsafe impl<T, const N: usize> TryConvertOwned for [T; N] where T: TryConvert {}
210199

211200
impl<T0> TryConvert for (T0,)
212201
where
@@ -225,7 +214,7 @@ where
225214
Ok((slice[0].try_convert()?,))
226215
}
227216
}
228-
impl<T0> TryConvertOwned for (T0,) where T0: TryConvert {}
217+
unsafe impl<T0> TryConvertOwned for (T0,) where T0: TryConvert {}
229218

230219
impl<T0, T1> TryConvert for (T0, T1)
231220
where
@@ -245,7 +234,7 @@ where
245234
Ok((slice[0].try_convert()?, slice[1].try_convert()?))
246235
}
247236
}
248-
impl<T0, T1> TryConvertOwned for (T0, T1)
237+
unsafe impl<T0, T1> TryConvertOwned for (T0, T1)
249238
where
250239
T0: TryConvert,
251240
T1: TryConvert,
@@ -275,7 +264,7 @@ where
275264
))
276265
}
277266
}
278-
impl<T0, T1, T2> TryConvertOwned for (T0, T1, T2)
267+
unsafe impl<T0, T1, T2> TryConvertOwned for (T0, T1, T2)
279268
where
280269
T0: TryConvert,
281270
T1: TryConvert,
@@ -308,7 +297,7 @@ where
308297
))
309298
}
310299
}
311-
impl<T0, T1, T2, T3> TryConvertOwned for (T0, T1, T2, T3)
300+
unsafe impl<T0, T1, T2, T3> TryConvertOwned for (T0, T1, T2, T3)
312301
where
313302
T0: TryConvert,
314303
T1: TryConvert,
@@ -344,7 +333,7 @@ where
344333
))
345334
}
346335
}
347-
impl<T0, T1, T2, T3, T4> TryConvertOwned for (T0, T1, T2, T3, T4)
336+
unsafe impl<T0, T1, T2, T3, T4> TryConvertOwned for (T0, T1, T2, T3, T4)
348337
where
349338
T0: TryConvert,
350339
T1: TryConvert,
@@ -383,7 +372,7 @@ where
383372
))
384373
}
385374
}
386-
impl<T0, T1, T2, T3, T4, T5> TryConvertOwned for (T0, T1, T2, T3, T4, T5)
375+
unsafe impl<T0, T1, T2, T3, T4, T5> TryConvertOwned for (T0, T1, T2, T3, T4, T5)
387376
where
388377
T0: TryConvert,
389378
T1: TryConvert,
@@ -425,7 +414,7 @@ where
425414
))
426415
}
427416
}
428-
impl<T0, T1, T2, T3, T4, T5, T6> TryConvertOwned for (T0, T1, T2, T3, T4, T5, T6)
417+
unsafe impl<T0, T1, T2, T3, T4, T5, T6> TryConvertOwned for (T0, T1, T2, T3, T4, T5, T6)
429418
where
430419
T0: TryConvert,
431420
T1: TryConvert,
@@ -470,7 +459,7 @@ where
470459
))
471460
}
472461
}
473-
impl<T0, T1, T2, T3, T4, T5, T6, T7> TryConvertOwned for (T0, T1, T2, T3, T4, T5, T6, T7)
462+
unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7> TryConvertOwned for (T0, T1, T2, T3, T4, T5, T6, T7)
474463
where
475464
T0: TryConvert,
476465
T1: TryConvert,
@@ -518,7 +507,8 @@ where
518507
))
519508
}
520509
}
521-
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> TryConvertOwned for (T0, T1, T2, T3, T4, T5, T6, T7, T8)
510+
unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> TryConvertOwned
511+
for (T0, T1, T2, T3, T4, T5, T6, T7, T8)
522512
where
523513
T0: TryConvert,
524514
T1: TryConvert,
@@ -569,7 +559,7 @@ where
569559
))
570560
}
571561
}
572-
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> TryConvertOwned
562+
unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> TryConvertOwned
573563
for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)
574564
where
575565
T0: TryConvert,
@@ -625,7 +615,7 @@ where
625615
))
626616
}
627617
}
628-
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> TryConvertOwned
618+
unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> TryConvertOwned
629619
for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
630620
where
631621
T0: TryConvert,
@@ -684,7 +674,7 @@ where
684674
))
685675
}
686676
}
687-
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> TryConvertOwned
677+
unsafe impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> TryConvertOwned
688678
for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
689679
where
690680
T0: TryConvert,
@@ -712,7 +702,7 @@ where
712702
RHash::try_convert(val)?.to_hash_map()
713703
}
714704
}
715-
impl<K, V> TryConvertOwned for std::collections::HashMap<K, V>
705+
unsafe impl<K, V> TryConvertOwned for std::collections::HashMap<K, V>
716706
where
717707
K: TryConvertOwned + Eq + std::hash::Hash,
718708
V: TryConvertOwned,
@@ -742,4 +732,4 @@ impl TryConvert for PathBuf {
742732
}
743733
}
744734

745-
impl TryConvertOwned for PathBuf {}
735+
unsafe impl TryConvertOwned for PathBuf {}

0 commit comments

Comments
 (0)