1688
1688
< span id ="1688 "> 1688</ span >
1689
1689
< span id ="1689 "> 1689</ span >
1690
1690
< span id ="1690 "> 1690</ span >
1691
+ < span id ="1691 "> 1691</ span >
1692
+ < span id ="1692 "> 1692</ span >
1693
+ < span id ="1693 "> 1693</ span >
1694
+ < span id ="1694 "> 1694</ span >
1695
+ < span id ="1695 "> 1695</ span >
1696
+ < span id ="1696 "> 1696</ span >
1697
+ < span id ="1697 "> 1697</ span >
1698
+ < span id ="1698 "> 1698</ span >
1699
+ < span id ="1699 "> 1699</ span >
1700
+ < span id ="1700 "> 1700</ span >
1701
+ < span id ="1701 "> 1701</ span >
1702
+ < span id ="1702 "> 1702</ span >
1703
+ < span id ="1703 "> 1703</ span >
1704
+ < span id ="1704 "> 1704</ span >
1705
+ < span id ="1705 "> 1705</ span >
1706
+ < span id ="1706 "> 1706</ span >
1707
+ < span id ="1707 "> 1707</ span >
1708
+ < span id ="1708 "> 1708</ span >
1709
+ < span id ="1709 "> 1709</ span >
1710
+ < span id ="1710 "> 1710</ span >
1711
+ < span id ="1711 "> 1711</ span >
1712
+ < span id ="1712 "> 1712</ span >
1713
+ < span id ="1713 "> 1713</ span >
1714
+ < span id ="1714 "> 1714</ span >
1715
+ < span id ="1715 "> 1715</ span >
1716
+ < span id ="1716 "> 1716</ span >
1717
+ < span id ="1717 "> 1717</ span >
1718
+ < span id ="1718 "> 1718</ span >
1719
+ < span id ="1719 "> 1719</ span >
1720
+ < span id ="1720 "> 1720</ span >
1721
+ < span id ="1721 "> 1721</ span >
1722
+ < span id ="1722 "> 1722</ span >
1723
+ < span id ="1723 "> 1723</ span >
1724
+ < span id ="1724 "> 1724</ span >
1725
+ < span id ="1725 "> 1725</ span >
1726
+ < span id ="1726 "> 1726</ span >
1727
+ < span id ="1727 "> 1727</ span >
1728
+ < span id ="1728 "> 1728</ span >
1729
+ < span id ="1729 "> 1729</ span >
1730
+ < span id ="1730 "> 1730</ span >
1731
+ < span id ="1731 "> 1731</ span >
1732
+ < span id ="1732 "> 1732</ span >
1733
+ < span id ="1733 "> 1733</ span >
1734
+ < span id ="1734 "> 1734</ span >
1735
+ < span id ="1735 "> 1735</ span >
1736
+ < span id ="1736 "> 1736</ span >
1737
+ < span id ="1737 "> 1737</ span >
1738
+ < span id ="1738 "> 1738</ span >
1739
+ < span id ="1739 "> 1739</ span >
1740
+ < span id ="1740 "> 1740</ span >
1741
+ < span id ="1741 "> 1741</ span >
1742
+ < span id ="1742 "> 1742</ span >
1743
+ < span id ="1743 "> 1743</ span >
1744
+ < span id ="1744 "> 1744</ span >
1745
+ < span id ="1745 "> 1745</ span >
1746
+ < span id ="1746 "> 1746</ span >
1747
+ < span id ="1747 "> 1747</ span >
1748
+ < span id ="1748 "> 1748</ span >
1749
+ < span id ="1749 "> 1749</ span >
1750
+ < span id ="1750 "> 1750</ span >
1751
+ < span id ="1751 "> 1751</ span >
1752
+ < span id ="1752 "> 1752</ span >
1753
+ < span id ="1753 "> 1753</ span >
1754
+ < span id ="1754 "> 1754</ span >
1755
+ < span id ="1755 "> 1755</ span >
1756
+ < span id ="1756 "> 1756</ span >
1757
+ < span id ="1757 "> 1757</ span >
1758
+ < span id ="1758 "> 1758</ span >
1759
+ < span id ="1759 "> 1759</ span >
1760
+ < span id ="1760 "> 1760</ span >
1761
+ < span id ="1761 "> 1761</ span >
1762
+ < span id ="1762 "> 1762</ span >
1763
+ < span id ="1763 "> 1763</ span >
1764
+ < span id ="1764 "> 1764</ span >
1765
+ < span id ="1765 "> 1765</ span >
1766
+ < span id ="1766 "> 1766</ span >
1767
+ < span id ="1767 "> 1767</ span >
1768
+ < span id ="1768 "> 1768</ span >
1769
+ < span id ="1769 "> 1769</ span >
1691
1770
</ pre > < pre class ="rust "> < code > < span class ="attribute "> #![allow(clippy::missing_safety_doc)]
1692
1771
#![allow(clippy::extra_unused_lifetimes)]
1693
1772
3006
3085
</ span > path.symlink_metadata().is_ok()
3007
3086
}
3008
3087
3088
+ < span class ="doccomment "> /// Zip the ancestors of a source path and destination path.
3089
+ ///
3090
+ /// # Examples
3091
+ ///
3092
+ /// ```rust,ignore
3093
+ /// let actual = aligned_ancestors(&Path::new("a/b/c"), &Path::new("d/a/b/c"));
3094
+ /// let expected = vec![
3095
+ /// (Path::new("a"), Path::new("d/a")),
3096
+ /// (Path::new("a/b"), Path::new("d/a/b")),
3097
+ /// ];
3098
+ /// assert_eq!(actual, expected);
3099
+ /// ```
3100
+ </ span > < span class ="kw "> fn </ span > aligned_ancestors<< span class ="lifetime "> 'a</ span > >(source: < span class ="kw-2 "> &</ span > < span class ="lifetime "> 'a </ span > Path, dest: < span class ="kw-2 "> &</ span > < span class ="lifetime "> 'a </ span > Path) -> Vec<(< span class ="kw-2 "> &</ span > < span class ="lifetime "> 'a </ span > Path, < span class ="kw-2 "> &</ span > < span class ="lifetime "> 'a </ span > Path)> {
3101
+ < span class ="comment "> // Collect the ancestors of each. For example, if `source` is
3102
+ // "a/b/c", then the ancestors are "a/b/c", "a/b", "a/", and "".
3103
+ </ span > < span class ="kw "> let </ span > source_ancestors: Vec<< span class ="kw-2 "> &</ span > Path> = source.ancestors().collect();
3104
+ < span class ="kw "> let </ span > dest_ancestors: Vec<< span class ="kw-2 "> &</ span > Path> = dest.ancestors().collect();
3105
+
3106
+ < span class ="comment "> // For this particular application, we don't care about the null
3107
+ // path "" and we don't care about the full path (e.g. "a/b/c"),
3108
+ // so we exclude those.
3109
+ </ span > < span class ="kw "> let </ span > n = source_ancestors.len();
3110
+ < span class ="kw "> let </ span > source_ancestors = < span class ="kw-2 "> &</ span > source_ancestors[< span class ="number "> 1</ span > ..n - < span class ="number "> 1</ span > ];
3111
+
3112
+ < span class ="comment "> // Get the matching number of elements from the ancestors of the
3113
+ // destination path (for example, get "d/a" and "d/a/b").
3114
+ </ span > < span class ="kw "> let </ span > k = source_ancestors.len();
3115
+ < span class ="kw "> let </ span > dest_ancestors = < span class ="kw-2 "> &</ span > dest_ancestors[< span class ="number "> 1</ span > ..< span class ="number "> 1 </ span > + k];
3116
+
3117
+ < span class ="comment "> // Now we have two slices of the same length, so we zip them.
3118
+ </ span > < span class ="kw "> let </ span > < span class ="kw-2 "> mut </ span > result = < span class ="macro "> vec!</ span > [];
3119
+ < span class ="kw "> for </ span > (x, y) < span class ="kw "> in </ span > source_ancestors
3120
+ .iter()
3121
+ .rev()
3122
+ .zip(dest_ancestors.iter().rev())
3123
+ {
3124
+ result.push((< span class ="kw-2 "> *</ span > x, < span class ="kw-2 "> *</ span > y));
3125
+ }
3126
+ result
3127
+ }
3128
+
3009
3129
< span class ="doccomment "> /// Copy the a file from `source` to `dest`. `source` will be dereferenced if
3010
3130
/// `options.dereference` is set to true. `dest` will be dereferenced only if
3011
3131
/// the source was not a symlink.
3065
3185
< span class ="kw "> if let </ span > < span class ="prelude-val "> Some</ span > (pb) = progress_bar {
3066
3186
< span class ="comment "> // Suspend (hide) the progress bar so the println won't overlap with the progress bar.
3067
3187
</ span > pb.suspend(|| {
3188
+ < span class ="kw "> if </ span > options.parents {
3189
+ < span class ="comment "> // For example, if copying file `a/b/c` and its parents
3190
+ // to directory `d/`, then print
3191
+ //
3192
+ // a -> d/a
3193
+ // a/b -> d/a/b
3194
+ //
3195
+ </ span > < span class ="kw "> for </ span > (x, y) < span class ="kw "> in </ span > aligned_ancestors(source, dest) {
3196
+ < span class ="macro "> println!</ span > (< span class ="string "> "{} -> {}"</ span > , x.display(), y.display());
3197
+ }
3198
+ }
3199
+
3068
3200
< span class ="macro "> println!</ span > (< span class ="string "> "{}"</ span > , context_for(source, dest));
3069
3201
});
3070
3202
} < span class ="kw "> else </ span > {
3203
+ < span class ="kw "> if </ span > options.parents {
3204
+ < span class ="comment "> // For example, if copying file `a/b/c` and its parents
3205
+ // to directory `d/`, then print
3206
+ //
3207
+ // a -> d/a
3208
+ // a/b -> d/a/b
3209
+ //
3210
+ </ span > < span class ="kw "> for </ span > (x, y) < span class ="kw "> in </ span > aligned_ancestors(source, dest) {
3211
+ < span class ="macro "> println!</ span > (< span class ="string "> "{} -> {}"</ span > , x.display(), y.display());
3212
+ }
3213
+ }
3214
+
3071
3215
< span class ="macro "> println!</ span > (< span class ="string "> "{}"</ span > , context_for(source, dest));
3072
3216
}
3073
3217
}
3366
3510
< span class ="prelude-val "> Ok</ span > (total)
3367
3511
}
3368
3512
3369
- < span class ="attribute "> #[test]
3370
- </ span > < span class ="kw "> fn </ span > test_cp_localize_to_target() {
3371
- < span class ="macro "> assert!</ span > (
3372
- localize_to_target(
3373
- Path::new(< span class ="string "> "a/source/"</ span > ),
3374
- Path::new(< span class ="string "> "a/source/c.txt"</ span > ),
3375
- Path::new(< span class ="string "> "target/"</ span > )
3376
- )
3377
- .unwrap()
3378
- == Path::new(< span class ="string "> "target/c.txt"</ span > )
3379
- );
3513
+ < span class ="attribute "> #[cfg(test)]
3514
+ </ span > < span class ="kw "> mod </ span > tests {
3515
+
3516
+ < span class ="kw "> use crate</ span > ::{aligned_ancestors, localize_to_target};
3517
+ < span class ="kw "> use </ span > std::path::Path;
3518
+
3519
+ < span class ="attribute "> #[test]
3520
+ </ span > < span class ="kw "> fn </ span > test_cp_localize_to_target() {
3521
+ < span class ="kw "> let </ span > root = Path::new(< span class ="string "> "a/source/"</ span > );
3522
+ < span class ="kw "> let </ span > source = Path::new(< span class ="string "> "a/source/c.txt"</ span > );
3523
+ < span class ="kw "> let </ span > target = Path::new(< span class ="string "> "target/"</ span > );
3524
+ < span class ="kw "> let </ span > actual = localize_to_target(root, source, target).unwrap();
3525
+ < span class ="kw "> let </ span > expected = Path::new(< span class ="string "> "target/c.txt"</ span > );
3526
+ < span class ="macro "> assert_eq!</ span > (actual, expected);
3527
+ }
3528
+
3529
+ < span class ="attribute "> #[test]
3530
+ </ span > < span class ="kw "> fn </ span > test_aligned_ancestors() {
3531
+ < span class ="kw "> let </ span > actual = aligned_ancestors(< span class ="kw-2 "> &</ span > Path::new(< span class ="string "> "a/b/c"</ span > ), < span class ="kw-2 "> &</ span > Path::new(< span class ="string "> "d/a/b/c"</ span > ));
3532
+ < span class ="kw "> let </ span > expected = < span class ="macro "> vec!</ span > [
3533
+ (Path::new(< span class ="string "> "a"</ span > ), Path::new(< span class ="string "> "d/a"</ span > )),
3534
+ (Path::new(< span class ="string "> "a/b"</ span > ), Path::new(< span class ="string "> "d/a/b"</ span > )),
3535
+ ];
3536
+ < span class ="macro "> assert_eq!</ span > (actual, expected);
3537
+ }
3380
3538
}
3381
3539
</ code > </ pre > </ div >
3382
3540
</ section > </ div > </ main > < div id ="rustdoc-vars " data-root-path ="../../ " data-current-crate ="uu_cp " data-themes ="ayu,dark,light " data-resource-suffix ="" data-rustdoc-version ="1.65.0 (897e37553 2022-11-02) " > </ div > </ body > </ html >
0 commit comments