use super::*;
pub(crate) const fn strip_prefix<'a>(value: &'a str, prefix: &str) -> Option<&'a str> {
let value_bytes = value.as_bytes();
let prefix_bytes = prefix.as_bytes();
if prefix_bytes.len() > value_bytes.len() {
return None;
}
let mut index = 0;
while index < prefix_bytes.len() {
if value_bytes[index] != prefix_bytes[index] {
return None;
}
index += 1;
}
let (_, rest) = value_bytes.split_at(index);
match core::str::from_utf8(rest) {
Ok(text) => Some(text),
Err(_) => None,
}
}
pub const fn strip_path_prefix<'a>(value: &'a str, prefix: &str) -> Option<&'a str> {
let value_bytes = value.as_bytes();
let prefix_bytes = prefix.as_bytes();
if prefix_bytes.len() > value_bytes.len() {
return None;
}
let mut index = 0;
while index < prefix_bytes.len() {
let left = value_bytes[index];
let right = prefix_bytes[index];
if left != right && !(is_separator(left) && is_separator(right)) {
return None;
}
index += 1;
}
let (_, rest) = value_bytes.split_at(index);
let prefix_ends_on_separator = match prefix_bytes.len() {
0 => false,
length => is_separator(prefix_bytes[length - 1]),
};
if !prefix_ends_on_separator
&& let Some(next) = rest.first()
&& !is_separator(*next)
{
return None;
}
match core::str::from_utf8(rest) {
Ok(text) => Some(text),
Err(_) => None,
}
}
pub const fn last_path_segment(path: &str) -> &str {
let bytes = path.as_bytes();
let mut index = bytes.len();
while index > 0 {
index -= 1;
if bytes[index] == b':' {
let (_, rest) = bytes.split_at(index + 1);
return match core::str::from_utf8(rest) {
Ok(text) => text,
Err(_) => path,
};
}
}
path
}
pub const fn manifest_relative_source<'a>(manifest_dir: &str, file: &'a str) -> &'a str {
let after_manifest = match strip_path_prefix(file, manifest_dir) {
Some(rest) => rest,
None => return file,
};
let after_separator = strip_leading_separator(after_manifest);
match strip_prefix(after_separator, "src/") {
Some(rest) => rest,
None => match strip_prefix(after_separator, "src\\") {
Some(rest) => rest,
None => after_separator,
},
}
}