@@ -6,16 +6,16 @@ use std::{fmt, iter::FromIterator, str::FromStr};
66pub type Result < T > = std:: result:: Result < T , ConversionError > ;
77
88#[ derive( Debug , thiserror:: Error ) ]
9- #[ error( "Failed to turn {value} into a {target_type}" ) ]
9+ #[ error( "Failed to turn {value} into a value of type {target_type}" ) ]
1010pub struct ConversionError {
1111 pub value : DynVal ,
1212 pub target_type : & ' static str ,
1313 pub source : Option < Box < dyn std:: error:: Error > > ,
1414}
1515
1616impl ConversionError {
17- fn new ( value : DynVal , target_type : & ' static str , source : Box < dyn std:: error:: Error > ) -> Self {
18- ConversionError { value, target_type, source : Some ( source) }
17+ fn new ( value : DynVal , target_type : & ' static str , source : impl std:: error:: Error + ' static ) -> Self {
18+ ConversionError { value, target_type, source : Some ( Box :: new ( source) ) }
1919 }
2020
2121 pub fn span ( & self ) -> Option < Span > {
@@ -83,16 +83,6 @@ impl<E, T: FromStr<Err = E>> FromDynVal for T {
8383 }
8484}
8585
86- macro_rules! impl_from_dynval {
87- (
88- $( for $for: ty => |$name: ident| $code: expr) ;* ;
89- ) => {
90- $( impl FromDynVal for $for {
91- type Err = ConversionError ;
92- fn from_dynval( $name: DynVal ) -> std:: result:: Result <Self , Self :: Err > { $code }
93- } ) *
94- } ;
95- }
9686macro_rules! impl_dynval_from {
9787 ( $( $t: ty) ,* ) => {
9888 $( impl From <$t> for DynVal {
@@ -101,14 +91,6 @@ macro_rules! impl_dynval_from {
10191 } ;
10292}
10393
104- // impl_from_dynval! {
105- // for String => |x| x.as_string();
106- // for f64 => |x| x.as_f64();
107- // for i32 => |x| x.as_i32();
108- // for bool => |x| x.as_bool();
109- ////for Vec<String> => |x| x.as_vec();
110- //}
111-
11294impl_dynval_from ! ( bool , i32 , u32 , f32 , u8 , f64 , & str ) ;
11395
11496impl From < & serde_json:: Value > for DynVal {
@@ -128,6 +110,10 @@ impl DynVal {
128110 DynVal ( self . 0 , Some ( span) )
129111 }
130112
113+ pub fn span ( & self ) -> Option < Span > {
114+ self . 1
115+ }
116+
131117 pub fn from_string ( s : String ) -> Self {
132118 DynVal ( s, None )
133119 }
@@ -146,15 +132,39 @@ impl DynVal {
146132 }
147133
148134 pub fn as_f64 ( & self ) -> Result < f64 > {
149- self . 0 . parse ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "f64" , Box :: new ( e ) ) )
135+ self . 0 . parse ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "f64" , e ) )
150136 }
151137
152138 pub fn as_i32 ( & self ) -> Result < i32 > {
153- self . 0 . parse ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "i32" , Box :: new ( e ) ) )
139+ self . 0 . parse ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "i32" , e ) )
154140 }
155141
156142 pub fn as_bool ( & self ) -> Result < bool > {
157- self . 0 . parse ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "bool" , Box :: new ( e) ) )
143+ self . 0 . parse ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "bool" , e) )
144+ }
145+
146+ pub fn as_duration ( & self ) -> Result < std:: time:: Duration > {
147+ use std:: time:: Duration ;
148+ let s = & self . 0 ;
149+ if s. ends_with ( "ms" ) {
150+ Ok ( Duration :: from_millis (
151+ s. trim_end_matches ( "ms" ) . parse ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "integer" , e) ) ?,
152+ ) )
153+ } else if s. ends_with ( 's' ) {
154+ Ok ( Duration :: from_secs (
155+ s. trim_end_matches ( 's' ) . parse ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "integer" , e) ) ?,
156+ ) )
157+ } else if s. ends_with ( 'm' ) {
158+ Ok ( Duration :: from_secs (
159+ s. trim_end_matches ( 'm' ) . parse :: < u64 > ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "integer" , e) ) ? * 60 ,
160+ ) )
161+ } else if s. ends_with ( 'h' ) {
162+ Ok ( Duration :: from_secs (
163+ s. trim_end_matches ( 'h' ) . parse :: < u64 > ( ) . map_err ( |e| ConversionError :: new ( self . clone ( ) , "integer" , e) ) ? * 60 * 60 ,
164+ ) )
165+ } else {
166+ Err ( ConversionError { value : self . clone ( ) , target_type : "duration" , source : None } )
167+ }
158168 }
159169
160170 // pub fn as_vec(&self) -> Result<Vec<String>> {
0 commit comments