• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..--

src/25-Apr-2025-3,5051,488

tests/25-Apr-2025-11698

.cargo-checksum.jsonD25-Apr-20251.3 KiB11

Android.bpD25-Apr-2025808 3127

CHANGELOG.mdD25-Apr-20255.8 KiB172107

Cargo.lock.rust134D25-Apr-202524.3 KiB554489

Cargo.tomlD25-Apr-20251.6 KiB7969

LICENSED25-Apr-202510.6 KiB202169

LICENSE-APACHED25-Apr-202510.6 KiB202169

LICENSE-MITD25-Apr-20251,023 2421

METADATAD25-Apr-2025343 1817

MODULE_LICENSE_APACHE2D25-Apr-20250

README.mdD25-Apr-20258.2 KiB139100

build.rsD25-Apr-20253.7 KiB11181

cargo_embargo.jsonD25-Apr-202525 43

clippy.tomlD25-Apr-202516 21

release.tomlD25-Apr-2025282 98

rustfmt.tomlD25-Apr-202549 32

README.md

1# camino - UTF-8 paths
2
3[![camino on crates.io](https://img.shields.io/crates/v/camino)](https://crates.io/crates/camino)
4[![crates.io download count](https://img.shields.io/crates/d/camino)](https://crates.io/crates/camino)
5[![Documentation (latest release)](https://img.shields.io/badge/docs-latest%20version-brightgreen.svg)](https://docs.rs/camino)
6[![Documentation (main)](https://img.shields.io/badge/docs-main-purple.svg)](https://camino-rs.github.io/camino/rustdoc/camino/)
7[![License](https://img.shields.io/badge/license-Apache-green.svg)](LICENSE-APACHE)
8[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE-MIT)
9
10This repository contains the source code for `camino`, an extension of the `std::path` module that adds new
11[`Utf8PathBuf`] and [`Utf8Path`] types.
12
13## What is camino?
14
15`camino`'s [`Utf8PathBuf`] and [`Utf8Path`] types are like the standard library's [`PathBuf`] and [`Path`] types, except
16they are guaranteed to only contain UTF-8 encoded data. Therefore, they expose the ability to get their
17contents as strings, they implement `Display`, etc.
18
19The `std::path` types are not guaranteed to be valid UTF-8. This is the right decision for the standard library,
20since it must be as general as possible. However, on all platforms, non-Unicode paths are vanishingly uncommon for a
21number of reasons:
22
23- Unicode won. There are still some legacy codebases that store paths in encodings like [Shift JIS], but most
24  have been converted to Unicode at this point.
25- Unicode is the common subset of supported paths across Windows and Unix platforms. (On Windows, Rust stores paths
26  as [an extension to UTF-8](https://simonsapin.github.io/wtf-8/), and converts them to UTF-16 at Win32
27  API boundaries.)
28- There are already many systems, such as Cargo, that only support UTF-8 paths. If your own tool interacts with any such
29  system, you can assume that paths are valid UTF-8 without creating any additional burdens on consumers.
30- The ["makefile problem"](https://www.mercurial-scm.org/wiki/EncodingStrategy#The_.22makefile_problem.22) asks: given a
31  Makefile or other metadata file (such as `Cargo.toml`) that lists the names of other files, how should the names in
32  the Makefile be matched with the ones on disk? This has _no general, cross-platform solution_ in systems that support
33  non-UTF-8 paths. However, restricting paths to UTF-8 eliminates this problem.
34
35[Shift JIS]: https://en.wikipedia.org/wiki/Shift_JIS
36
37Therefore, many programs that want to manipulate paths _do_ assume they contain UTF-8 data, and convert them to `str`s
38as necessary. However, because this invariant is not encoded in the `Path` type, conversions such as
39`path.to_str().unwrap()` need to be repeated again and again, creating a frustrating experience.
40
41Instead, `camino` allows you to check that your paths are UTF-8 _once_, and then manipulate them
42as valid UTF-8 from there on, avoiding repeated lossy and confusing conversions.
43
44## Examples
45
46The documentation for [`Utf8PathBuf`] and [`Utf8Path`] contains several examples.
47
48For examples of how to use `camino` with other libraries like `serde` and `clap`, see the [`camino-examples`] directory.
49
50## API design
51
52`camino` is a very thin wrapper around `std::path`. [`Utf8Path`] and [`Utf8PathBuf`] are drop-in replacements
53for [`Path`] and [`PathBuf`].
54
55Most APIs are the same, but those at the boundary with `str` are different. Some examples:
56
57- `Path::to_str() -> Option<&str>` has been renamed to `Utf8Path::as_str() -> &str`.
58- [`Utf8Path`] implements `Display`, and `Path::display()` has been removed.
59- Iterating over a [`Utf8Path`] returns `&str`, not `&OsStr`.
60
61Every [`Utf8Path`] is a valid [`Path`], so [`Utf8Path`] implements `AsRef<Path>`. Any APIs that accept `impl AsRef<Path>`
62will continue to work with [`Utf8Path`] instances.
63
64## Should you use camino?
65
66`camino` trades off some utility for a great deal of simplicity. Whether `camino` is appropriate for a project or not
67is ultimately a case-by-case decision. Here are some general guidelines that may help.
68
69_You should consider using camino if..._
70
71- **You're building portable, cross-platform software.** While both Unix and Windows platforms support different kinds
72  of non-Unicode paths, Unicode is the common subset that's supported across them.
73- **Your system has files that contain the names of other files.** If you don't use UTF-8 paths, you will run into the
74  makefile problem described above, which has no general, cross-platform solution.
75- **You're interacting with existing systems that already assume UTF-8 paths.** In that case you won't be adding any new
76  burdens on downstream consumers.
77- **You're building something brand new and are willing to ask your users to rename their paths if necessary.** Projects
78  that don't have to worry about legacy compatibility have more flexibility in choosing what paths they support.
79
80In general, using camino is the right choice for most projects.
81
82_You should **NOT** use camino, if..._
83
84- **You're writing a core system utility.** If you're writing, say, an `mv` or `cat` replacement, you should
85  **not** use camino. Instead, use [`std::path::Path`] and add extensive tests for non-UTF-8 paths.
86- **You have legacy compatibility constraints.** For example, Git supports non-UTF-8 paths. If your tool needs to handle
87  arbitrary Git repositories, it should use its own path type that's a wrapper around `Vec<u8>`.
88  - [`std::path::Path`] supports arbitrary bytestrings [on Unix] but not on Windows.
89- **There's some other reason you need to support non-UTF-8 paths.** Some tools like disk recovery utilities need to
90  handle potentially corrupt filenames: only being able to handle UTF-8 paths would greatly diminish their utility.
91
92[on Unix]: https://doc.rust-lang.org/std/os/unix/ffi/index.html
93
94## Optional features
95
96By default, `camino` has **no dependencies** other than `std`. There are some optional features that enable
97dependencies:
98
99- `serde1` adds serde [`Serialize`] and [`Deserialize`] impls for [`Utf8PathBuf`] and [`Utf8Path`]
100  (zero-copy).
101- `proptest1` adds [proptest](https://altsysrq.github.io/proptest-book/) [`Arbitrary`]
102  implementations for [`Utf8PathBuf`] and `Box<Utf8Path>`.
103
104> NOTE: Enabling the `serde` or `proptest` features will not do anything. You must enable the `serde1` and `proptest1` features, respectively.
105
106## Rust version support
107
108The minimum supported Rust version (MSRV) for `camino` with default features is **1.34**. This project is tested in CI
109against the latest stable version of Rust and the MSRV.
110
111- _Stable APIs_ added in later Rust versions are supported either through conditional compilation in `build.rs`, or through backfills that also work on older versions.
112- _Deprecations_ are kept in sync with the version of Rust they're added in.
113- _Unstable APIs_ are currently not supported. Please
114  [file an issue on GitHub](https://github.com/camino-rs/camino/issues/new) if you need an unstable API.
115
116`camino` is designed to be a core library and has a conservative MSRV policy. MSRV increases will only happen for
117a compelling enough reason, and will involve at least a minor version bump.
118
119Optional features may pull in dependencies that require a newer version of Rust.
120
121## License
122
123This project is available under the terms of either the [Apache 2.0 license](LICENSE-APACHE) or the [MIT
124license](LICENSE-MIT).
125
126This project's documentation is adapted from [The Rust Programming Language](https://github.com/rust-lang/rust/), which is
127available under the terms of either the [Apache 2.0 license](https://github.com/rust-lang/rust/blob/master/LICENSE-APACHE)
128or the [MIT license](https://github.com/rust-lang/rust/blob/master/LICENSE-MIT).
129
130[`Utf8PathBuf`]: https://docs.rs/camino/*/camino/struct.Utf8PathBuf.html
131[`Utf8Path`]: https://docs.rs/camino/*/camino/struct.Utf8Path.html
132[`PathBuf`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html
133[`Path`]: https://doc.rust-lang.org/std/path/struct.Path.html
134[`std::path::Path`]: https://doc.rust-lang.org/std/path/struct.Path.html
135[`Serialize`]: https://docs.rs/serde/1/serde/trait.Serialize.html
136[`Deserialize`]: https://docs.rs/serde/1/serde/trait.Deserialize.html
137[`camino-examples`]: https://github.com/camino-rs/camino/tree/main/camino-examples
138[`Arbitrary`]: https://docs.rs/proptest/1/proptest/arbitrary/trait.Arbitrary.html
139