@@ -6,16 +6,16 @@ use std::{fmt, iter::FromIterator, str::FromStr};
6
6
pub type Result < T > = std:: result:: Result < T , ConversionError > ;
7
7
8
8
#[ 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}" ) ]
10
10
pub struct ConversionError {
11
11
pub value : DynVal ,
12
12
pub target_type : & ' static str ,
13
13
pub source : Option < Box < dyn std:: error:: Error > > ,
14
14
}
15
15
16
16
impl 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) ) }
19
19
}
20
20
21
21
pub fn span ( & self ) -> Option < Span > {
@@ -83,16 +83,6 @@ impl<E, T: FromStr<Err = E>> FromDynVal for T {
83
83
}
84
84
}
85
85
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
- }
96
86
macro_rules! impl_dynval_from {
97
87
( $( $t: ty) ,* ) => {
98
88
$( impl From <$t> for DynVal {
@@ -101,14 +91,6 @@ macro_rules! impl_dynval_from {
101
91
} ;
102
92
}
103
93
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
-
112
94
impl_dynval_from ! ( bool , i32 , u32 , f32 , u8 , f64 , & str ) ;
113
95
114
96
impl From < & serde_json:: Value > for DynVal {
@@ -128,6 +110,10 @@ impl DynVal {
128
110
DynVal ( self . 0 , Some ( span) )
129
111
}
130
112
113
+ pub fn span ( & self ) -> Option < Span > {
114
+ self . 1
115
+ }
116
+
131
117
pub fn from_string ( s : String ) -> Self {
132
118
DynVal ( s, None )
133
119
}
@@ -146,15 +132,39 @@ impl DynVal {
146
132
}
147
133
148
134
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 ) )
150
136
}
151
137
152
138
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 ) )
154
140
}
155
141
156
142
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
+ }
158
168
}
159
169
160
170
// pub fn as_vec(&self) -> Result<Vec<String>> {
0 commit comments