@@ -4,6 +4,7 @@ use regex::Regex;
4
4
use serde_derive:: { Deserialize , Serialize } ;
5
5
use std:: error:: Error ;
6
6
use std:: path:: { Path , PathBuf } ;
7
+ use time:: { Duration , Tm } ;
7
8
8
9
#[ derive( Debug , PartialEq , Deserialize ) ]
9
10
struct YamlHeader {
@@ -21,13 +22,14 @@ pub(crate) struct Post {
21
22
pub ( crate ) layout : String ,
22
23
pub ( crate ) title : String ,
23
24
pub ( crate ) author : String ,
24
- pub ( crate ) year : String ,
25
+ pub ( crate ) year : u32 ,
25
26
pub ( crate ) show_year : bool ,
26
- pub ( crate ) month : String ,
27
- pub ( crate ) day : String ,
27
+ pub ( crate ) month : u32 ,
28
+ pub ( crate ) day : u32 ,
28
29
pub ( crate ) contents : String ,
29
30
pub ( crate ) url : String ,
30
31
pub ( crate ) published : String ,
32
+ pub ( crate ) updated : String ,
31
33
pub ( crate ) release : bool ,
32
34
pub ( crate ) has_team : bool ,
33
35
pub ( crate ) team : String ,
@@ -42,9 +44,10 @@ impl Post {
42
44
// we need to get the metadata out of the url
43
45
let mut split = filename. splitn ( 4 , "-" ) ;
44
46
45
- let year = split. next ( ) . unwrap ( ) . to_string ( ) ;
46
- let month = split. next ( ) . unwrap ( ) . to_string ( ) ;
47
- let day = split. next ( ) . unwrap ( ) . to_string ( ) ;
47
+ // we do some unwraps because these need to be valid
48
+ let year = split. next ( ) . unwrap ( ) . parse :: < u32 > ( ) . unwrap ( ) ;
49
+ let month = split. next ( ) . unwrap ( ) . parse :: < u32 > ( ) . unwrap ( ) ;
50
+ let day = split. next ( ) . unwrap ( ) . parse :: < u32 > ( ) . unwrap ( ) ;
48
51
let filename = split. next ( ) . unwrap ( ) . to_string ( ) ;
49
52
50
53
let contents = std:: fs:: read_to_string ( path) ?;
@@ -76,29 +79,16 @@ impl Post {
76
79
// this is fine
77
80
let url = format ! ( "{}/{}/{}/{}" , year, month, day, url. to_str( ) . unwrap( ) ) ;
78
81
79
- // build the published time. this is only approximate, which is fine.
80
- // we do some unwraps because these need to be valid
81
- let published = time:: Tm {
82
- tm_sec : 0 ,
83
- tm_min : 0 ,
84
- tm_hour : 0 ,
85
- tm_mday : day. parse :: < i32 > ( ) . unwrap ( ) ,
86
- tm_mon : month. parse :: < i32 > ( ) . unwrap ( ) - 1 , // 0-11 not 1-12
87
- tm_year : year. parse :: < i32 > ( ) . unwrap ( ) - 1900 , // from the year 1900, not the actual year
88
- // these next two fields are wrong but we never use them to generate our times
89
- tm_wday : 1 ,
90
- tm_yday : 1 ,
91
- tm_isdst : 0 ,
92
- tm_utcoff : 0 ,
93
- tm_nsec : 0 ,
94
- } ;
95
-
96
- let published = published. rfc3339 ( ) . to_string ( ) ;
82
+ let published = build_post_time ( year, month, day, 0 ) ;
83
+ let updated = published. clone ( ) ;
97
84
98
85
// validate for now that the layout is specified as "post"
99
86
match & * layout {
100
87
"post" => ( ) ,
101
- _ => panic ! ( "blog post at path `{}` should have layout `post`" , path. display( ) ) ,
88
+ _ => panic ! (
89
+ "blog post at path `{}` should have layout `post`" ,
90
+ path. display( )
91
+ ) ,
102
92
} ;
103
93
104
94
// Enforce extra conditions
@@ -114,13 +104,18 @@ impl Post {
114
104
}
115
105
let captures = match R . captures ( & s) {
116
106
Some ( c) => c,
117
- None => panic ! ( "team from path `{}` should have format `$name <$url>`" ,
118
- path. display( ) ) ,
107
+ None => panic ! (
108
+ "team from path `{}` should have format `$name <$url>`" ,
109
+ path. display( )
110
+ ) ,
119
111
} ;
120
- ( Some ( captures[ "name" ] . to_string ( ) ) , Some ( captures[ "url" ] . to_string ( ) ) )
112
+ (
113
+ Some ( captures[ "name" ] . to_string ( ) ) ,
114
+ Some ( captures[ "url" ] . to_string ( ) ) ,
115
+ )
121
116
}
122
117
123
- None => ( None , None )
118
+ None => ( None , None ) ,
124
119
} ;
125
120
126
121
Ok ( Self {
@@ -134,11 +129,36 @@ impl Post {
134
129
contents,
135
130
url,
136
131
published,
132
+ updated,
137
133
release,
138
134
layout,
139
135
has_team : team. is_some ( ) ,
140
136
team : team. unwrap_or_default ( ) ,
141
137
team_url : team_url. unwrap_or_default ( ) ,
142
138
} )
143
139
}
140
+
141
+ pub fn set_updated ( & mut self , hour : u32 ) {
142
+ self . updated = build_post_time ( self . year , self . month , self . day , hour) ;
143
+ }
144
+ }
145
+
146
+ fn build_post_time ( year : u32 , month : u32 , day : u32 , seconds : u32 ) -> String {
147
+ // build the time. this is only approximate, which is fine.
148
+ let mut time = Tm {
149
+ tm_sec : 0 ,
150
+ tm_min : 0 ,
151
+ tm_hour : 0 ,
152
+ tm_mday : day as i32 ,
153
+ tm_mon : ( month as i32 ) - 1 , // 0-11 not 1-12
154
+ tm_year : ( year as i32 ) - 1900 , // from the year 1900, not the actual year
155
+ // these next two fields are wrong but we never use them to generate our times
156
+ tm_wday : 1 ,
157
+ tm_yday : 1 ,
158
+ tm_isdst : 0 ,
159
+ tm_utcoff : 0 ,
160
+ tm_nsec : 0 ,
161
+ } ;
162
+ time = time + Duration :: seconds ( seconds as i64 ) ;
163
+ time. rfc3339 ( ) . to_string ( )
144
164
}
0 commit comments