11#![ doc = include_str ! ( "../README.md" ) ]
22
3+ #[ cfg( feature = "serde" ) ]
4+ mod serde_support;
5+
36/// A simple String wrapper type, similar to NonZeroUsize and friends.
47/// Guarantees that the String contained inside is not of length 0.
5- #[ derive( Debug , Clone ) ]
8+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
9+ #[ repr( transparent) ]
610pub struct NonEmptyString ( String ) ;
711
812impl NonEmptyString {
913 /// Attempts to create a new NonEmptyString.
10- /// If the given `string` is empty, `None ` is returned, `Some ` otherwise.
11- pub fn new ( string : String ) -> Option < NonEmptyString > {
14+ /// If the given `string` is empty, `Err ` is returned, containing the original `String`, `Ok ` otherwise.
15+ pub fn new ( string : String ) -> Result < NonEmptyString , String > {
1216 if string. is_empty ( ) {
13- None
17+ Err ( string )
1418 } else {
15- Some ( NonEmptyString ( string) )
19+ Ok ( NonEmptyString ( string) )
1620 }
1721 }
1822
23+ /// Returns a reference to the contained value.
24+ pub fn get ( & self ) -> & str {
25+ & self . 0
26+ }
27+
28+ /// Consume the `NonEmptyString` to get the internal `String` out.
1929 pub fn into_inner ( self ) -> String {
2030 self . 0
2131 }
@@ -33,19 +43,31 @@ impl std::convert::AsRef<String> for NonEmptyString {
3343 }
3444}
3545
46+ impl < ' s > std:: convert:: TryFrom < & ' s str > for NonEmptyString {
47+ type Error = ( ) ;
48+
49+ fn try_from ( value : & ' s str ) -> Result < Self , Self :: Error > {
50+ if value. is_empty ( ) {
51+ Err ( ( ) )
52+ } else {
53+ Ok ( NonEmptyString :: new ( value. to_owned ( ) ) . expect ( "Value is not empty" ) )
54+ }
55+ }
56+ }
57+
3658#[ cfg( test) ]
3759mod tests {
3860 use super :: * ;
3961 use assert_matches:: assert_matches;
4062
4163 #[ test]
4264 fn empty_string_returns_none ( ) {
43- assert_matches ! ( NonEmptyString :: new( "" . to_owned( ) ) , None ) ;
65+ assert_eq ! ( NonEmptyString :: new( "" . to_owned( ) ) , Err ( "" . to_owned ( ) ) ) ;
4466 }
4567
4668 #[ test]
4769 fn non_empty_string_returns_some ( ) {
48- assert_matches ! ( NonEmptyString :: new( "string" . to_owned( ) ) , Some ( _) ) ;
70+ assert_matches ! ( NonEmptyString :: new( "string" . to_owned( ) ) , Ok ( _) ) ;
4971 }
5072
5173 #[ test]
@@ -57,4 +79,25 @@ mod tests {
5779 "string" . to_owned( )
5880 ) ;
5981 }
82+
83+ #[ test]
84+ fn as_ref_str_works ( ) {
85+ let nes = NonEmptyString :: new ( "string" . to_owned ( ) ) . unwrap ( ) ;
86+ let val: & str = nes. as_ref ( ) ;
87+ assert_eq ! ( val, "string" ) ;
88+ }
89+
90+ #[ test]
91+ fn as_ref_string_works ( ) {
92+ let nes = NonEmptyString :: new ( "string" . to_owned ( ) ) . unwrap ( ) ;
93+ let val: & String = nes. as_ref ( ) ;
94+ assert_eq ! ( val, "string" ) ;
95+ }
96+
97+ #[ test]
98+ fn calling_string_methods_works ( ) {
99+ let nes = NonEmptyString :: new ( "string" . to_owned ( ) ) . unwrap ( ) ;
100+ // `len` is a `String` method.
101+ assert ! ( nes. get( ) . len( ) > 0 ) ;
102+ }
60103}
0 commit comments