@@ -24,7 +24,7 @@ pub mod consts;
24
24
mod line_proto_term;
25
25
pub mod read_query;
26
26
pub mod write_query;
27
- use std:: fmt;
27
+ use std:: { convert :: Infallible , fmt} ;
28
28
29
29
use crate :: { Error , WriteQuery } ;
30
30
use consts:: {
@@ -70,48 +70,55 @@ impl fmt::Display for Timestamp {
70
70
}
71
71
72
72
#[ cfg( feature = "chrono" ) ]
73
- impl From < Timestamp > for chrono:: DateTime < chrono:: Utc > {
74
- fn from ( ts : Timestamp ) -> chrono:: DateTime < chrono:: Utc > {
73
+ impl TryFrom < Timestamp > for chrono:: DateTime < chrono:: Utc > {
74
+ type Error = <i64 as TryFrom < u128 > >:: Error ;
75
+
76
+ fn try_from ( ts : Timestamp ) -> Result < Self , Self :: Error > {
75
77
use chrono:: TimeZone as _;
76
- chrono:: Utc . timestamp_nanos ( ts. nanos ( ) as i64 )
78
+ Ok ( chrono:: Utc . timestamp_nanos ( ts. nanos ( ) . try_into ( ) ? ) )
77
79
}
78
80
}
79
81
80
82
#[ cfg( feature = "chrono" ) ]
81
- impl < T > From < chrono:: DateTime < T > > for Timestamp
82
- where
83
- T : chrono:: TimeZone ,
84
- {
85
- fn from ( date_time : chrono:: DateTime < T > ) -> Self {
86
- Timestamp :: Nanoseconds ( date_time. timestamp_nanos_opt ( ) . unwrap ( ) as u128 )
87
- }
88
- }
83
+ impl TryFrom < chrono:: DateTime < chrono:: Utc > > for Timestamp {
84
+ type Error = crate :: error:: TimeTryFromError <
85
+ crate :: error:: TimestampTooLargeError ,
86
+ <u128 as TryFrom < i64 > >:: Error ,
87
+ > ;
89
88
90
- #[ cfg( feature = "time" ) ]
91
- impl From < Timestamp > for time:: UtcDateTime {
92
- fn from ( value : Timestamp ) -> Self {
93
- time:: UtcDateTime :: from_unix_timestamp_nanos ( value. nanos ( ) as i128 ) . unwrap ( )
89
+ fn try_from ( dt : chrono:: DateTime < chrono:: Utc > ) -> Result < Self , Self :: Error > {
90
+ // unfortunately chrono doesn't give us the nanos as i128, so we have to error
91
+ // if it doesn't fit and then cast the i64 to u128 anyways
92
+ let nanos = dt
93
+ . timestamp_nanos_opt ( )
94
+ . ok_or ( Self :: Error :: TimeError (
95
+ crate :: error:: TimestampTooLargeError ( ( ) ) ,
96
+ ) ) ?
97
+ . try_into ( )
98
+ . map_err ( Self :: Error :: IntError ) ?;
99
+ Ok ( Self :: Nanoseconds ( nanos) )
94
100
}
95
101
}
96
102
97
103
#[ cfg( feature = "time" ) ]
98
- impl From < time:: UtcDateTime > for Timestamp {
99
- fn from ( value : time:: UtcDateTime ) -> Self {
100
- Timestamp :: Nanoseconds ( value. unix_timestamp_nanos ( ) as u128 )
101
- }
102
- }
104
+ impl TryFrom < Timestamp > for time:: UtcDateTime {
105
+ type Error =
106
+ crate :: error:: TimeTryFromError < time:: error:: ComponentRange , <i128 as TryFrom < u128 > >:: Error > ;
103
107
104
- #[ cfg( feature = "time" ) ]
105
- impl From < Timestamp > for time:: OffsetDateTime {
106
- fn from ( value : Timestamp ) -> Self {
107
- time:: OffsetDateTime :: from_unix_timestamp_nanos ( value. nanos ( ) as i128 ) . unwrap ( )
108
+ fn try_from ( value : Timestamp ) -> Result < Self , Self :: Error > {
109
+ let nanos = value. nanos ( ) . try_into ( ) . map_err ( Self :: Error :: IntError ) ?;
110
+ time:: UtcDateTime :: from_unix_timestamp_nanos ( nanos) . map_err ( Self :: Error :: TimeError )
108
111
}
109
112
}
110
113
111
114
#[ cfg( feature = "time" ) ]
112
- impl From < time:: OffsetDateTime > for Timestamp {
113
- fn from ( value : time:: OffsetDateTime ) -> Self {
114
- Timestamp :: Nanoseconds ( value. unix_timestamp_nanos ( ) as u128 )
115
+ impl TryFrom < time:: UtcDateTime > for Timestamp {
116
+ type Error = <u128 as TryFrom < i128 > >:: Error ;
117
+
118
+ fn try_from ( value : time:: UtcDateTime ) -> Result < Self , Self :: Error > {
119
+ Ok ( Timestamp :: Nanoseconds (
120
+ value. unix_timestamp_nanos ( ) . try_into ( ) ?,
121
+ ) )
115
122
}
116
123
}
117
124
@@ -186,12 +193,16 @@ impl<Q: Query> Query for Box<Q> {
186
193
}
187
194
188
195
pub trait InfluxDbWriteable {
189
- fn into_query < I : Into < String > > ( self , name : I ) -> WriteQuery ;
196
+ type Error ;
197
+
198
+ fn try_into_query < I : Into < String > > ( self , name : I ) -> Result < WriteQuery , Self :: Error > ;
190
199
}
191
200
192
201
impl InfluxDbWriteable for Timestamp {
193
- fn into_query < I : Into < String > > ( self , name : I ) -> WriteQuery {
194
- WriteQuery :: new ( self , name. into ( ) )
202
+ type Error = Infallible ;
203
+
204
+ fn try_into_query < I : Into < String > > ( self , name : I ) -> Result < WriteQuery , Infallible > {
205
+ Ok ( WriteQuery :: new ( self , name. into ( ) ) )
195
206
}
196
207
}
197
208
@@ -232,30 +243,35 @@ pub enum QueryType {
232
243
233
244
#[ cfg( test) ]
234
245
mod tests {
246
+ #[ cfg( feature = "chrono" ) ]
235
247
use super :: consts:: {
236
248
MILLIS_PER_SECOND , MINUTES_PER_HOUR , NANOS_PER_MICRO , NANOS_PER_MILLI , SECONDS_PER_MINUTE ,
237
249
} ;
238
250
use crate :: query:: { Timestamp , ValidQuery } ;
251
+
239
252
#[ test]
240
253
fn test_equality_str ( ) {
241
254
assert_eq ! ( ValidQuery :: from( "hello" ) , "hello" ) ;
242
255
}
256
+
243
257
#[ test]
244
258
fn test_equality_string ( ) {
245
259
assert_eq ! (
246
260
ValidQuery :: from( String :: from( "hello" ) ) ,
247
261
String :: from( "hello" )
248
262
) ;
249
263
}
264
+
250
265
#[ test]
251
266
fn test_format_for_timestamp_else ( ) {
252
267
assert ! ( format!( "{}" , Timestamp :: Nanoseconds ( 100 ) ) == "100" ) ;
253
268
}
269
+
254
270
#[ cfg( feature = "chrono" ) ]
255
271
#[ test]
256
272
fn test_chrono_datetime_from_timestamp_hours ( ) {
257
273
use chrono:: prelude:: * ;
258
- let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Hours ( 2 ) . into ( ) ;
274
+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Hours ( 2 ) . try_into ( ) . unwrap ( ) ;
259
275
assert_eq ! (
260
276
Utc . timestamp_nanos(
261
277
( 2 * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI )
@@ -265,11 +281,12 @@ mod tests {
265
281
datetime_from_timestamp
266
282
)
267
283
}
284
+
268
285
#[ cfg( feature = "chrono" ) ]
269
286
#[ test]
270
287
fn test_chrono_datetime_from_timestamp_minutes ( ) {
271
288
use chrono:: prelude:: * ;
272
- let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Minutes ( 2 ) . into ( ) ;
289
+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Minutes ( 2 ) . try_into ( ) . unwrap ( ) ;
273
290
assert_eq ! (
274
291
Utc . timestamp_nanos(
275
292
( 2 * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI )
@@ -279,11 +296,12 @@ mod tests {
279
296
datetime_from_timestamp
280
297
)
281
298
}
299
+
282
300
#[ cfg( feature = "chrono" ) ]
283
301
#[ test]
284
302
fn test_chrono_datetime_from_timestamp_seconds ( ) {
285
303
use chrono:: prelude:: * ;
286
- let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Seconds ( 2 ) . into ( ) ;
304
+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Seconds ( 2 ) . try_into ( ) . unwrap ( ) ;
287
305
assert_eq ! (
288
306
Utc . timestamp_nanos(
289
307
( 2 * MILLIS_PER_SECOND * NANOS_PER_MILLI )
@@ -293,33 +311,37 @@ mod tests {
293
311
datetime_from_timestamp
294
312
)
295
313
}
314
+
296
315
#[ cfg( feature = "chrono" ) ]
297
316
#[ test]
298
317
fn test_chrono_datetime_from_timestamp_millis ( ) {
299
318
use chrono:: prelude:: * ;
300
- let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Milliseconds ( 2 ) . into ( ) ;
319
+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Milliseconds ( 2 ) . try_into ( ) . unwrap ( ) ;
301
320
assert_eq ! (
302
321
Utc . timestamp_nanos( ( 2 * NANOS_PER_MILLI ) . try_into( ) . unwrap( ) ) ,
303
322
datetime_from_timestamp
304
323
)
305
324
}
325
+
306
326
#[ cfg( feature = "chrono" ) ]
307
327
#[ test]
308
328
fn test_chrono_datetime_from_timestamp_nanos ( ) {
309
329
use chrono:: prelude:: * ;
310
- let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Nanoseconds ( 1 ) . into ( ) ;
330
+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Nanoseconds ( 1 ) . try_into ( ) . unwrap ( ) ;
311
331
assert_eq ! ( Utc . timestamp_nanos( 1 ) , datetime_from_timestamp)
312
332
}
333
+
313
334
#[ cfg( feature = "chrono" ) ]
314
335
#[ test]
315
336
fn test_chrono_datetime_from_timestamp_micros ( ) {
316
337
use chrono:: prelude:: * ;
317
- let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Microseconds ( 2 ) . into ( ) ;
338
+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Microseconds ( 2 ) . try_into ( ) . unwrap ( ) ;
318
339
assert_eq ! (
319
340
Utc . timestamp_nanos( ( 2 * NANOS_PER_MICRO ) . try_into( ) . unwrap( ) ) ,
320
341
datetime_from_timestamp
321
342
)
322
343
}
344
+
323
345
#[ cfg( feature = "chrono" ) ]
324
346
#[ test]
325
347
fn test_timestamp_from_chrono_date ( ) {
@@ -328,7 +350,8 @@ mod tests {
328
350
. with_ymd_and_hms ( 1970 , 1 , 1 , 0 , 0 , 1 )
329
351
. single ( )
330
352
. unwrap ( )
331
- . into ( ) ;
353
+ . try_into ( )
354
+ . unwrap ( ) ;
332
355
assert_eq ! (
333
356
Timestamp :: Nanoseconds ( MILLIS_PER_SECOND * NANOS_PER_MILLI ) ,
334
357
timestamp_from_datetime
0 commit comments