@@ -9,7 +9,7 @@ use core::{
9
9
#[ cfg( feature = "serde" ) ]
10
10
use serde:: { de:: Error as ErrorUtil , Deserialize , Deserializer , Serialize , Serializer } ;
11
11
12
- use crate :: errors:: Error ;
12
+ use crate :: { constants :: RESERVED_SPACES , errors:: Error } ;
13
13
14
14
pub const MAX_LABEL_LEN : usize = 62 ;
15
15
pub const PUNYCODE_PREFIX : & [ u8 ] = b"xn--" ;
@@ -188,6 +188,32 @@ impl<'a> TryFrom<&'a [u8]> for SLabelRef<'a> {
188
188
}
189
189
}
190
190
191
+ impl SLabel {
192
+ pub fn as_str_unprefixed ( & self ) -> Result < & str , core:: str:: Utf8Error > {
193
+ let label_len = self . 0 [ 0 ] as usize ;
194
+ let label = & self . 0 [ 1 ..=label_len] ;
195
+ core:: str:: from_utf8 ( label)
196
+ }
197
+
198
+ pub fn to_string_unprefixed ( & self ) -> Result < String , core:: str:: Utf8Error > {
199
+ self . as_str_unprefixed ( ) . map ( |s| s. to_string ( ) )
200
+ }
201
+
202
+ pub fn from_str_unprefixed ( label : & str ) -> Result < Self , Error > {
203
+ if label. is_empty ( ) {
204
+ return Err ( Error :: Name ( NameErrorKind :: ZeroLength ) ) ;
205
+ }
206
+ if label. len ( ) > MAX_LABEL_LEN {
207
+ return Err ( Error :: Name ( NameErrorKind :: TooLong ) ) ;
208
+ }
209
+ let mut label_bytes = [ 0 ; MAX_LABEL_LEN + 1 ] ;
210
+ label_bytes[ 0 ] = label. len ( ) as u8 ;
211
+ label_bytes[ 1 ..=label. len ( ) ] . copy_from_slice ( label. as_bytes ( ) ) ;
212
+
213
+ SLabel :: try_from ( label_bytes. as_slice ( ) )
214
+ }
215
+ }
216
+
191
217
impl TryFrom < String > for SLabel {
192
218
type Error = Error ;
193
219
@@ -204,26 +230,13 @@ impl TryFrom<&str> for SLabel {
204
230
return Err ( Error :: Name ( NameErrorKind :: NotCanonical ) ) ;
205
231
}
206
232
let label = & value[ 1 ..] ;
207
- if label. is_empty ( ) {
208
- return Err ( Error :: Name ( NameErrorKind :: ZeroLength ) ) ;
209
- }
210
- if label. len ( ) > MAX_LABEL_LEN {
211
- return Err ( Error :: Name ( NameErrorKind :: TooLong ) ) ;
212
- }
213
- let mut label_bytes = [ 0 ; MAX_LABEL_LEN + 1 ] ;
214
- label_bytes[ 0 ] = label. len ( ) as u8 ;
215
- label_bytes[ 1 ..=label. len ( ) ] . copy_from_slice ( label. as_bytes ( ) ) ;
216
-
217
- SLabel :: try_from ( label_bytes. as_slice ( ) )
233
+ Self :: from_str_unprefixed ( label)
218
234
}
219
235
}
220
236
221
237
impl Display for SLabel {
222
238
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
223
- let label_len = self . 0 [ 0 ] as usize ;
224
- let label = & self . 0 [ 1 ..=label_len] ;
225
-
226
- let label_str = core:: str:: from_utf8 ( label) . map_err ( |_| core:: fmt:: Error ) ?;
239
+ let label_str = self . as_str_unprefixed ( ) . map_err ( |_| core:: fmt:: Error ) ?;
227
240
write ! ( f, "@{}" , label_str)
228
241
}
229
242
}
@@ -238,6 +251,10 @@ impl SLabel {
238
251
pub fn as_name_ref ( & self ) -> SLabelRef {
239
252
SLabelRef ( & self . 0 )
240
253
}
254
+
255
+ pub fn is_reserved ( & self ) -> bool {
256
+ self . as_name_ref ( ) . is_reserved ( )
257
+ }
241
258
}
242
259
243
260
impl SLabelRef < ' _ > {
@@ -246,6 +263,12 @@ impl SLabelRef<'_> {
246
263
owned. 0 [ ..self . 0 . len ( ) ] . copy_from_slice ( self . 0 ) ;
247
264
owned
248
265
}
266
+
267
+ pub fn is_reserved ( & self ) -> bool {
268
+ RESERVED_SPACES
269
+ . iter ( )
270
+ . any ( |reserved| * reserved == self . as_ref ( ) )
271
+ }
249
272
}
250
273
251
274
#[ cfg( test) ]
0 commit comments