{"id":21586036,"url":"https://github.com/magiclen/path-absolutize","last_synced_at":"2025-04-05T23:06:36.951Z","repository":{"id":32886676,"uuid":"145195475","full_name":"magiclen/path-absolutize","owner":"magiclen","description":"A library for extending `Path` and `PathBuf` in order to get an absolute path and remove the containing dots.","archived":false,"fork":false,"pushed_at":"2023-09-09T11:35:03.000Z","size":83,"stargazers_count":64,"open_issues_count":4,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-29T22:07:12.973Z","etag":null,"topics":["linux","macos","path","rust","windows"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/magiclen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-08-18T06:18:04.000Z","updated_at":"2025-03-15T09:20:15.000Z","dependencies_parsed_at":"2023-11-18T00:13:21.562Z","dependency_job_id":"b5101897-b889-441f-8852-6c310ba24cba","html_url":"https://github.com/magiclen/path-absolutize","commit_stats":{"total_commits":64,"total_committers":5,"mean_commits":12.8,"dds":0.0625,"last_synced_commit":"0882f98f7864247c17586c19d75b2c3a7eb70d42"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magiclen%2Fpath-absolutize","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magiclen%2Fpath-absolutize/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magiclen%2Fpath-absolutize/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magiclen%2Fpath-absolutize/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/magiclen","download_url":"https://codeload.github.com/magiclen/path-absolutize/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247411229,"owners_count":20934653,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linux","macos","path","rust","windows"],"created_at":"2024-11-24T15:12:28.484Z","updated_at":"2025-04-05T23:06:36.914Z","avatar_url":"https://github.com/magiclen.png","language":"Rust","readme":"Path Absolutize\n====================\n\n[![CI](https://github.com/magiclen/path-absolutize/actions/workflows/ci.yml/badge.svg)](https://github.com/magiclen/path-absolutize/actions/workflows/ci.yml)\n\nThis is a library for extending `Path` and `PathBuf` in order to get an absolute path and remove the containing dots.\n\nThe difference between `absolutize` and `canonicalize` methods is that `absolutize` does not care about whether the file exists and what the file really is.\n\nPlease read the following examples to know the parsing rules.\n\n## Examples\n\nThere are two methods you can use.\n\n### absolutize\n\nGet an absolute path.\n\nThe dots in a path will be parsed even if it is already an absolute path (which means the path starts with a `MAIN_SEPARATOR` on Unix-like systems).\n\n```rust\nuse std::path::Path;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"/path/to/123/456\");\n\nassert_eq!(\"/path/to/123/456\", p.absolutize().unwrap().to_str().unwrap());\n```\n\n```rust\nuse std::path::Path;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"/path/to/./123/../456\");\n\nassert_eq!(\"/path/to/456\", p.absolutize().unwrap().to_str().unwrap());\n```\n\nIf a path starts with a single dot, the dot means your program's **current working directory** (CWD).\n\n```rust\nuse std::path::Path;\nuse std::env;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"./path/to/123/456\");\n\nassert_eq!(Path::join(env::current_dir().unwrap().as_path(), Path::new(\"path/to/123/456\")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());\n```\n\nIf a path starts with a pair of dots, the dots means the parent of the CWD. If the CWD is **root**, the parent is still **root**.\n\n```rust\nuse std::path::Path;\nuse std::env;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"../path/to/123/456\");\n\nlet cwd = env::current_dir().unwrap();\n\nlet cwd_parent = cwd.parent();\n\nmatch cwd_parent {\n   Some(cwd_parent) =\u003e {\n       assert_eq!(Path::join(\u0026cwd_parent, Path::new(\"path/to/123/456\")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());\n   }\n   None =\u003e {\n       assert_eq!(Path::join(Path::new(\"/\"), Path::new(\"path/to/123/456\")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());\n   }\n}\n```\n\nA path which does not start with a `MAIN_SEPARATOR`, **Single Dot** and **Double Dots**, will act like having a single dot at the start when `absolutize` method is used.\n\n```rust\nuse std::path::Path;\nuse std::env;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"path/to/123/456\");\n\nassert_eq!(Path::join(env::current_dir().unwrap().as_path(), Path::new(\"path/to/123/456\")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());\n```\n\n```rust\nuse std::path::Path;\nuse std::env;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"path/../../to/123/456\");\n\nlet cwd = env::current_dir().unwrap();\n\nlet cwd_parent = cwd.parent();\n\nmatch cwd_parent {\n   Some(cwd_parent) =\u003e {\n       assert_eq!(Path::join(\u0026cwd_parent, Path::new(\"to/123/456\")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());\n   }\n   None =\u003e {\n       assert_eq!(Path::join(Path::new(\"/\"), Path::new(\"to/123/456\")).to_str().unwrap(), p.absolutize().unwrap().to_str().unwrap());\n   }\n}\n```\n\n### Starting from a given current working directory\n\nWith the `absolutize_from` function, you can provide the current working directory that the relative paths should be resolved from.\n\n```rust\nuse std::env;\nuse std::path::Path;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"../path/to/123/456\");\nlet cwd = env::current_dir().unwrap();\n\nprintln!(\"{}\", p.absolutize_from(cwd).unwrap().to_str().unwrap());\n```\n\n\n### absolutize_virtually\n\nGet an absolute path **only under a specific directory**.\n\nThe dots in a path will be parsed even if it is already an absolute path (which means the path starts with a `MAIN_SEPARATOR` on Unix-like systems).\n\n```rust\nuse std::path::Path;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"/path/to/123/456\");\n\nassert_eq!(\"/path/to/123/456\", p.absolutize_virtually(\"/\").unwrap().to_str().unwrap());\n```\n\n```rust\nuse std::path::Path;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"/path/to/./123/../456\");\n\nassert_eq!(\"/path/to/456\", p.absolutize_virtually(\"/\").unwrap().to_str().unwrap());\n```\n\nEvery absolute path should under the virtual root.\n\n```rust\nuse std::path::Path;\n\nuse std::io::ErrorKind;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"/path/to/123/456\");\n\nassert_eq!(ErrorKind::InvalidInput, p.absolutize_virtually(\"/virtual/root\").unwrap_err().kind());\n```\n\nEvery relative path should under the virtual root.\n\n```rust\nuse std::path::Path;\n\nuse std::io::ErrorKind;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"./path/to/123/456\");\n\nassert_eq!(ErrorKind::InvalidInput, p.absolutize_virtually(\"/virtual/root\").unwrap_err().kind());\n```\n\n```rust\nuse std::path::Path;\n\nuse std::io::ErrorKind;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"../path/to/123/456\");\n\nassert_eq!(ErrorKind::InvalidInput, p.absolutize_virtually(\"/virtual/root\").unwrap_err().kind());\n```\n\nA path which does not start with a `MAIN_SEPARATOR`, **Single Dot** and **Double Dots**, will be located in the virtual root after the `absolutize_virtually` method is used.\n\n```rust\nuse std::path::Path;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"path/to/123/456\");\n\nassert_eq!(\"/virtual/root/path/to/123/456\", p.absolutize_virtually(\"/virtual/root\").unwrap().to_str().unwrap());\n```\n\n```rust\nuse std::path::Path;\n\nuse path_absolutize::*;\n\nlet p = Path::new(\"path/to/../../../../123/456\");\n\nassert_eq!(\"/virtual/root/123/456\", p.absolutize_virtually(\"/virtual/root\").unwrap().to_str().unwrap());\n```\n\n## Caching\n\nBy default, the `absolutize` method and the `absolutize_virtually` method create a new `PathBuf` instance of the CWD every time in their operation. Although it allows us to safely change the CWD at runtime by the program itself (e.g. using the `std::env::set_current_dir` function) or outside controls (e.g. using gdb to call `chdir`), we don't need that in most cases.\n\nIn order to parse paths with better performance, this crate provides three ways to cache the CWD.\n\n### once_cell_cache\n\nEnabling the `once_cell_cache` feature can let this crate use `once_cell` to cache the CWD. It's thread-safe and does not need to modify any code, but once the CWD is cached, it cannot be changed anymore at runtime.\n\n```toml\n[dependencies.path-absolutize]\nversion = \"*\"\nfeatures = [\"once_cell_cache\"]\n```\n\n### lazy_static_cache\n\nEnabling the `lazy_static_cache` feature can let this crate use `lazy_static` to cache the CWD. It's thread-safe and does not need to modify any code, but once the CWD is cached, it cannot be changed anymore at runtime.\n\n```toml\n[dependencies.path-absolutize]\nversion = \"*\"\nfeatures = [\"lazy_static_cache\"]\n```\n\n### unsafe_cache\n\nEnabling the `unsafe_cache` feature can let this crate use a mutable static variable to cache the CWD. It allows the program to change the CWD at runtime by the program itself, but it's not thread-safe.\n\nYou need to use the `update_cwd` function to initialize the CWD first. The function should also be used to update the CWD after the CWD is changed.\n\n```toml\n[dependencies.path-absolutize]\nversion = \"*\"\nfeatures = [\"unsafe_cache\"]\n```\n\n```rust\nuse std::path::Path;\n\nuse path_absolutize::*;\n\nunsafe {\n    update_cwd();\n}\n\nlet p = Path::new(\"./path/to/123/456\");\n\nprintln!(\"{}\", p.absolutize().unwrap().to_str().unwrap());\n\nstd::env::set_current_dir(\"/\").unwrap();\n\nunsafe {\n    update_cwd();\n}\n\nprintln!(\"{}\", p.absolutize().unwrap().to_str().unwrap());\n```\n\n## Benchmark\n\n#### No-cache\n\n```bash\ncargo bench\n```\n\n#### once_cell_cache\n\n```bash\ncargo bench --features once_cell_cache\n```\n\n#### lazy_static_cache\n\n```bash\ncargo bench --features lazy_static_cache\n```\n\n#### unsafe_cache\n\n```bash\ncargo bench --features unsafe_cache\n```\n\n## Crates.io\n\nhttps://crates.io/crates/path-absolutize\n\n## Documentation\n\nhttps://docs.rs/path-absolutize\n\n## License\n\n[MIT](LICENSE)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagiclen%2Fpath-absolutize","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmagiclen%2Fpath-absolutize","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagiclen%2Fpath-absolutize/lists"}