11
11
12
12
//! Adapters for alternative string formats.
13
13
14
- use core:: str:: FromStr ;
14
+ use core:: { convert :: TryInto as _ , str:: FromStr } ;
15
15
16
16
use crate :: {
17
- std:: { borrow:: Borrow , fmt, ptr , str} ,
17
+ std:: { borrow:: Borrow , fmt, str} ,
18
18
Error , Uuid , Variant ,
19
19
} ;
20
20
@@ -67,25 +67,105 @@ impl fmt::UpperHex for Uuid {
67
67
68
68
/// Format a [`Uuid`] as a hyphenated string, like
69
69
/// `67e55044-10b1-426f-9247-bb680e5fe0c8`.
70
- #[ derive( Clone , Copy , Debug , Default , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
70
+ #[ derive(
71
+ Clone ,
72
+ Copy ,
73
+ Debug ,
74
+ Default ,
75
+ Eq ,
76
+ Hash ,
77
+ Ord ,
78
+ PartialEq ,
79
+ PartialOrd ,
80
+ ) ]
81
+ #[ cfg_attr(
82
+ all( uuid_unstable, feature = "zerocopy" ) ,
83
+ derive(
84
+ zerocopy:: IntoBytes ,
85
+ zerocopy:: FromBytes ,
86
+ zerocopy:: KnownLayout ,
87
+ zerocopy:: Immutable ,
88
+ zerocopy:: Unaligned
89
+ )
90
+ ) ]
71
91
#[ repr( transparent) ]
72
92
pub struct Hyphenated ( Uuid ) ;
73
93
74
94
/// Format a [`Uuid`] as a simple string, like
75
95
/// `67e5504410b1426f9247bb680e5fe0c8`.
76
- #[ derive( Clone , Copy , Debug , Default , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
96
+ #[ derive(
97
+ Clone ,
98
+ Copy ,
99
+ Debug ,
100
+ Default ,
101
+ Eq ,
102
+ Hash ,
103
+ Ord ,
104
+ PartialEq ,
105
+ PartialOrd ,
106
+ ) ]
107
+ #[ cfg_attr(
108
+ all( uuid_unstable, feature = "zerocopy" ) ,
109
+ derive(
110
+ zerocopy:: IntoBytes ,
111
+ zerocopy:: FromBytes ,
112
+ zerocopy:: KnownLayout ,
113
+ zerocopy:: Immutable ,
114
+ zerocopy:: Unaligned
115
+ )
116
+ ) ]
77
117
#[ repr( transparent) ]
78
118
pub struct Simple ( Uuid ) ;
79
119
80
120
/// Format a [`Uuid`] as a URN string, like
81
121
/// `urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8`.
82
- #[ derive( Clone , Copy , Debug , Default , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
122
+ #[ derive(
123
+ Clone ,
124
+ Copy ,
125
+ Debug ,
126
+ Default ,
127
+ Eq ,
128
+ Hash ,
129
+ Ord ,
130
+ PartialEq ,
131
+ PartialOrd ,
132
+ ) ]
133
+ #[ cfg_attr(
134
+ all( uuid_unstable, feature = "zerocopy" ) ,
135
+ derive(
136
+ zerocopy:: IntoBytes ,
137
+ zerocopy:: FromBytes ,
138
+ zerocopy:: KnownLayout ,
139
+ zerocopy:: Immutable ,
140
+ zerocopy:: Unaligned
141
+ )
142
+ ) ]
83
143
#[ repr( transparent) ]
84
144
pub struct Urn ( Uuid ) ;
85
145
86
146
/// Format a [`Uuid`] as a braced hyphenated string, like
87
147
/// `{67e55044-10b1-426f-9247-bb680e5fe0c8}`.
88
- #[ derive( Clone , Copy , Debug , Default , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
148
+ #[ derive(
149
+ Clone ,
150
+ Copy ,
151
+ Debug ,
152
+ Default ,
153
+ Eq ,
154
+ Hash ,
155
+ Ord ,
156
+ PartialEq ,
157
+ PartialOrd ,
158
+ ) ]
159
+ #[ cfg_attr(
160
+ all( uuid_unstable, feature = "zerocopy" ) ,
161
+ derive(
162
+ zerocopy:: IntoBytes ,
163
+ zerocopy:: FromBytes ,
164
+ zerocopy:: KnownLayout ,
165
+ zerocopy:: Immutable ,
166
+ zerocopy:: Unaligned
167
+ )
168
+ ) ]
89
169
#[ repr( transparent) ]
90
170
pub struct Braced ( Uuid ) ;
91
171
@@ -99,8 +179,7 @@ impl Uuid {
99
179
/// Get a borrowed [`Hyphenated`] formatter.
100
180
#[ inline]
101
181
pub fn as_hyphenated ( & self ) -> & Hyphenated {
102
- // SAFETY: `Uuid` and `Hyphenated` have the same ABI
103
- unsafe { & * ( self as * const Uuid as * const Hyphenated ) }
182
+ unsafe_transmute_ref ! ( self )
104
183
}
105
184
106
185
/// Get a [`Simple`] formatter.
@@ -112,8 +191,7 @@ impl Uuid {
112
191
/// Get a borrowed [`Simple`] formatter.
113
192
#[ inline]
114
193
pub fn as_simple ( & self ) -> & Simple {
115
- // SAFETY: `Uuid` and `Simple` have the same ABI
116
- unsafe { & * ( self as * const Uuid as * const Simple ) }
194
+ unsafe_transmute_ref ! ( self )
117
195
}
118
196
119
197
/// Get a [`Urn`] formatter.
@@ -125,8 +203,7 @@ impl Uuid {
125
203
/// Get a borrowed [`Urn`] formatter.
126
204
#[ inline]
127
205
pub fn as_urn ( & self ) -> & Urn {
128
- // SAFETY: `Uuid` and `Urn` have the same ABI
129
- unsafe { & * ( self as * const Uuid as * const Urn ) }
206
+ unsafe_transmute_ref ! ( self )
130
207
}
131
208
132
209
/// Get a [`Braced`] formatter.
@@ -138,8 +215,7 @@ impl Uuid {
138
215
/// Get a borrowed [`Braced`] formatter.
139
216
#[ inline]
140
217
pub fn as_braced ( & self ) -> & Braced {
141
- // SAFETY: `Uuid` and `Braced` have the same ABI
142
- unsafe { & * ( self as * const Uuid as * const Braced ) }
218
+ unsafe_transmute_ref ! ( self )
143
219
}
144
220
}
145
221
@@ -194,58 +270,62 @@ const fn format_hyphenated(src: &[u8; 16], upper: bool) -> [u8; 36] {
194
270
#[ inline]
195
271
fn encode_simple < ' b > ( src : & [ u8 ; 16 ] , buffer : & ' b mut [ u8 ] , upper : bool ) -> & ' b mut str {
196
272
let buf = & mut buffer[ ..Simple :: LENGTH ] ;
197
- let dst = buf. as_mut_ptr ( ) ;
273
+ let buf: & mut [ u8 ; Simple :: LENGTH ] = buf. try_into ( ) . unwrap ( ) ;
274
+ * buf = format_simple ( src, upper) ;
198
275
199
- // SAFETY: `buf` is guaranteed to be at least `LEN` bytes
200
276
// SAFETY: The encoded buffer is ASCII encoded
201
- unsafe {
202
- ptr:: write ( dst. cast ( ) , format_simple ( src, upper) ) ;
203
- str:: from_utf8_unchecked_mut ( buf)
204
- }
277
+ unsafe { str:: from_utf8_unchecked_mut ( buf) }
205
278
}
206
279
207
280
#[ inline]
208
281
fn encode_hyphenated < ' b > ( src : & [ u8 ; 16 ] , buffer : & ' b mut [ u8 ] , upper : bool ) -> & ' b mut str {
209
282
let buf = & mut buffer[ ..Hyphenated :: LENGTH ] ;
210
- let dst = buf. as_mut_ptr ( ) ;
283
+ let buf: & mut [ u8 ; Hyphenated :: LENGTH ] = buf. try_into ( ) . unwrap ( ) ;
284
+ * buf = format_hyphenated ( src, upper) ;
211
285
212
- // SAFETY: `buf` is guaranteed to be at least `LEN` bytes
213
286
// SAFETY: The encoded buffer is ASCII encoded
214
- unsafe {
215
- ptr:: write ( dst. cast ( ) , format_hyphenated ( src, upper) ) ;
216
- str:: from_utf8_unchecked_mut ( buf)
217
- }
287
+ unsafe { str:: from_utf8_unchecked_mut ( buf) }
218
288
}
219
289
220
290
#[ inline]
221
291
fn encode_braced < ' b > ( src : & [ u8 ; 16 ] , buffer : & ' b mut [ u8 ] , upper : bool ) -> & ' b mut str {
222
- let buf = & mut buffer[ ..Braced :: LENGTH ] ;
223
- buf[ 0 ] = b'{' ;
224
- buf[ Braced :: LENGTH - 1 ] = b'}' ;
292
+ let buf = & mut buffer[ ..Hyphenated :: LENGTH + 2 ] ;
293
+ let buf: & mut [ u8 ; Hyphenated :: LENGTH + 2 ] = buf. try_into ( ) . unwrap ( ) ;
294
+
295
+ #[ cfg_attr(
296
+ all( uuid_unstable, feature = "zerocopy" ) ,
297
+ derive( zerocopy:: IntoBytes )
298
+ ) ]
299
+ #[ repr( C ) ]
300
+ struct Braced {
301
+ open_curly : u8 ,
302
+ hyphenated : [ u8 ; Hyphenated :: LENGTH ] ,
303
+ close_curly : u8 ,
304
+ }
225
305
226
- // SAFETY: `buf` is guaranteed to be at least `LEN` bytes
227
- // SAFETY: The encoded buffer is ASCII encoded
228
- unsafe {
229
- let dst = buf. as_mut_ptr ( ) . add ( 1 ) ;
306
+ let braced = Braced {
307
+ open_curly : b'{' ,
308
+ hyphenated : format_hyphenated ( src, upper) ,
309
+ close_curly : b'}' ,
310
+ } ;
230
311
231
- ptr:: write ( dst. cast ( ) , format_hyphenated ( src, upper) ) ;
232
- str:: from_utf8_unchecked_mut ( buf)
233
- }
312
+ * buf = unsafe_transmute ! ( braced) ;
313
+
314
+ // SAFETY: The encoded buffer is ASCII encoded
315
+ unsafe { str:: from_utf8_unchecked_mut ( buf) }
234
316
}
235
317
236
318
#[ inline]
237
319
fn encode_urn < ' b > ( src : & [ u8 ; 16 ] , buffer : & ' b mut [ u8 ] , upper : bool ) -> & ' b mut str {
238
320
let buf = & mut buffer[ ..Urn :: LENGTH ] ;
239
321
buf[ ..9 ] . copy_from_slice ( b"urn:uuid:" ) ;
240
322
241
- // SAFETY: `buf` is guaranteed to be at least `LEN` bytes
242
- // SAFETY: The encoded buffer is ASCII encoded
243
- unsafe {
244
- let dst = buf. as_mut_ptr ( ) . add ( 9 ) ;
323
+ let dst = & mut buf[ 9 ..( 9 + Hyphenated :: LENGTH ) ] ;
324
+ let dst: & mut [ u8 ; Hyphenated :: LENGTH ] = dst. try_into ( ) . unwrap ( ) ;
325
+ * dst = format_hyphenated ( src, upper) ;
245
326
246
- ptr:: write ( dst. cast ( ) , format_hyphenated ( src, upper) ) ;
247
- str:: from_utf8_unchecked_mut ( buf)
248
- }
327
+ // SAFETY: The encoded buffer is ASCII encoded
328
+ unsafe { str:: from_utf8_unchecked_mut ( buf) }
249
329
}
250
330
251
331
impl Hyphenated {
0 commit comments