summaryrefslogtreecommitdiffstats
path: root/vendor/pathdiff/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/pathdiff/src
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/pathdiff/src')
-rw-r--r--vendor/pathdiff/src/lib.rs222
1 files changed, 222 insertions, 0 deletions
diff --git a/vendor/pathdiff/src/lib.rs b/vendor/pathdiff/src/lib.rs
new file mode 100644
index 000000000..3860c2d91
--- /dev/null
+++ b/vendor/pathdiff/src/lib.rs
@@ -0,0 +1,222 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Adapted from rustc's path_relative_from
+// https://github.com/rust-lang/rust/blob/e1d0de82cc40b666b88d4a6d2c9dcbc81d7ed27f/src/librustc_back/rpath.rs#L116-L158
+
+use std::path::*;
+
+/// Construct a relative path from a provided base directory path to the provided path.
+///
+/// ```rust
+/// use pathdiff::diff_paths;
+/// use std::path::*;
+///
+/// let baz = "/foo/bar/baz";
+/// let bar = "/foo/bar";
+/// let quux = "/foo/bar/quux";
+/// assert_eq!(diff_paths(bar, baz), Some("../".into()));
+/// assert_eq!(diff_paths(baz, bar), Some("baz".into()));
+/// assert_eq!(diff_paths(quux, baz), Some("../quux".into()));
+/// assert_eq!(diff_paths(baz, quux), Some("../baz".into()));
+/// assert_eq!(diff_paths(bar, quux), Some("../".into()));
+///
+/// assert_eq!(diff_paths(&baz, &bar.to_string()), Some("baz".into()));
+/// assert_eq!(diff_paths(Path::new(baz), Path::new(bar).to_path_buf()), Some("baz".into()));
+/// ```
+pub fn diff_paths<P, B>(path: P, base: B) -> Option<PathBuf>
+where
+ P: AsRef<Path>,
+ B: AsRef<Path>,
+{
+ let path = path.as_ref();
+ let base = base.as_ref();
+
+ if path.is_absolute() != base.is_absolute() {
+ if path.is_absolute() {
+ Some(PathBuf::from(path))
+ } else {
+ None
+ }
+ } else {
+ let mut ita = path.components();
+ let mut itb = base.components();
+ let mut comps: Vec<Component> = vec![];
+ loop {
+ match (ita.next(), itb.next()) {
+ (None, None) => break,
+ (Some(a), None) => {
+ comps.push(a);
+ comps.extend(ita.by_ref());
+ break;
+ }
+ (None, _) => comps.push(Component::ParentDir),
+ (Some(a), Some(b)) if comps.is_empty() && a == b => (),
+ (Some(a), Some(b)) if b == Component::CurDir => comps.push(a),
+ (Some(_), Some(b)) if b == Component::ParentDir => return None,
+ (Some(a), Some(_)) => {
+ comps.push(Component::ParentDir);
+ for _ in itb {
+ comps.push(Component::ParentDir);
+ }
+ comps.push(a);
+ comps.extend(ita.by_ref());
+ break;
+ }
+ }
+ }
+ Some(comps.iter().map(|c| c.as_os_str()).collect())
+ }
+}
+
+#[cfg(feature = "camino")]
+mod utf8_paths {
+ use camino::{Utf8Component, Utf8Path, Utf8PathBuf};
+
+ /// Construct a relative UTF-8 path from a provided base directory path to the provided path.
+ ///
+ /// ```rust
+ /// # extern crate camino;
+ /// use camino::*;
+ /// use pathdiff::diff_utf8_paths;
+ ///
+ /// let baz = "/foo/bar/baz";
+ /// let bar = "/foo/bar";
+ /// let quux = "/foo/bar/quux";
+ /// assert_eq!(diff_utf8_paths(bar, baz), Some("../".into()));
+ /// assert_eq!(diff_utf8_paths(baz, bar), Some("baz".into()));
+ /// assert_eq!(diff_utf8_paths(quux, baz), Some("../quux".into()));
+ /// assert_eq!(diff_utf8_paths(baz, quux), Some("../baz".into()));
+ /// assert_eq!(diff_utf8_paths(bar, quux), Some("../".into()));
+ ///
+ /// assert_eq!(diff_utf8_paths(&baz, &bar.to_string()), Some("baz".into()));
+ /// assert_eq!(diff_utf8_paths(Utf8Path::new(baz), Utf8Path::new(bar).to_path_buf()), Some("baz".into()));
+ /// ```
+ #[cfg_attr(docsrs, doc(cfg(feature = "camino")))]
+ pub fn diff_utf8_paths<P, B>(path: P, base: B) -> Option<Utf8PathBuf>
+ where
+ P: AsRef<Utf8Path>,
+ B: AsRef<Utf8Path>,
+ {
+ let path = path.as_ref();
+ let base = base.as_ref();
+
+ if path.is_absolute() != base.is_absolute() {
+ if path.is_absolute() {
+ Some(Utf8PathBuf::from(path))
+ } else {
+ None
+ }
+ } else {
+ let mut ita = path.components();
+ let mut itb = base.components();
+ let mut comps: Vec<Utf8Component> = vec![];
+ loop {
+ match (ita.next(), itb.next()) {
+ (None, None) => break,
+ (Some(a), None) => {
+ comps.push(a);
+ comps.extend(ita.by_ref());
+ break;
+ }
+ (None, _) => comps.push(Utf8Component::ParentDir),
+ (Some(a), Some(b)) if comps.is_empty() && a == b => (),
+ (Some(a), Some(b)) if b == Utf8Component::CurDir => comps.push(a),
+ (Some(_), Some(b)) if b == Utf8Component::ParentDir => return None,
+ (Some(a), Some(_)) => {
+ comps.push(Utf8Component::ParentDir);
+ for _ in itb {
+ comps.push(Utf8Component::ParentDir);
+ }
+ comps.push(a);
+ comps.extend(ita.by_ref());
+ break;
+ }
+ }
+ }
+ Some(comps.iter().map(|c| c.as_str()).collect())
+ }
+ }
+}
+
+#[cfg(feature = "camino")]
+pub use crate::utf8_paths::*;
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_absolute() {
+ assert_diff_paths("/foo", "/bar", Some("../foo"));
+ assert_diff_paths("/foo", "bar", Some("/foo"));
+ assert_diff_paths("foo", "/bar", None);
+ assert_diff_paths("foo", "bar", Some("../foo"));
+ }
+
+ #[test]
+ fn test_identity() {
+ assert_diff_paths(".", ".", Some(""));
+ assert_diff_paths("../foo", "../foo", Some(""));
+ assert_diff_paths("./foo", "./foo", Some(""));
+ assert_diff_paths("/foo", "/foo", Some(""));
+ assert_diff_paths("foo", "foo", Some(""));
+
+ assert_diff_paths("../foo/bar/baz", "../foo/bar/baz", Some("".into()));
+ assert_diff_paths("foo/bar/baz", "foo/bar/baz", Some(""));
+ }
+
+ #[test]
+ fn test_subset() {
+ assert_diff_paths("foo", "fo", Some("../foo"));
+ assert_diff_paths("fo", "foo", Some("../fo"));
+ }
+
+ #[test]
+ fn test_empty() {
+ assert_diff_paths("", "", Some(""));
+ assert_diff_paths("foo", "", Some("foo"));
+ assert_diff_paths("", "foo", Some(".."));
+ }
+
+ #[test]
+ fn test_relative() {
+ assert_diff_paths("../foo", "../bar", Some("../foo"));
+ assert_diff_paths("../foo", "../foo/bar/baz", Some("../.."));
+ assert_diff_paths("../foo/bar/baz", "../foo", Some("bar/baz"));
+
+ assert_diff_paths("foo/bar/baz", "foo", Some("bar/baz"));
+ assert_diff_paths("foo/bar/baz", "foo/bar", Some("baz"));
+ assert_diff_paths("foo/bar/baz", "foo/bar/baz", Some(""));
+ assert_diff_paths("foo/bar/baz", "foo/bar/baz/", Some(""));
+
+ assert_diff_paths("foo/bar/baz/", "foo", Some("bar/baz"));
+ assert_diff_paths("foo/bar/baz/", "foo/bar", Some("baz"));
+ assert_diff_paths("foo/bar/baz/", "foo/bar/baz", Some(""));
+ assert_diff_paths("foo/bar/baz/", "foo/bar/baz/", Some(""));
+
+ assert_diff_paths("foo/bar/baz", "foo/", Some("bar/baz"));
+ assert_diff_paths("foo/bar/baz", "foo/bar/", Some("baz"));
+ assert_diff_paths("foo/bar/baz", "foo/bar/baz", Some(""));
+ }
+
+ #[test]
+ fn test_current_directory() {
+ assert_diff_paths(".", "foo", Some("../."));
+ assert_diff_paths("foo", ".", Some("foo"));
+ assert_diff_paths("/foo", "/.", Some("foo"));
+ }
+
+ fn assert_diff_paths(path: &str, base: &str, expected: Option<&str>) {
+ assert_eq!(diff_paths(path, base), expected.map(|s| s.into()));
+ #[cfg(feature = "camino")]
+ assert_eq!(diff_utf8_paths(path, base), expected.map(|s| s.into()));
+ }
+}