use lsp_types::Uri;
use std::path::Path;
pub fn path_to_uri(path: &Path) -> Result<Uri, String> {
let absolute =
if path.is_absolute() { path.to_path_buf() } else { std::env::current_dir().unwrap_or_default().join(path) };
let absolute = absolute.canonicalize().unwrap_or(absolute);
#[cfg(windows)]
let uri_str = {
let path_str = absolute.to_string_lossy().replace('\\', "/");
format!("file:///{}", path_str)
};
#[cfg(not(windows))]
let uri_str = format!("file://{}", absolute.display());
uri_str.parse().map_err(|e| format!("Invalid path '{}': {e}", absolute.display()))
}
pub fn uri_to_path(uri: &Uri) -> String {
let uri_str = uri.as_str();
if let Some(path) = uri_str.strip_prefix("file://") {
if path.starts_with('/') && path.len() > 2 && path.chars().nth(2) == Some(':') {
path[1..].to_string()
} else {
path.to_string()
}
} else {
uri_str.to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::Path;
#[test]
fn test_path_to_uri_absolute() {
let uri = path_to_uri(Path::new("/src/main.rs")).unwrap();
assert_eq!(uri.as_str(), "file:///src/main.rs");
}
#[test]
fn test_uri_to_path_basic() {
let uri: Uri = "file:///src/main.rs".parse().unwrap();
assert_eq!(uri_to_path(&uri), "/src/main.rs");
}
#[test]
fn test_roundtrip() {
let path = Path::new("/home/user/project/src/lib.rs");
let uri = path_to_uri(path).unwrap();
let back = uri_to_path(&uri);
assert_eq!(back, path.to_str().unwrap());
}
}