use cov::IntoStringLossy;
use home::cargo_home;
use std::path::MAIN_SEPARATOR;
use std::str::FromStr;
const MACOS_RUSTSRC_DIR: &str = "/Users/travis/build/rust-lang/rust/";
const DOCKER_RUSTSRC_DIR: &str = "/checkout/";
const WINDOWS_RUSTSRC_DIR: &str = r"C:\projects\rust\";
lazy_static! {
static ref REGISTRY_PATH: String = {
let mut cargo_home = cargo_home().expect("$CARGO_HOME is undefined");
cargo_home.push("registry");
cargo_home.push("src");
let mut registry_path = cargo_home.into_string_lossy();
registry_path.push(MAIN_SEPARATOR);
registry_path
};
}
bitflags! {
pub struct SourceType: u8 {
const LOCAL = 1;
const MACROS = 2;
const UNKNOWN = 4;
const CRATES = 8;
const RUSTSRC = 16;
const DEFAULT = SourceType::LOCAL.bits | SourceType::MACROS.bits | SourceType::UNKNOWN.bits;
}
}
#[derive(Debug)]
pub struct UnsupportedSourceTypeName;
impl SourceType {
pub fn from_multi_str<'a, I>(strings: I) -> Result<SourceType, UnsupportedSourceTypeName>
where
I: Iterator<Item = &'a str>,
{
let mut res = SourceType::empty();
for s in strings {
res |= s.parse()?;
}
Ok(res)
}
pub fn prefix(self) -> &'static str {
match self {
SourceType::LOCAL => ".",
SourceType::RUSTSRC => "«rust»",
SourceType::CRATES => "«crates»",
_ => "",
}
}
}
impl FromStr for SourceType {
type Err = UnsupportedSourceTypeName;
fn from_str(s: &str) -> Result<SourceType, UnsupportedSourceTypeName> {
Ok(match s {
"local" => SourceType::LOCAL,
"macros" => SourceType::MACROS,
"rustsrc" => SourceType::RUSTSRC,
"crates" => SourceType::CRATES,
"unknown" => SourceType::UNKNOWN,
"all" => SourceType::all(),
_ => return Err(UnsupportedSourceTypeName),
})
}
}
pub fn identify_source_path(path: &str, crates_path: &str) -> (SourceType, usize) {
if path.starts_with(crates_path) {
(SourceType::LOCAL, crates_path.len())
} else if path.starts_with(&*REGISTRY_PATH) {
let subpath = &path[REGISTRY_PATH.len()..];
let first_slash = subpath.find(MAIN_SEPARATOR).map_or(0, |s| s + MAIN_SEPARATOR.len_utf8());
(SourceType::CRATES, REGISTRY_PATH.len() + first_slash)
} else if path.starts_with('<') && path.ends_with(" macros>") {
(SourceType::MACROS, 0)
} else if path.starts_with(MACOS_RUSTSRC_DIR) {
(SourceType::RUSTSRC, MACOS_RUSTSRC_DIR.len())
} else if path.starts_with(DOCKER_RUSTSRC_DIR) {
(SourceType::RUSTSRC, DOCKER_RUSTSRC_DIR.len())
} else if path.starts_with(WINDOWS_RUSTSRC_DIR) {
(SourceType::RUSTSRC, WINDOWS_RUSTSRC_DIR.len())
} else {
(SourceType::UNKNOWN, 0)
}
}