Skip to content

Commit 9e415bb

Browse files
author
Joshua Nelson
committed
Revert "Source"
This reverts commit 754b91d.
1 parent aa6f044 commit 9e415bb

File tree

3 files changed

+162
-146
lines changed

3 files changed

+162
-146
lines changed

src/web/source.rs

+124-41
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,69 @@
11
//! Source code browser
22
3-
use crate::{
4-
db::Pool,
5-
impl_webpage,
6-
web::{error::Nope, file::File as DbFile, page::WebPage, MetaData},
7-
Config,
8-
};
9-
use iron::{status::Status, IronError, IronResult, Request, Response};
3+
use super::file::File as DbFile;
4+
use super::page::Page;
5+
use super::MetaData;
6+
use crate::db::Pool;
7+
use crate::Config;
8+
use iron::prelude::*;
109
use postgres::Connection;
1110
use router::Router;
12-
use serde::Serialize;
11+
use serde::ser::{Serialize, SerializeStruct, Serializer};
1312
use serde_json::Value;
1413
use std::cmp::Ordering;
14+
use std::collections::HashMap;
1515

16-
/// A source file's name and mime type
17-
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Serialize)]
16+
/// A source file's type
17+
#[derive(PartialEq, PartialOrd)]
18+
enum FileType {
19+
Dir,
20+
Text,
21+
Binary,
22+
RustSource,
23+
}
24+
25+
/// A source file
26+
#[derive(PartialEq, PartialOrd)]
1827
struct File {
19-
/// The name of the file
2028
name: String,
21-
/// The mime type of the file
22-
mime: String,
29+
file_type: FileType,
2330
}
2431

2532
/// A list of source files
26-
#[derive(Debug, Clone, PartialEq, Serialize)]
2733
struct FileList {
2834
metadata: MetaData,
2935
files: Vec<File>,
3036
}
3137

38+
impl Serialize for FileList {
39+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
40+
where
41+
S: Serializer,
42+
{
43+
let mut state = serializer.serialize_struct("FileList", 2)?;
44+
state.serialize_field("metadata", &self.metadata)?;
45+
46+
let mut files = Vec::with_capacity(self.files.len());
47+
for file in &self.files {
48+
let mut map = HashMap::with_capacity(2);
49+
map.insert("name", Value::String(file.name.to_owned()));
50+
51+
let file_type = match file.file_type {
52+
FileType::Dir => "file_type_dir",
53+
FileType::Text => "file_type_text",
54+
FileType::Binary => "file_type_binary",
55+
FileType::RustSource => "file_type_rust_source",
56+
};
57+
map.insert(file_type, Value::Bool(true));
58+
59+
files.push(map);
60+
}
61+
state.serialize_field("files", &files)?;
62+
63+
state.end()
64+
}
65+
}
66+
3267
impl FileList {
3368
/// Gets FileList from a request path
3469
///
@@ -91,15 +126,19 @@ impl FileList {
91126
let path_splited: Vec<&str> = path.split('/').collect();
92127

93128
// if path have '/' it is a directory
94-
let mime = if path_splited.len() > 1 {
95-
"dir".to_owned()
129+
let ftype = if path_splited.len() > 1 {
130+
FileType::Dir
131+
} else if mime.starts_with("text") && path_splited[0].ends_with(".rs") {
132+
FileType::RustSource
133+
} else if mime.starts_with("text") {
134+
FileType::Text
96135
} else {
97-
mime.to_owned()
136+
FileType::Binary
98137
};
99138

100139
let file = File {
101140
name: path_splited[0].to_owned(),
102-
mime,
141+
file_type: ftype,
103142
};
104143

105144
// avoid adding duplicates, a directory may occur more than once
@@ -116,9 +155,9 @@ impl FileList {
116155

117156
file_list.sort_by(|a, b| {
118157
// directories must be listed first
119-
if a.mime == "dir" && b.mime != "dir" {
158+
if a.file_type == FileType::Dir && b.file_type != FileType::Dir {
120159
Ordering::Less
121-
} else if a.mime != "dir" && b.mime == "dir" {
160+
} else if a.file_type != FileType::Dir && b.file_type == FileType::Dir {
122161
Ordering::Greater
123162
} else {
124163
a.name.to_lowercase().cmp(&b.name.to_lowercase())
@@ -142,18 +181,6 @@ impl FileList {
142181
}
143182
}
144183

145-
#[derive(Debug, Clone, PartialEq, Serialize)]
146-
struct SourcePage {
147-
file_list: FileList,
148-
show_parent_link: bool,
149-
file_content: Option<String>,
150-
is_rust_source: bool,
151-
}
152-
153-
impl_webpage! {
154-
SourcePage = "crate/source.html",
155-
}
156-
157184
pub fn source_browser_handler(req: &mut Request) -> IronResult<Response> {
158185
let router = extension!(req, Router);
159186
let name = cexpect!(req, router.find("name"));
@@ -195,7 +222,7 @@ pub fn source_browser_handler(req: &mut Request) -> IronResult<Response> {
195222
None
196223
};
197224

198-
let (file_content, is_rust_source) = if let Some(file) = file {
225+
let (content, is_rust_source) = if let Some(file) = file {
199226
// serve the file with DatabaseFileHandler if file isn't text and not empty
200227
if !file.0.mime.starts_with("text") && !file.is_empty() {
201228
return Ok(file.serve());
@@ -211,21 +238,77 @@ pub fn source_browser_handler(req: &mut Request) -> IronResult<Response> {
211238
(None, false)
212239
};
213240

214-
let file_list = FileList::from_path(&conn, &name, &version, &req_path)
215-
.ok_or_else(|| IronError::new(Nope::NoResults, Status::NotFound))?;
241+
let list = FileList::from_path(&conn, &name, &version, &req_path);
242+
if list.is_none() {
243+
use super::error::Nope;
244+
use iron::status;
245+
return Err(IronError::new(Nope::NoResults, status::NotFound));
246+
}
247+
248+
let page = Page::new(list)
249+
.set_bool("show_parent_link", !req_path.is_empty())
250+
.set_true("javascript_highlightjs")
251+
.set_true("show_package_navigation")
252+
.set_true("package_source_tab");
216253

217-
SourcePage {
218-
file_list,
219-
show_parent_link: !req_path.is_empty(),
220-
file_content,
221-
is_rust_source,
254+
if let Some(content) = content {
255+
page.set("file_content", &content)
256+
.set_bool("file_content_rust_source", is_rust_source)
257+
.to_resp("source")
258+
} else {
259+
page.to_resp("source")
222260
}
223-
.into_response(req)
224261
}
225262

226263
#[cfg(test)]
227264
mod tests {
265+
use super::*;
228266
use crate::test::{assert_success, wrapper};
267+
use serde_json::json;
268+
269+
#[test]
270+
fn serialize_file_list() {
271+
let file_list = FileList {
272+
metadata: MetaData {
273+
name: "rcc".to_string(),
274+
version: "0.0.0".to_string(),
275+
description: Some("it compiles an unholy language".to_string()),
276+
target_name: None,
277+
rustdoc_status: true,
278+
default_target: "x86_64-unknown-linux-gnu".to_string(),
279+
},
280+
files: vec![
281+
File {
282+
name: "main.rs".to_string(),
283+
file_type: FileType::RustSource,
284+
},
285+
File {
286+
name: "lib.rs".to_string(),
287+
file_type: FileType::RustSource,
288+
},
289+
],
290+
};
291+
292+
let correct_json = json!({
293+
"metadata": {
294+
"name": "rcc",
295+
"version": "0.0.0",
296+
"description": "it compiles an unholy language",
297+
"target_name": null,
298+
"rustdoc_status": true,
299+
"default_target": "x86_64-unknown-linux-gnu"
300+
},
301+
"files": [{
302+
"name": "main.rs",
303+
"file_type_rust_source": true
304+
}, {
305+
"name": "lib.rs",
306+
"file_type_rust_source": true
307+
}],
308+
});
309+
310+
assert_eq!(correct_json, serde_json::to_value(&file_list).unwrap(),);
311+
}
229312

230313
#[test]
231314
fn cargo_ok_not_skipped() {

templates/source.hbs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{{> header}}
2+
3+
4+
{{#with content}}
5+
<div class="container package-page-container">
6+
<div class="pure-g">
7+
<div class="pure-u-1 {{#if ../varss.file_content}}pure-u-sm-7-24 pure-u-md-5-24{{/if}}">
8+
<div class="pure-menu package-menu">
9+
<ul class="pure-menu-list">
10+
{{#if ../varsb.show_parent_link}}
11+
<li class="pure-menu-item">
12+
<a href="../" class="pure-menu-link"><i class="fa fa-fw fa-folder-open-o"></i> ..</a>
13+
</li>
14+
{{/if}}
15+
{{#each files}}
16+
<li class="pure-menu-item">
17+
<a href="./{{name}}{{#if file_type_dir }}/{{/if}}" class="pure-menu-link">
18+
{{log this}}
19+
{{#if file_type_dir }}<i class="fa fa-fw fa-folder-open-o"></i>{{/if}}
20+
{{#if file_type_text }}<i class="fa fa-fw fa-file-text-o"></i>{{/if}}
21+
{{#if file_type_rust_source }}<i class="fa fa-fw fa-file-code-o"></i>{{/if}}
22+
{{#if file_type_binary }}<i class="fa fa-fw fa-file-archive-o"></i>{{/if}}
23+
{{name}}</a>
24+
</li>
25+
{{/each}}
26+
</ul>
27+
</div>
28+
</div>
29+
{{#if ../varss.file_content}}
30+
<div class="pure-u-1 pure-u-sm-17-24 pure-u-md-19-24">
31+
<pre><code{{#if ../varsb.file_content_rust_source}} class="rust"{{/if}}>{{ ../varss.file_content }}</code></pre>
32+
</div>
33+
{{/if}}
34+
</div>
35+
</div>
36+
{{/with}}
37+
38+
{{> footer}}

tera-templates/crate/source.html

-105
This file was deleted.

0 commit comments

Comments
 (0)