@@ -9,7 +9,7 @@ use core::{
99#[ cfg( feature = "serde" ) ]
1010use serde:: { de:: Error as ErrorUtil , Deserialize , Deserializer , Serialize , Serializer } ;
1111
12- use crate :: errors:: Error ;
12+ use crate :: { constants :: RESERVED_SPACES , errors:: Error } ;
1313
1414pub const MAX_LABEL_LEN : usize = 62 ;
1515pub const PUNYCODE_PREFIX : & [ u8 ] = b"xn--" ;
@@ -188,6 +188,32 @@ impl<'a> TryFrom<&'a [u8]> for SLabelRef<'a> {
188188 }
189189}
190190
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+
191217impl TryFrom < String > for SLabel {
192218 type Error = Error ;
193219
@@ -204,26 +230,13 @@ impl TryFrom<&str> for SLabel {
204230 return Err ( Error :: Name ( NameErrorKind :: NotCanonical ) ) ;
205231 }
206232 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)
218234 }
219235}
220236
221237impl Display for SLabel {
222238 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 ) ?;
227240 write ! ( f, "@{}" , label_str)
228241 }
229242}
@@ -238,6 +251,10 @@ impl SLabel {
238251 pub fn as_name_ref ( & self ) -> SLabelRef {
239252 SLabelRef ( & self . 0 )
240253 }
254+
255+ pub fn is_reserved ( & self ) -> bool {
256+ self . as_name_ref ( ) . is_reserved ( )
257+ }
241258}
242259
243260impl SLabelRef < ' _ > {
@@ -246,6 +263,12 @@ impl SLabelRef<'_> {
246263 owned. 0 [ ..self . 0 . len ( ) ] . copy_from_slice ( self . 0 ) ;
247264 owned
248265 }
266+
267+ pub fn is_reserved ( & self ) -> bool {
268+ RESERVED_SPACES
269+ . iter ( )
270+ . any ( |reserved| * reserved == self . as_ref ( ) )
271+ }
249272}
250273
251274#[ cfg( test) ]
0 commit comments