11use crate :: result:: Error ;
22use crate :: rule:: Rule ;
33use serde:: { Deserialize , Deserializer , Serialize , Serializer } ;
4+ use std:: collections:: { HashMap , HashSet , VecDeque } ;
45use std:: fmt:: { Debug , Display , Formatter } ;
56
67/// Refined is a versatile type in ensuring that `T` satisfies the conditions of `RULE` (predicate type)
8586 }
8687}
8788
89+ macro_rules! impl_try_from {
90+ ( $t: ty) => {
91+ impl <RULE : Rule <Item = $t>> TryFrom <$t> for Refined <RULE > {
92+ type Error = Error <$t>;
93+
94+ fn try_from( value: $t) -> Result <Self , Self :: Error > {
95+ Refined :: new( value)
96+ }
97+ }
98+ } ;
99+ ( $( $ts: ty) , +) => {
100+ $( impl_try_from!( $ts) ; ) +
101+ } ;
102+ }
103+
104+ impl_try_from ! [ u8 , u16 , u32 , u64 , u128 , usize , i8 , i16 , i32 , i64 , i128 , isize , f32 , f64 ] ;
105+ impl_try_from ! [ String , char ] ;
106+
107+ impl < ' a , RULE : Rule < Item = String > > TryFrom < & ' a str > for Refined < RULE > {
108+ type Error = Error < String > ;
109+
110+ fn try_from ( value : & ' a str ) -> Result < Self , Self :: Error > {
111+ Refined :: new ( value. into ( ) )
112+ }
113+ }
114+
115+ impl < T , RULE : Rule < Item = Vec < T > > > TryFrom < Vec < T > > for Refined < RULE > {
116+ type Error = Error < Vec < T > > ;
117+
118+ fn try_from ( value : Vec < T > ) -> Result < Self , Self :: Error > {
119+ Refined :: new ( value)
120+ }
121+ }
122+
123+ impl < T , RULE : Rule < Item = VecDeque < T > > > TryFrom < VecDeque < T > > for Refined < RULE > {
124+ type Error = Error < VecDeque < T > > ;
125+
126+ fn try_from ( value : VecDeque < T > ) -> Result < Self , Self :: Error > {
127+ Refined :: new ( value)
128+ }
129+ }
130+
131+ impl < T , RULE : Rule < Item = HashSet < T > > > TryFrom < HashSet < T > > for Refined < RULE > {
132+ type Error = Error < HashSet < T > > ;
133+
134+ fn try_from ( value : HashSet < T > ) -> Result < Self , Self :: Error > {
135+ Refined :: new ( value)
136+ }
137+ }
138+
139+ impl < K , V , RULE : Rule < Item = HashMap < K , V > > > TryFrom < HashMap < K , V > > for Refined < RULE > {
140+ type Error = Error < HashMap < K , V > > ;
141+
142+ fn try_from ( value : HashMap < K , V > ) -> Result < Self , Self :: Error > {
143+ Refined :: new ( value)
144+ }
145+ }
146+
88147impl < RULE , T > Display for Refined < RULE >
89148where
90149 RULE : Rule < Item = T > ,
@@ -99,10 +158,15 @@ where
99158mod test {
100159 use serde:: { Deserialize , Serialize } ;
101160 use serde_json:: json;
161+ use std:: collections:: { HashMap , HashSet , VecDeque } ;
102162
103163 use crate :: refined:: Refined ;
104164 use crate :: result:: Error ;
105- use crate :: rule:: { NonEmptyString , NonEmptyStringRule , NonEmptyVec } ;
165+ use crate :: rule:: {
166+ EqualI128 , EqualI16 , EqualI32 , EqualI64 , EqualI8 , EqualIsize , EqualU128 , EqualU16 ,
167+ EqualU32 , EqualU64 , EqualU8 , EqualUsize , NonEmptyHashMap , NonEmptyHashSet , NonEmptyString ,
168+ NonEmptyStringRule , NonEmptyVec , NonEmptyVecDeque ,
169+ } ;
106170
107171 #[ test]
108172 fn test_unsafe_new_success ( ) {
@@ -255,4 +319,86 @@ mod test {
255319 assert ! ( result. is_err( ) ) ;
256320 Ok ( ( ) )
257321 }
322+
323+ #[ test]
324+ fn test_try_from ( ) -> anyhow:: Result < ( ) > {
325+ let value = NonEmptyString :: try_from ( "hello" ) ?;
326+ assert_eq ! ( value. into_value( ) , "hello" ) ;
327+
328+ let value = NonEmptyString :: try_from ( "hello" . to_string ( ) ) ?;
329+ assert_eq ! ( value. into_value( ) , "hello" ) ;
330+
331+ let value = EqualU8 :: < 8 > :: try_from ( 8 ) ?;
332+ assert_eq ! ( value. into_value( ) , 8 ) ;
333+
334+ let value = EqualU16 :: < 16 > :: try_from ( 16 ) ?;
335+ assert_eq ! ( value. into_value( ) , 16 ) ;
336+
337+ let value = EqualU32 :: < 32 > :: try_from ( 32 ) ?;
338+ assert_eq ! ( value. into_value( ) , 32 ) ;
339+
340+ let value = EqualU64 :: < 64 > :: try_from ( 64 ) ?;
341+ assert_eq ! ( value. into_value( ) , 64 ) ;
342+
343+ let value = EqualU128 :: < 128 > :: try_from ( 128 ) ?;
344+ assert_eq ! ( value. into_value( ) , 128 ) ;
345+
346+ let value = EqualUsize :: < 1 > :: try_from ( 1 ) ?;
347+ assert_eq ! ( value. into_value( ) , 1 ) ;
348+
349+ let value = EqualI8 :: < 8 > :: try_from ( 8 ) ?;
350+ assert_eq ! ( value. into_value( ) , 8 ) ;
351+
352+ let value = EqualI16 :: < 16 > :: try_from ( 16 ) ?;
353+ assert_eq ! ( value. into_value( ) , 16 ) ;
354+
355+ let value = EqualI32 :: < 32 > :: try_from ( 32 ) ?;
356+ assert_eq ! ( value. into_value( ) , 32 ) ;
357+
358+ let value = EqualI64 :: < 64 > :: try_from ( 64 ) ?;
359+ assert_eq ! ( value. into_value( ) , 64 ) ;
360+
361+ let value = EqualI128 :: < 128 > :: try_from ( 128 ) ?;
362+ assert_eq ! ( value. into_value( ) , 128 ) ;
363+
364+ let value = EqualIsize :: < 1 > :: try_from ( 1 ) ?;
365+ assert_eq ! ( value. into_value( ) , 1 ) ;
366+
367+ let value = NonEmptyVec :: try_from ( vec ! [ "hello" . to_string( ) ] ) ?;
368+ assert_eq ! ( value. into_value( ) , vec![ "hello" . to_string( ) ] ) ;
369+
370+ let value = NonEmptyVecDeque :: try_from (
371+ vec ! [ "hello" . to_string( ) ]
372+ . into_iter ( )
373+ . collect :: < VecDeque < _ > > ( ) ,
374+ ) ?;
375+ assert_eq ! ( value. into_value( ) , vec![ "hello" . to_string( ) ] ) ;
376+
377+ let value = NonEmptyHashSet :: try_from (
378+ vec ! [ "hello" . to_string( ) ]
379+ . into_iter ( )
380+ . collect :: < HashSet < _ > > ( ) ,
381+ ) ?;
382+ assert_eq ! (
383+ value. into_value( ) ,
384+ vec![ "hello" . to_string( ) ] . into_iter( ) . collect( )
385+ ) ;
386+
387+ let value = NonEmptyHashMap :: try_from (
388+ vec ! [ ( "hello" . to_string( ) , "world" . to_string( ) ) ]
389+ . into_iter ( )
390+ . collect :: < HashMap < _ , _ > > ( ) ,
391+ ) ?;
392+ assert_eq ! (
393+ value. into_value( ) ,
394+ vec![ ( "hello" . to_string( ) , "world" . to_string( ) ) ]
395+ . into_iter( )
396+ . collect( )
397+ ) ;
398+
399+ let value: NonEmptyVec < NonEmptyString > =
400+ NonEmptyVec :: try_from ( vec ! [ "hello" . to_string( ) . try_into( ) ?] ) ?;
401+ assert_eq ! ( value. into_value( ) , vec![ "hello" . to_string( ) . try_into( ) ?] ) ;
402+ Ok ( ( ) )
403+ }
258404}
0 commit comments