pub const CLOUDREVE_URI_PREFIX: &str = "cloudreve://my/";
pub fn path_to_uri(path: &str) -> String {
if path.starts_with("cloudreve://") {
return path.to_string();
}
let trimmed_path = path.strip_prefix('/').unwrap_or(path);
format!("{}{}", CLOUDREVE_URI_PREFIX, trimmed_path)
}
pub fn is_valid_uri(uri: &str) -> bool {
uri.starts_with(CLOUDREVE_URI_PREFIX) && uri.len() >= CLOUDREVE_URI_PREFIX.len()
}
pub fn uri_to_path(uri: &str) -> Result<&str, String> {
if !uri.starts_with(CLOUDREVE_URI_PREFIX) {
return Err(format!(
"Invalid Cloudreve URI: expected format 'cloudreve://my/...', got: {}",
uri
));
}
let path = &uri[CLOUDREVE_URI_PREFIX.len() - 1..];
Ok(path)
}
pub fn uri_to_decoded_path(uri: &str) -> Result<String, String> {
let raw = uri_to_path(uri)?;
Ok(urlencoding::decode(raw)
.map(|decoded| decoded.into_owned())
.unwrap_or_else(|_| raw.to_string()))
}
pub fn paths_to_uris(paths: &[&str]) -> Vec<String> {
paths.iter().map(|p| path_to_uri(p)).collect()
}
pub fn search_uri(path: &str, keyword: &str, case_folding: bool) -> String {
let scope = path
.split('/')
.filter(|segment| !segment.is_empty())
.map(|segment| urlencoding::encode(segment).into_owned())
.collect::<Vec<String>>()
.join("/");
format!(
"{}{}?name={}&case_folding={}",
CLOUDREVE_URI_PREFIX,
scope,
urlencoding::encode(keyword),
case_folding
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_path_to_uri_absolute() {
assert_eq!(
path_to_uri("/path/to/file.txt"),
"cloudreve://my/path/to/file.txt"
);
}
#[test]
fn test_path_to_uri_relative() {
assert_eq!(
path_to_uri("path/to/file.txt"),
"cloudreve://my/path/to/file.txt"
);
}
#[test]
fn test_path_to_uri_already_uri() {
assert_eq!(
path_to_uri("cloudreve://my/path/to/file.txt"),
"cloudreve://my/path/to/file.txt"
);
}
#[test]
fn test_path_to_uri_root() {
assert_eq!(path_to_uri("/"), "cloudreve://my/");
}
#[test]
fn test_is_valid_uri() {
assert!(is_valid_uri("cloudreve://my/path/to/file.txt"));
assert!(is_valid_uri("cloudreve://my/"));
assert!(!is_valid_uri("/path/to/file.txt"));
assert!(!is_valid_uri("path/to/file.txt"));
assert!(!is_valid_uri("cloudreve://"));
}
#[test]
fn test_uri_to_path() {
assert_eq!(
uri_to_path("cloudreve://my/path/to/file.txt").unwrap(),
"/path/to/file.txt"
);
assert_eq!(uri_to_path("cloudreve://my/").unwrap(), "/");
}
#[test]
fn test_uri_to_path_invalid() {
assert!(uri_to_path("/path/to/file.txt").is_err());
assert!(uri_to_path("cloudreve://").is_err());
}
#[test]
fn test_paths_to_uris() {
let paths = vec!["/file1.txt", "file2.txt", "cloudreve://my/file3.txt"];
let uris = paths_to_uris(&paths);
assert_eq!(
uris,
vec![
"cloudreve://my/file1.txt",
"cloudreve://my/file2.txt",
"cloudreve://my/file3.txt"
]
);
}
}