@@ -7,7 +7,7 @@ use std::{
7
7
8
8
use comrak:: ComrakOptions ;
9
9
10
- use handlebars:: { Handlebars , Helper , Context , RenderContext , Output , HelperResult , RenderError } ;
10
+ use handlebars:: { Context , Handlebars , Helper , HelperResult , Output , RenderContext , RenderError } ;
11
11
12
12
use serde_derive:: { Deserialize , Serialize } ;
13
13
use serde_json:: json;
@@ -20,7 +20,7 @@ struct Blog {
20
20
out_directory : PathBuf ,
21
21
}
22
22
23
- #[ derive( Debug , Serialize , Deserialize ) ]
23
+ #[ derive( Debug , Serialize , Deserialize , Clone ) ]
24
24
struct Post {
25
25
filename : String ,
26
26
title : String ,
@@ -32,32 +32,58 @@ struct Post {
32
32
contents : String ,
33
33
url : String ,
34
34
published : String ,
35
+ release : bool ,
35
36
}
36
37
37
38
#[ derive( Debug , PartialEq , Serialize , Deserialize ) ]
38
39
struct YamlHeader {
39
40
title : String ,
40
41
author : String ,
42
+ #[ serde( default ) ]
43
+ release : bool ,
41
44
}
42
45
43
- fn hb_month_helper < ' a > ( h : & Helper , _b : & Handlebars , _ctx : & Context , _rc : & mut RenderContext ,
44
- out : & mut Output ) -> HelperResult {
45
- let num: u32 = h. param ( 0 ) . unwrap ( ) . value ( ) . as_str ( ) . unwrap ( ) . parse ( )
46
+ #[ derive( Debug , Serialize ) ]
47
+ struct Releases {
48
+ releases : Vec < ReleasePost > ,
49
+ feed_updated : String ,
50
+ }
51
+
52
+ #[ derive( Debug , Serialize ) ]
53
+ struct ReleasePost {
54
+ title : String ,
55
+ url : String ,
56
+ }
57
+
58
+ fn hb_month_helper < ' a > (
59
+ h : & Helper ,
60
+ _b : & Handlebars ,
61
+ _ctx : & Context ,
62
+ _rc : & mut RenderContext ,
63
+ out : & mut Output ,
64
+ ) -> HelperResult {
65
+ let num: u32 = h
66
+ . param ( 0 )
67
+ . unwrap ( )
68
+ . value ( )
69
+ . as_str ( )
70
+ . unwrap ( )
71
+ . parse ( )
46
72
. or_else ( |_| Err ( RenderError :: new ( "The value is not a number" ) ) ) ?;
47
73
let name = match num {
48
- 1 => "Jan." ,
49
- 2 => "Feb." ,
50
- 3 => "Mar." ,
51
- 4 => "Apr." ,
52
- 5 => "May" ,
53
- 6 => "June" ,
54
- 7 => "July" ,
55
- 8 => "Aug." ,
56
- 9 => "Sept." ,
74
+ 1 => "Jan." ,
75
+ 2 => "Feb." ,
76
+ 3 => "Mar." ,
77
+ 4 => "Apr." ,
78
+ 5 => "May" ,
79
+ 6 => "June" ,
80
+ 7 => "July" ,
81
+ 8 => "Aug." ,
82
+ 9 => "Sept." ,
57
83
10 => "Oct." ,
58
84
11 => "Nov." ,
59
85
12 => "Dec." ,
60
- _ => "Error!" ,
86
+ _ => "Error!" ,
61
87
} ;
62
88
out. write ( name) ?;
63
89
Ok ( ( ) )
@@ -109,9 +135,11 @@ impl Blog {
109
135
// so we need to find the end. we need the fours to adjust for those first bytes
110
136
let end_of_yaml = contents[ 4 ..] . find ( "---" ) . unwrap ( ) + 4 ;
111
137
let yaml = & contents[ ..end_of_yaml] ;
112
-
113
- let YamlHeader { author, title } = serde_yaml:: from_str ( yaml) ?;
114
-
138
+ let YamlHeader {
139
+ author,
140
+ title,
141
+ release,
142
+ } = serde_yaml:: from_str ( yaml) ?;
115
143
// next, the contents. we add + to get rid of the final "---\n\n"
116
144
let options = ComrakOptions {
117
145
ext_header_ids : Some ( String :: new ( ) ) ,
@@ -126,7 +154,7 @@ impl Blog {
126
154
127
155
// this is fine
128
156
let url = format ! ( "{}/{}/{}/{}" , year, month, day, url. to_str( ) . unwrap( ) ) ;
129
-
157
+
130
158
// build the published time. this is only approximate, which is fine.
131
159
// we do some unwraps because these need to be valid
132
160
let published = time:: Tm {
@@ -157,6 +185,7 @@ impl Blog {
157
185
contents,
158
186
url,
159
187
published,
188
+ release,
160
189
} ;
161
190
162
191
posts. push ( post) ;
@@ -168,7 +197,7 @@ impl Blog {
168
197
169
198
posts. reverse ( ) ;
170
199
171
- for i in 1 .. posts. len ( ) {
200
+ for i in 1 .. posts. len ( ) {
172
201
posts[ i] . show_year = posts[ i - 1 ] . year != posts[ i] . year ;
173
202
}
174
203
@@ -192,6 +221,8 @@ impl Blog {
192
221
193
222
self . copy_static_files ( ) ?;
194
223
224
+ self . generate_releases_feed ( ) ?;
225
+
195
226
Ok ( ( ) )
196
227
}
197
228
@@ -258,12 +289,34 @@ impl Blog {
258
289
259
290
fn render_feed ( & self ) -> Result < ( ) , Box < Error > > {
260
291
let posts: Vec < _ > = self . posts . iter ( ) . by_ref ( ) . take ( 10 ) . collect ( ) ;
261
- let data = json ! ( { "posts" : posts, "feed_updated" : time:: now_utc( ) . rfc3339( ) . to_string( ) } ) ;
292
+ let data =
293
+ json ! ( { "posts" : posts, "feed_updated" : time:: now_utc( ) . rfc3339( ) . to_string( ) } ) ;
262
294
263
295
self . render_template ( "feed.xml" , "feed" , data) ?;
264
296
Ok ( ( ) )
265
297
}
266
298
299
+ fn generate_releases_feed ( & self ) -> Result < ( ) , Box < Error > > {
300
+ let posts = self . posts . clone ( ) ;
301
+ let is_released: Vec < & Post > = posts. iter ( ) . filter ( |post| post. release ) . collect ( ) ;
302
+ let releases: Vec < ReleasePost > = is_released
303
+ . iter ( )
304
+ . map ( |post| ReleasePost {
305
+ title : post. title . clone ( ) ,
306
+ url : post. url . clone ( ) ,
307
+ } )
308
+ . collect ( ) ;
309
+ let data = Releases {
310
+ releases : releases,
311
+ feed_updated : time:: now_utc ( ) . rfc3339 ( ) . to_string ( ) ,
312
+ } ;
313
+ fs:: write (
314
+ self . out_directory . join ( "releases.json" ) ,
315
+ serde_json:: to_string ( & data) ?,
316
+ ) ?;
317
+ Ok ( ( ) )
318
+ }
319
+
267
320
fn copy_static_files ( & self ) -> Result < ( ) , Box < Error > > {
268
321
use fs_extra:: dir:: { self , CopyOptions } ;
269
322
0 commit comments