• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

facet-rs / facet / 15222427616

24 May 2025 02:17AM UTC coverage: 57.627% (-0.02%) from 57.643%
15222427616

Pull #673

github

web-flow
Merge 484c5ddbc into 950e6a37a
Pull Request #673: Add `Shape.type_identifier` to access type name in const contexts

55 of 103 new or added lines in 23 files covered. (53.4%)

4 existing lines in 3 files now uncovered.

9909 of 17195 relevant lines covered (57.63%)

137.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

14.56
/facet-core/src/impls_ordered_float.rs
1
use crate::{
2
    Def, Facet, PtrConst, PtrMut, PtrUninit, Repr, ScalarAffinity, ScalarDef, Shape, StructType,
3
    TryBorrowInnerError, TryFromError, TryIntoInnerError, Type, UserType, ValueVTable,
4
    field_in_type, value_vtable,
5
};
6
use ordered_float::{NotNan, OrderedFloat};
7

8
macro_rules! impl_facet_for_ordered_float_and_notnan {
9
    ($float:ty) => {
10
        unsafe impl<'a> Facet<'a> for OrderedFloat<$float> {
11
            const VTABLE: &'static ValueVTable = &const {
12
                // Define conversion functions for transparency
13
                unsafe fn try_from<'shape, 'dst>(
1✔
14
                    src_ptr: PtrConst<'_>,
1✔
15
                    src_shape: &'shape Shape<'shape>,
1✔
16
                    dst: PtrUninit<'dst>,
1✔
17
                ) -> Result<PtrMut<'dst>, TryFromError<'shape>> {
1✔
18
                    if src_shape == <$float as Facet>::SHAPE {
1✔
19
                        // Get the inner value and wrap as OrderedFloat
20
                        let value = unsafe { src_ptr.get::<$float>() };
1✔
21
                        let ord = OrderedFloat(*value);
1✔
22
                        Ok(unsafe { dst.put(ord) })
1✔
23
                    } else {
24
                        let inner_try_from = (<$float as Facet>::SHAPE.vtable.try_from)().ok_or(
×
25
                            TryFromError::UnsupportedSourceShape {
×
26
                                src_shape,
×
27
                                expected: &[<$float as Facet>::SHAPE],
×
28
                            },
×
29
                        )?;
×
30
                        // fallback to inner's try_from
31
                        // This relies on the fact that `dst` is the same size as `OrderedFloat<$float>`
32
                        // which should be true because `OrderedFloat` is `repr(transparent)`
33
                        let inner_result = unsafe { (inner_try_from)(src_ptr, src_shape, dst) };
×
34
                        match inner_result {
×
35
                            Ok(result) => {
×
36
                                // After conversion to inner type, wrap as OrderedFloat
37
                                let value = unsafe { result.read::<$float>() };
×
38
                                let ord = OrderedFloat(value);
×
39
                                Ok(unsafe { dst.put(ord) })
×
40
                            }
41
                            Err(e) => Err(e),
×
42
                        }
43
                    }
44
                }
1✔
45

46
                // Conversion back to inner float type
47
                unsafe fn try_into_inner<'dst>(
×
48
                    src_ptr: PtrMut<'_>,
×
49
                    dst: PtrUninit<'dst>,
×
50
                ) -> Result<PtrMut<'dst>, TryIntoInnerError> {
×
51
                    let v = unsafe { src_ptr.read::<OrderedFloat<$float>>() };
×
52
                    Ok(unsafe { dst.put(v.0) })
×
53
                }
×
54

55
                // Borrow inner float type
56
                unsafe fn try_borrow_inner(
×
57
                    src_ptr: PtrConst<'_>,
×
58
                ) -> Result<PtrConst<'_>, TryBorrowInnerError> {
×
59
                    let v = unsafe { src_ptr.get::<OrderedFloat<$float>>() };
×
60
                    Ok(PtrConst::new((&v.0) as *const $float as *const u8))
×
61
                }
×
62

63
                let mut vtable =
64
                    value_vtable!((), |f, _opts| write!(f, "{}", Self::SHAPE.type_identifier));
3✔
UNCOV
65
                vtable.parse = || {
×
66
                    // `OrderedFloat` is `repr(transparent)`
67
                    (<$float as Facet>::SHAPE.vtable.parse)()
×
68
                };
×
69
                vtable.try_from = || Some(try_from);
1✔
70
                vtable.try_into_inner = || Some(try_into_inner);
×
71
                vtable.try_borrow_inner = || Some(try_borrow_inner);
×
72
                vtable
73
            };
74

75
            const SHAPE: &'static Shape<'static> = &const {
76
                fn inner_shape() -> &'static Shape<'static> {
3✔
77
                    <$float as Facet>::SHAPE
3✔
78
                }
3✔
79

80
                Shape::builder_for_sized::<Self>()
81
                    .type_identifier("OrderedFloat")
82
                    .ty(Type::User(UserType::Struct(
83
                        StructType::builder()
84
                            .repr(Repr::transparent())
85
                            .fields(&const { [field_in_type!(Self, 0)] })
86
                            .kind(crate::StructKind::Tuple)
87
                            .build(),
88
                    )))
89
                    .def(Def::Scalar(
90
                        ScalarDef::builder()
91
                            // Affinity: use number affinity as inner's
92
                            .affinity(&const { ScalarAffinity::opaque().build() })
93
                            .build(),
94
                    ))
95
                    .inner(inner_shape)
96
                    .build()
97
            };
98
        }
99

100
        unsafe impl<'a> Facet<'a> for NotNan<$float> {
101
            const VTABLE: &'static ValueVTable = &const {
102
                // Conversion from inner float type to NotNan<$float>
103
                unsafe fn try_from<'shape, 'dst>(
×
104
                    src_ptr: PtrConst<'_>,
×
105
                    src_shape: &'shape Shape<'shape>,
×
106
                    dst: PtrUninit<'dst>,
×
107
                ) -> Result<PtrMut<'dst>, TryFromError<'shape>> {
×
108
                    if src_shape == <$float as Facet>::SHAPE {
×
109
                        // Get the inner value and check that it's not NaN
110
                        let value = unsafe { *src_ptr.get::<$float>() };
×
111
                        let nn =
×
112
                            NotNan::new(value).map_err(|_| TryFromError::Generic("was NaN"))?;
×
113
                        Ok(unsafe { dst.put(nn) })
×
114
                    } else {
115
                        let inner_try_from = (<$float as Facet>::SHAPE.vtable.try_from)().ok_or(
×
116
                            TryFromError::UnsupportedSourceShape {
×
117
                                src_shape,
×
118
                                expected: &[<$float as Facet>::SHAPE],
×
119
                            },
×
120
                        )?;
×
121

122
                        // fallback to inner's try_from
123
                        // This relies on the fact that `dst` is the same size as `NotNan<$float>`
124
                        // which should be true because `NotNan` is `repr(transparent)`
125
                        let inner_result = unsafe { (inner_try_from)(src_ptr, src_shape, dst) };
×
126
                        match inner_result {
×
127
                            Ok(result) => {
×
128
                                // After conversion to inner type, wrap as NotNan
129
                                let value = unsafe { *result.get::<$float>() };
×
130
                                let nn = NotNan::new(value)
×
131
                                    .map_err(|_| TryFromError::Generic("was NaN"))?;
×
132
                                Ok(unsafe { dst.put(nn) })
×
133
                            }
134
                            Err(e) => Err(e),
×
135
                        }
136
                    }
137
                }
×
138

139
                // Conversion back to inner float type
140
                unsafe fn try_into_inner<'dst>(
×
141
                    src_ptr: PtrMut<'_>,
×
142
                    dst: PtrUninit<'dst>,
×
143
                ) -> Result<PtrMut<'dst>, TryIntoInnerError> {
×
144
                    let v = unsafe { src_ptr.read::<NotNan<$float>>() };
×
145
                    Ok(unsafe { dst.put(v.into_inner()) })
×
146
                }
×
147

148
                // Borrow inner float type
149
                unsafe fn try_borrow_inner(
×
150
                    src_ptr: PtrConst<'_>,
×
151
                ) -> Result<PtrConst<'_>, TryBorrowInnerError> {
×
152
                    let v = unsafe { src_ptr.get::<NotNan<$float>>() };
×
153
                    Ok(PtrConst::new(
×
154
                        (&v.into_inner()) as *const $float as *const u8,
×
155
                    ))
×
156
                }
×
157

158
                let mut vtable =
NEW
159
                    value_vtable!((), |f, _opts| write!(f, "{}", Self::SHAPE.type_identifier));
×
160
                // Accept parsing as inner T, but enforce NotNan invariant
161
                vtable.parse = || {
×
162
                    Some(|s, target| match s.parse::<$float>() {
×
163
                        Ok(inner) => match NotNan::new(inner) {
×
164
                            Ok(not_nan) => Ok(unsafe { target.put(not_nan) }),
×
165
                            Err(_) => {
166
                                Err(crate::ParseError::Generic("NaN is not allowed for NotNan"))
×
167
                            }
168
                        },
169
                        Err(_) => Err(crate::ParseError::Generic(
×
170
                            "Failed to parse inner type for NotNan",
×
171
                        )),
×
172
                    })
×
173
                };
×
174
                vtable.try_from = || Some(try_from);
×
175
                vtable.try_into_inner = || Some(try_into_inner);
×
176
                vtable.try_borrow_inner = || Some(try_borrow_inner);
×
177
                vtable
178
            };
179

180
            const SHAPE: &'static Shape<'static> = &const {
181
                fn inner_shape() -> &'static Shape<'static> {
×
182
                    <$float as Facet>::SHAPE
×
183
                }
×
184

185
                Shape::builder_for_sized::<Self>()
186
                    .type_identifier("NotNan")
187
                    .ty(Type::User(UserType::Opaque))
188
                    .def(Def::Scalar(
189
                        ScalarDef::builder()
190
                            .affinity(&const { ScalarAffinity::opaque().build() })
191
                            .build(),
192
                    ))
193
                    .inner(inner_shape)
194
                    .build()
195
            };
196
        }
197
    };
198
}
199

200
impl_facet_for_ordered_float_and_notnan!(f32);
201
impl_facet_for_ordered_float_and_notnan!(f64);
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc