1
1
use super :: error:: Nope ;
2
- use super :: page:: Page ;
3
- use super :: {
4
- duration_to_str, match_version, redirect_base, render_markdown, MatchSemver , MetaData ,
5
- } ;
6
- use crate :: db:: Pool ;
2
+ use super :: { match_version, redirect_base, render_markdown, MatchSemver , MetaData } ;
3
+ use crate :: { db:: Pool , impl_webpage, web:: page:: WebPage } ;
7
4
use chrono:: { DateTime , NaiveDateTime , Utc } ;
8
5
use iron:: prelude:: * ;
9
6
use iron:: { status, Url } ;
10
7
use postgres:: Connection ;
11
8
use router:: Router ;
12
- use serde:: {
13
- ser:: { SerializeStruct , Serializer } ,
14
- Serialize ,
15
- } ;
9
+ use serde:: { ser:: Serializer , Serialize } ;
16
10
use serde_json:: Value ;
17
11
18
12
// TODO: Add target name and versions
19
13
20
- #[ derive( Debug , Clone , PartialEq ) ]
14
+ #[ derive( Debug , Clone , PartialEq , Serialize ) ]
21
15
pub struct CrateDetails {
22
16
name : String ,
23
17
version : String ,
@@ -26,7 +20,9 @@ pub struct CrateDetails {
26
20
owners : Vec < ( String , String ) > ,
27
21
authors_json : Option < Value > ,
28
22
dependencies : Option < Value > ,
23
+ #[ serde( serialize_with = "optional_markdown" ) ]
29
24
readme : Option < String > ,
25
+ #[ serde( serialize_with = "optional_markdown" ) ]
30
26
rustdoc : Option < String > , // this is description_long in database
31
27
release_time : DateTime < Utc > ,
32
28
build_status : bool ,
@@ -50,60 +46,16 @@ pub struct CrateDetails {
50
46
documentation_url : Option < String > ,
51
47
}
52
48
53
- impl Serialize for CrateDetails {
54
- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
55
- where
56
- S : Serializer ,
57
- {
58
- // Make sure that the length parameter passed to serde is correct by
59
- // adding the someness of `readme` and `rustdoc` to the total. `true`
60
- // is 1 and `false` is 0, so it increments if the value is some (and therefore
61
- // needs to be serialized)
62
- let mut state = serializer. serialize_struct (
63
- "CrateDetails" ,
64
- 26 + self . readme . is_some ( ) as usize + self . rustdoc . is_some ( ) as usize ,
65
- ) ?;
66
-
67
- state. serialize_field ( "metadata" , & self . metadata ) ?;
68
- state. serialize_field ( "name" , & self . name ) ?;
69
- state. serialize_field ( "version" , & self . version ) ?;
70
- state. serialize_field ( "description" , & self . description ) ?;
71
- state. serialize_field ( "authors" , & self . authors ) ?;
72
- state. serialize_field ( "owners" , & self . owners ) ?;
73
- state. serialize_field ( "authors_json" , & self . authors_json ) ?;
74
- state. serialize_field ( "dependencies" , & self . dependencies ) ?;
75
-
76
- if let Some ( ref readme) = self . readme {
77
- state. serialize_field ( "readme" , & render_markdown ( & readme) ) ?;
78
- }
79
-
80
- if let Some ( ref rustdoc) = self . rustdoc {
81
- state. serialize_field ( "rustdoc" , & render_markdown ( & rustdoc) ) ?;
82
- }
83
-
84
- state. serialize_field ( "release_time" , & duration_to_str ( self . release_time ) ) ?;
85
- state. serialize_field ( "build_status" , & self . build_status ) ?;
86
- state. serialize_field ( "last_successful_build" , & self . last_successful_build ) ?;
87
- state. serialize_field ( "rustdoc_status" , & self . rustdoc_status ) ?;
88
- state. serialize_field ( "repository_url" , & self . repository_url ) ?;
89
- state. serialize_field ( "homepage_url" , & self . homepage_url ) ?;
90
- state. serialize_field ( "keywords" , & self . keywords ) ?;
91
- state. serialize_field ( "have_examples" , & self . have_examples ) ?;
92
- state. serialize_field ( "target_name" , & self . target_name ) ?;
93
- state. serialize_field ( "releases" , & self . releases ) ?;
94
- state. serialize_field ( "github" , & self . github ) ?;
95
- state. serialize_field ( "github_stars" , & self . github_stars ) ?;
96
- state. serialize_field ( "github_forks" , & self . github_forks ) ?;
97
- state. serialize_field ( "github_issues" , & self . github_issues ) ?;
98
- state. serialize_field ( "metadata" , & self . metadata ) ?;
99
- state. serialize_field ( "is_library" , & self . is_library ) ?;
100
- state. serialize_field ( "doc_targets" , & self . doc_targets ) ?;
101
- state. serialize_field ( "yanked" , & self . yanked ) ?;
102
- state. serialize_field ( "license" , & self . license ) ?;
103
- state. serialize_field ( "documentation_url" , & self . documentation_url ) ?;
104
-
105
- state. end ( )
49
+ fn optional_markdown < S > ( markdown : & Option < String > , serializer : S ) -> Result < S :: Ok , S :: Error >
50
+ where
51
+ S : Serializer ,
52
+ {
53
+ if let Some ( ref markdown) = markdown {
54
+ Some ( render_markdown ( & markdown) )
55
+ } else {
56
+ None
106
57
}
58
+ . serialize ( serializer)
107
59
}
108
60
109
61
#[ derive( Debug , Clone , Eq , PartialEq , Serialize ) ]
@@ -353,6 +305,15 @@ fn map_to_release(conn: &Connection, crate_id: i32, version: String) -> Release
353
305
}
354
306
}
355
307
308
+ #[ derive( Debug , Clone , PartialEq , Serialize ) ]
309
+ struct CrateDetailsPage {
310
+ details : Option < CrateDetails > ,
311
+ }
312
+
313
+ impl_webpage ! {
314
+ CrateDetailsPage = "crate/details.html" ,
315
+ }
316
+
356
317
pub fn crate_details_handler ( req : & mut Request ) -> IronResult < Response > {
357
318
let router = extension ! ( req, Router ) ;
358
319
// this handler must always called with a crate name
@@ -365,12 +326,9 @@ pub fn crate_details_handler(req: &mut Request) -> IronResult<Response> {
365
326
Some ( MatchSemver :: Exact ( ( version, _) ) ) => {
366
327
let details = CrateDetails :: new ( & conn, & name, & version) ;
367
328
368
- Page :: new ( details)
369
- . set_true ( "show_package_navigation" )
370
- . set_true ( "javascript_highlightjs" )
371
- . set_true ( "package_navigation_crate_tab" )
372
- . to_resp ( "crate_details" )
329
+ CrateDetailsPage { details } . into_response ( req)
373
330
}
331
+
374
332
Some ( MatchSemver :: Semver ( ( version, _) ) ) => {
375
333
let url = ctry ! (
376
334
req,
@@ -384,6 +342,7 @@ pub fn crate_details_handler(req: &mut Request) -> IronResult<Response> {
384
342
385
343
Ok ( super :: redirect ( url) )
386
344
}
345
+
387
346
None => Err ( IronError :: new ( Nope :: CrateNotFound , status:: NotFound ) ) ,
388
347
}
389
348
}
0 commit comments