{"id":20198978,"url":"https://github.com/simongoricar/fs-more","last_synced_at":"2025-09-10T22:35:44.707Z","repository":{"id":197629673,"uuid":"689783086","full_name":"simongoricar/fs-more","owner":"simongoricar","description":"Convenient Rust file and directory operations, including scanning and copying/moving with progress.","archived":false,"fork":false,"pushed_at":"2025-05-02T17:03:03.000Z","size":760,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-13T22:29:21.165Z","etag":null,"topics":["copy","filesystem","move","progress","remove","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simongoricar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-10T22:00:47.000Z","updated_at":"2025-06-12T02:52:59.000Z","dependencies_parsed_at":"2024-05-13T12:55:53.350Z","dependency_job_id":"17e24be9-5a7a-4d58-8763-419f846fe92f","html_url":"https://github.com/simongoricar/fs-more","commit_stats":null,"previous_names":["defaultsimon/fs-more","simongoricar/fs-more"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/simongoricar/fs-more","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simongoricar%2Ffs-more","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simongoricar%2Ffs-more/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simongoricar%2Ffs-more/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simongoricar%2Ffs-more/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simongoricar","download_url":"https://codeload.github.com/simongoricar/fs-more/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simongoricar%2Ffs-more/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274536170,"owners_count":25303780,"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","status":"online","status_checked_at":"2025-09-10T02:00:12.551Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["copy","filesystem","move","progress","remove","rust"],"created_at":"2024-11-14T04:35:13.743Z","updated_at":"2025-09-10T22:35:44.685Z","avatar_url":"https://github.com/simongoricar.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"fs-more\n=======\n[![Crates.io Version](https://img.shields.io/crates/v/fs-more?style=flat-square)](https://crates.io/crates/fs-more)\n[![Minimum Supported Rust Version is 1.74.1](https://img.shields.io/badge/MSRV-1.74.1-brightgreen?style=flat-square)](https://releases.rs/docs/1.77.0/)\n[![License](https://img.shields.io/badge/license-MIT_OR_Apache--2.0-blue?style=flat-square)](https://github.com/simongoricar/fs-more/blob/master/LICENSE-MIT)\n[![Documentation](https://img.shields.io/badge/docs-published-green?style=flat-square)](https://docs.rs/fs-more)\n\n\n\nConvenient file and directory operations built on top of `std::fs` with improved error handling and in-depth configuration.\nIncludes copying and moving files or directories with progress reporting.\n\n\n## Main features\n- copy and move files or directories with:\n  - in-depth configuration options (existing destination file behaviour, copying depth, IO buffer sizes, etc.), and\n  - **progress reporting**, if wanted,\n- scan directories (with options such as scan depth and symlink behaviour), and\n- calculate file or directory sizes.\n\n\u003cbr\u003e\n\n\n## Usage\nTo add `fs-more` into your project, specify it as a dependency in your `Cargo.toml` file:\n```toml\nfs-more = \"0.8.1\"\n```\n\n\n## Examples\n\nCopying a file and getting updates on the progress:\n\n```rust,no_run\nuse std::path::Path;\n\nuse fs_more::file::CollidingFileBehaviour;\nuse fs_more::file::FileCopyWithProgressOptions;\nuse fs_more::file::FileCopyFinished;\n\n\nlet source_path = Path::new(\"./source-file.txt\");\nlet destination_path = Path::new(\"./destination-file.txt\");\n\nlet finished_copy = fs_more::file::copy_file_with_progress(\n    source_path,\n    destination_path,\n    FileCopyWithProgressOptions {\n        colliding_file_behaviour: CollidingFileBehaviour::Abort,\n        ..Default::default()\n    },\n    |progress| {\n        let percent_copied =\n            (progress.bytes_finished as f64) \n            / (progress.bytes_total as f64 * 100.0);\n\n        println!(\"Copied {:.2}% of the file!\", percent_copied);\n    }\n).unwrap();\n\nmatch finished_copy {\n    FileCopyFinished::Created { bytes_copied } =\u003e {\n        println!(\"Copied {bytes_copied} bytes into a fresh file!\");\n    }\n    FileCopyFinished::Overwritten { bytes_copied } =\u003e {\n        println!(\"Copied {bytes_copied} bytes over an existing file!\");\n    }\n    // ... (see documentation) ...\n    _ =\u003e {}\n};\n```\n\n\u003cbr\u003e\n\nMoving a directory and getting updates on the progress:\n\n```rust,no_run\nuse std::path::Path;\nuse fs_more::directory::DirectoryMoveWithProgressOptions;\nuse fs_more::directory::DestinationDirectoryRule;\n\n\nlet source_path = Path::new(\"./source-directory\");\nlet destination_path = Path::new(\"./destination-directory\");\n\nlet moved = fs_more::directory::move_directory_with_progress(\n    source_path,\n    destination_path,\n    DirectoryMoveWithProgressOptions {\n        destination_directory_rule: DestinationDirectoryRule::AllowEmpty,\n        ..Default::default()\n    },\n    |progress| {\n        let percent_moved =\n            (progress.bytes_finished as f64) / (progress.bytes_total as f64)\n            * 100.0;\n        println!(\n            \"Moved {:.2}% of the directory ({} files and {} directories so far).\",\n            percent_moved,\n            progress.files_moved,\n            progress.directories_created\n        );\n    }\n).unwrap();\n\nprintln!(\n    \"Moved {} bytes ({} files, {} directories)! Underlying strategy: {:?}.\",\n    moved.total_bytes_moved,\n    moved.files_moved,\n    moved.directories_moved,\n    moved.strategy_used\n);\n```\n\n\n\u003cbr\u003e\n\n## Feature flags\n\u003ctable\u003e\n\u003cthead\u003e\n  \u003ctr\u003e\n  \u003cth align=\"left\"\u003e\n\u003cstrong\u003e\u003ccode\u003edunce\u003c/code\u003e\u003c/strong\u003e\n\u003cspan style=\"font-weight: normal\"\u003e\u0026nbsp;(\u003ci\u003eenabled\u003c/i\u003e by default)\u003c/span\u003e\n  \u003c/th\u003e\n  \u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n  \u003ctr\u003e\n  \u003ctd\u003e\n\nEnables the optional support for [`dunce`](https://docs.rs/dunce) which automatically strips Windows' UNC paths\nif they can be represented as non-UNC paths (e.g., `\\\\?\\C:\\foo` as `C:\\foo`). This is done both\ninternally and in external results from e.g., [`DirectoryScan`](https://docs.rs/fs-more/latest/fs_more/directory/struct.DirectoryScan.html).\n\nThis feature is enabled by default — and highly recommended — because path canonicalization on Windows very commonly returns UNC paths.\n`dunce` only has an effect when compiling for Windows targets.\n  \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n  \n\n\u003ctable\u003e\n\u003cthead\u003e\n  \u003ctr\u003e\n  \u003cth align=\"left\"\u003e\n\u003cstrong\u003e\u003ccode\u003efs-err\u003c/code\u003e\u003c/strong\u003e\n\u003cspan style=\"font-weight: normal\"\u003e\u0026nbsp;(disabled by default)\u003c/span\u003e\n  \u003c/th\u003e\n  \u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n  \u003ctr\u003e\n  \u003ctd\u003e\n\nEnables the optional support for [`fs-err`](https://docs.rs/fs-err) which provides more helpful\nerror messages for underlying IO errors. It should be noted that `fs-more` does already provide plenty\nof context on errors by itself, which is why this is disabled by default.\n  \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\n\u003cbr\u003e\n\n## How to contribute\nFound a bug or just want to improve `fs-more` by developing new features or writing tests? Awesome!\nStart by going over the contribution guide: [`CONTRIBUTING.md`](https://github.com/simongoricar/fs-more/blob/master/CONTRIBUTING.md).\n\n\n\u003cdetails\u003e\n\u003csummary\u003e🧵 Potential future features\u003c/summary\u003e\n\n\u003cbr\u003e\n\n\nContributions for the ideas below are most welcome!\n\nSome of these ideas and/or missing features are simpler, some are more of a long shot.\nHowever, note that even though they are stated below, they probably haven't been thought out deeply enough.\nIf you decide to contribute, it would probably be best to first open an issue, \nso various approaches can be discussed before something is developed.\n\n- [ ] *Cross-platform: allow copying file and directory permissions.*\n\n  This partially already exists in some functions, but it inconsistent across the API. \n  The reason is that `std::fs::copy` already copies permission bits, but we don't use that in several places,\n  since copying with progress reporting makes using `std::fs::copy` impossible. \n  Ideally, we should expose a new option through the existing `*Options` structs and make this consistent.\n\n  I think this should be reasonably simple to do, but it might take some thinking about edge cases \n  and implementing some platform-specifics (i.e. on Windows, we probably want to copy the hidden file flag, etc).\n\n- [ ] *On Unix: allow copying file and directory owners and groups.*\n  \n  Depending on how deep the implementation rabbit-hole goes,\n  perhaps using [`file-owner`](https://docs.rs/file-owner/latest/file_owner/) or [`nix`](https://docs.rs/nix/latest/nix/)\n  could suffice? Perhaps we should feature-gate these kinds of things so the average user doesn't need to pull in so many dependencies?\n\n- [ ] *Cross-platform: allow copying creation/access/modification time of files and directories (across the entire API). \n  This could also include various other metadata.*\n  \n  Ideally, this should be highly configurable through the existing `*Options` structs.\n  This might take some more work though due to various platform differences \n  (see: [Unix](https://doc.rust-lang.org/std/os/unix/fs/trait.MetadataExt.html), \n  [Linux](https://doc.rust-lang.org/std/os/linux/fs/trait.MetadataExt.html), \n  [Windows](https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html)).\n\n  It might be more feasible to simply delegate this to some existing crate, \n  i.e. [`filetime`](https://lib.rs/crates/filetime) (but this one covers only timestamps).\n  Perhaps we should start with just creation/access/modification timestamps and expand later?\n\n- [ ] *On Windows: allow copying the [ACL](https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-lists)\n  of files and directories.*\n\n  This seems like a long shot and would need some concrete use cases before proceeding. Maybe [`windows-acl`](https://github.com/trailofbits/windows-acl)\n  could help? If this feature is to be developed, I think we should not expose any underlying ACL API and allow purely for mirroring it when copying or moving. This should definitely be under a feature flag.\n\n\u003c/details\u003e\n\n\n\u003cbr\u003e\n\n---\n\n## License\n\nLicensed under either of\n\n * Apache License, Version 2.0\n   ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n * MIT license\n   ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimongoricar%2Ffs-more","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimongoricar%2Ffs-more","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimongoricar%2Ffs-more/lists"}