-
Notifications
You must be signed in to change notification settings - Fork 965
Open doc for specific topic #2019
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
use crate::errors::*; | ||
use std::ffi::OsString; | ||
use std::fs; | ||
use std::path::{Path, PathBuf}; | ||
|
||
struct DocData<'a> { | ||
topic: &'a str, | ||
subtopic: &'a str, | ||
root: &'a Path, | ||
} | ||
|
||
fn no_document(topic: &str) -> Result<PathBuf> { | ||
Err(format!("No document for '{}'", topic).into()) | ||
} | ||
|
||
fn index_html(doc: &DocData, wpath: &Path) -> Option<PathBuf> { | ||
let indexhtml = wpath.join("index.html"); | ||
match &doc.root.join(&indexhtml).exists() { | ||
true => Some(indexhtml), | ||
false => None, | ||
} | ||
} | ||
|
||
fn dir_into_vec(dir: &PathBuf) -> Result<Vec<OsString>> { | ||
let entries = fs::read_dir(dir).chain_err(|| format!("Opening directory {:?}", dir))?; | ||
let mut v = Vec::new(); | ||
for entry in entries { | ||
let entry = entry?; | ||
v.push(entry.file_name()); | ||
} | ||
Ok(v) | ||
} | ||
|
||
fn search_path(doc: &DocData, wpath: &Path, keywords: &[&str]) -> Result<PathBuf> { | ||
let dir = &doc.root.join(&wpath); | ||
if dir.is_dir() { | ||
let entries = dir_into_vec(dir)?; | ||
for k in keywords { | ||
let filename = &format!("{}.{}.html", k, doc.subtopic); | ||
if entries.contains(&OsString::from(filename)) { | ||
return Ok(dir.join(filename)); | ||
} | ||
} | ||
no_document(doc.topic) | ||
} else { | ||
no_document(doc.topic) | ||
} | ||
} | ||
|
||
pub fn local_path(root: &Path, topic: &str) -> Result<PathBuf> { | ||
let keywords_top = ["macro", "keyword", "primitive"]; | ||
let keywords_mod = ["fn", "struct", "trait", "enum", "type", "constant"]; | ||
|
||
let topic_vec: Vec<&str> = topic.split("::").collect(); | ||
let work_path = topic_vec.iter().fold(PathBuf::new(), |acc, e| acc.join(e)); | ||
|
||
let doc = DocData { | ||
topic: &topic, | ||
subtopic: topic_vec[topic_vec.len() - 1], | ||
root, | ||
}; | ||
|
||
/************************** | ||
* Please ensure tests/mock/topical_doc_data.rs is UPDATED to reflect | ||
* any change in functionality. | ||
|
||
Argument File directory | ||
|
||
# len() == 1 Return index.html | ||
std std/index.html root/std | ||
core core/index.html root/core | ||
alloc alloc/index.html root/core | ||
KKK std/keyword.KKK.html root/std | ||
PPP std/primitive.PPP.html root/std | ||
MMM std/macro.MMM.html root/std | ||
|
||
|
||
# len() == 2 not ending in :: | ||
MMM std/macro.MMM.html root/std | ||
KKK std/keyword.KKK.html root/std | ||
PPP std/primitive.PPP.html root/std | ||
MMM core/macro.MMM.html root/core | ||
MMM alloc/macro.MMM.html root/alloc | ||
# If above fail, try module | ||
std::module std/module/index.html root/std/module | ||
core::module core/module/index.html root/core/module | ||
alloc::module alloc/module/index.html alloc/core/module | ||
|
||
# len() == 2, ending with :: | ||
std::module std/module/index.html root/std/module | ||
core::module core/module/index.html root/core/module | ||
alloc::module alloc/module/index.html alloc/core/module | ||
|
||
# len() > 2 | ||
# search for index.html in rel_path | ||
std::AAA::MMM std/AAA/MMM/index.html root/std/AAA/MMM | ||
|
||
# OR check if parent() dir exists and search for fn/sturct/etc | ||
std::AAA::FFF std/AAA/fn.FFF9.html root/std/AAA | ||
std::AAA::SSS std/AAA/struct.SSS.html root/std/AAA | ||
core:AAA::SSS std/AAA/struct.SSS.html root/coreAAA | ||
alloc:AAA::SSS std/AAA/struct.SSS.html root/coreAAA | ||
std::AAA::TTT std/2222/trait.TTT.html root/std/AAA | ||
std::AAA::EEE std/2222/enum.EEE.html root/std/AAA | ||
std::AAA::TTT std/2222/type.TTT.html root/std/AAA | ||
std::AAA::CCC std/2222/constant.CCC.html root/std/AAA | ||
|
||
**************************/ | ||
|
||
// topic.split.count cannot be 0 | ||
let subpath_os_path = match topic_vec.len() { | ||
1 => match topic { | ||
"std" | "core" | "alloc" => match index_html(&doc, &work_path) { | ||
Some(f) => f, | ||
None => no_document(doc.topic)?, | ||
}, | ||
_ => { | ||
let std = PathBuf::from("std"); | ||
search_path(&doc, &std, &keywords_top)? | ||
} | ||
}, | ||
2 => match index_html(&doc, &work_path) { | ||
Some(f) => f, | ||
None => { | ||
let parent = work_path.parent().unwrap(); | ||
search_path(&doc, &parent, &keywords_top)? | ||
} | ||
}, | ||
_ => match index_html(&doc, &work_path) { | ||
Some(f) => f, | ||
None => { | ||
// len > 2, guaranteed to have a parent, safe to unwrap | ||
let parent = work_path.parent().unwrap(); | ||
search_path(&doc, &parent, &keywords_mod)? | ||
} | ||
}, | ||
}; | ||
// The path and filename were validated to be existing on the filesystem. | ||
// It should be safe to unwrap, or worth panicking. | ||
Ok(subpath_os_path) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use std::path::PathBuf; | ||
|
||
// Paths are written as a string in the UNIX format to make it easy | ||
// to maintain. | ||
static TEST_CASES: &[&[&str]] = &[ | ||
&["core", "core/index.html"], | ||
&["core::arch", "core/arch/index.html"], | ||
&["fn", "std/keyword.fn.html"], | ||
&["std::fs", "std/fs/index.html"], | ||
&["std::fs::read_dir", "std/fs/fn.read_dir.html"], | ||
&["std::io::Bytes", "std/io/struct.Bytes.html"], | ||
&["std::iter::Sum", "std/iter/trait.Sum.html"], | ||
&["std::io::error::Result", "std/io/error/type.Result.html"], | ||
&["usize", "std/primitive.usize.html"], | ||
&["eprintln", "std/macro.eprintln.html"], | ||
&["alloc::format", "alloc/macro.format.html"], | ||
]; | ||
|
||
fn repath(origin: &str) -> String { | ||
// Add doc prefix and rewrite string paths for the current platform | ||
let with_prefix = "share/doc/rust/html/".to_owned() + origin; | ||
let splitted = with_prefix.split("/"); | ||
let repathed = splitted.fold(PathBuf::new(), |acc, e| acc.join(e)); | ||
repathed.into_os_string().into_string().unwrap() | ||
} | ||
|
||
pub fn test_cases<'a>() -> impl Iterator<Item = (&'a str, String)> { | ||
TEST_CASES.iter().map(|x| (x[0], repath(x[1]))) | ||
} | ||
|
||
pub fn paths() -> impl Iterator<Item = String> { | ||
TEST_CASES.iter().map(|x| repath(x[1])) | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be worth referencing your
tests/mock/topical_doc_data.rs
file here to say that if additional functionality is added, it should be added to the tests so that it can be verified. That way we'll keep support for new doc sections properly supported ifstd
is split up further.