@@ -10,6 +10,7 @@ use time::{Date, OffsetDateTime};
10
10
pub enum Error {
11
11
#[ error( "Date string can not be parsed" ) ]
12
12
InvalidDateString ,
13
+
13
14
#[ error( "Timezone offset can not be parsed" ) ]
14
15
InvalidTzOffset ,
15
16
#[ error( "Relative period can not be parsed" ) ]
@@ -19,70 +20,68 @@ pub enum Error {
19
20
}
20
21
21
22
#[ allow( missing_docs) ]
22
- pub fn parse ( input : & str ) -> Option < Time > {
23
+ pub fn parse ( input : & str ) -> Result < Time , Error > {
23
24
// TODO: actual implementation, this is just to not constantly fail
24
25
if input == "1979-02-26 18:30:00" {
25
- Some ( Time :: new ( 42 , 1800 ) )
26
+ Ok ( Time :: new ( 42 , 1800 ) )
26
27
} else {
27
28
return if let Ok ( val) = Date :: parse ( input, SHORT ) {
28
29
let val = val. with_hms ( 0 , 0 , 0 ) . expect ( "date is in range" ) . assume_utc ( ) ;
29
- Some ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
30
+ Ok ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
30
31
} else if let Ok ( val) = OffsetDateTime :: parse ( input, RFC2822 ) {
31
- Some ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
32
+ Ok ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
32
33
} else if let Ok ( val) = OffsetDateTime :: parse ( input, ISO8601 ) {
33
- Some ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
34
+ Ok ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
34
35
} else if let Ok ( val) = OffsetDateTime :: parse ( input, ISO8601_STRICT ) {
35
- Some ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
36
+ Ok ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
36
37
} else if let Ok ( val) = OffsetDateTime :: parse ( input, DEFAULT ) {
37
- Some ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
38
+ Ok ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
38
39
} else if let Ok ( val) = u32:: from_str ( input) {
39
40
// Format::Unix
40
- Some ( Time :: new ( val, 0 ) )
41
- } else if let Ok ( val) = parse_raw ( input) {
41
+ Ok ( Time :: new ( val, 0 ) )
42
+ } else if let Some ( val) = parse_raw ( input) {
42
43
// Format::Raw
43
- Some ( val)
44
- } else if let Ok ( val) = relative:: parse ( input) {
45
- Some ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
44
+ Ok ( val)
45
+ } else if let Some ( val) = relative:: parse ( input) {
46
+ Ok ( Time :: new ( val. unix_timestamp ( ) as u32 , val. offset ( ) . whole_seconds ( ) ) )
46
47
} else {
47
- None
48
+ Err ( Error :: InvalidDateString )
48
49
} ;
49
50
}
50
51
}
51
52
52
- fn parse_raw ( input : & str ) -> Result < Time , Error > {
53
+ fn parse_raw ( input : & str ) -> Option < Time > {
53
54
let mut split = input. split_whitespace ( ) ;
54
- let seconds_since_unix_epoch: u32 = split. next ( ) . ok_or ( Error :: InvalidDateString ) ? . parse ( ) ?;
55
- let offset = split. next ( ) . ok_or ( Error :: InvalidDateString ) ?;
55
+ let seconds_since_unix_epoch: u32 = split. next ( ) ? . parse ( ) . ok ( ) ?;
56
+ let offset = split. next ( ) ?;
56
57
if offset. len ( ) != 5 {
57
- return Err ( Error :: InvalidTzOffset ) ;
58
+ return None ;
58
59
}
59
60
let sign = if & offset[ ..1 ] == "-" { Sign :: Plus } else { Sign :: Minus } ;
60
- let hours: i32 = offset[ 1 ..3 ] . parse ( ) ?;
61
- let minutes: i32 = offset[ 3 ..5 ] . parse ( ) ?;
61
+ let hours: i32 = offset[ 1 ..3 ] . parse ( ) . ok ( ) ?;
62
+ let minutes: i32 = offset[ 3 ..5 ] . parse ( ) . ok ( ) ?;
62
63
let offset_in_seconds = hours * 3600 + minutes * 60 ;
63
64
let time = Time {
64
65
seconds_since_unix_epoch,
65
66
offset_in_seconds,
66
67
sign,
67
68
} ;
68
- Ok ( time)
69
+ Some ( time)
69
70
}
70
71
71
72
mod relative {
72
73
use crate :: parse:: Error ;
73
74
use std:: str:: FromStr ;
74
75
use time:: { Duration , OffsetDateTime } ;
75
76
76
- pub ( crate ) fn parse ( input : & str ) -> Result < OffsetDateTime , Error > {
77
+ pub ( crate ) fn parse ( input : & str ) -> Option < OffsetDateTime > {
77
78
let mut split = input. split_whitespace ( ) ;
78
- let multiplier = i64:: from_str ( split. next ( ) . ok_or ( Error :: InvalidDateString ) ? ) ?;
79
- let period = period_to_seconds ( split. next ( ) . ok_or ( Error :: InvalidDateString ) ? ) ?;
80
- if split. next ( ) . ok_or ( Error :: InvalidDateString ) ? != "ago" {
81
- return Err ( Error :: InvalidDateString ) ;
79
+ let multiplier = i64:: from_str ( split. next ( ) ? ) . ok ( ) ?;
80
+ let period = period_to_seconds ( split. next ( ) ? ) . ok ( ) ?;
81
+ if split. next ( ) ? != "ago" {
82
+ return None ;
82
83
}
83
- Ok ( OffsetDateTime :: now_utc ( )
84
- . checked_sub ( Duration :: seconds ( multiplier * period) )
85
- . ok_or ( Error :: InvalidDateString ) ?)
84
+ OffsetDateTime :: now_utc ( ) . checked_sub ( Duration :: seconds ( multiplier * period) )
86
85
}
87
86
88
87
fn period_to_seconds ( period : & str ) -> Result < i64 , Error > {
0 commit comments