7
7
*/
8
8
module vibe.core.path ;
9
9
10
- import std.algorithm.searching : commonPrefix, endsWith, startsWith;
11
- import std.algorithm.comparison : equal, min;
10
+ import std.algorithm.searching : any, commonPrefix, endsWith, startsWith;
11
+ import std.algorithm.comparison : among, equal, min;
12
12
import std.algorithm.iteration : map;
13
13
import std.exception : enforce;
14
14
import std.range : empty, front, popFront, popFrontExactly, takeExactly;
@@ -65,7 +65,7 @@ Path relativeTo(Path)(in Path path, in Path base_path) @safe
65
65
base++ ;
66
66
}
67
67
68
- enum up = Path.Segment2 (" .." , Path.defaultSeparator);
68
+ enum up = Path.Segment (" .." , Path.defaultSeparator);
69
69
auto ret = Path(base_nodes.map! (p => up).chain(nodes));
70
70
if (path.endsWithSlash) {
71
71
if (ret.empty) return Path.fromTrustedString(" ." ~ path.toString()[$- 1 ]);
@@ -216,6 +216,7 @@ struct GenericPath(F) {
216
216
alias Format = F;
217
217
218
218
// / vibe-core 1.x compatibility alias
219
+ deprecated (" Use `Segment` instead." )
219
220
alias Segment2 = Segment;
220
221
221
222
/* * A single path segment.
@@ -524,6 +525,7 @@ struct GenericPath(F) {
524
525
}
525
526
526
527
// / vibe-core 1.x compatibility alias
528
+ deprecated (" Use `.bySegment` instead." )
527
529
alias bySegment2 = bySegment;
528
530
529
531
/* * Iterates over the individual segments of the path.
@@ -665,6 +667,7 @@ struct GenericPath(F) {
665
667
}
666
668
667
669
// vibe-core 1.x compatibility alias
670
+ deprecated (" Use `.head` instead." )
668
671
alias head2 = head;
669
672
670
673
// / Returns the trailing segment of the path.
@@ -723,26 +726,9 @@ struct GenericPath(F) {
723
726
724
727
/* * Returns the normalized form of the path.
725
728
726
- See `normalize` for a full description.
727
- */
728
- @property GenericPath normalized()
729
- const {
730
- GenericPath ret = this ;
731
- ret.normalize();
732
- return ret;
733
- }
734
-
735
- unittest {
736
- assert (PosixPath(" foo/../bar" ).normalized == PosixPath(" bar" ));
737
- assert (PosixPath(" foo//./bar/../baz" ).normalized == PosixPath(" foo/baz" ));
738
- }
739
-
740
-
741
- /* * Removes any redundant path segments and replaces all separators by the
742
- default one.
743
-
744
- The resulting path representation is suitable for basic semantic
745
- comparison to other normalized paths.
729
+ This removes any redundant path segments and replaces all separators
730
+ by the default one. The resulting path representation is suitable for
731
+ basic semantic comparison to other normalized paths.
746
732
747
733
Note that there are still ways for different normalized paths to
748
734
represent the same file. Examples of this are the tilde shortcut to the
@@ -754,10 +740,17 @@ struct GenericPath(F) {
754
740
segments ("..") that lead to a path that is a parent path of the
755
741
root path.
756
742
*/
757
- void normalize ()
758
- {
743
+ @property GenericPath normalized ()
744
+ const {
759
745
import std.array : appender, join;
760
746
747
+ // avoid constucting a new path if already normalized
748
+ if (! this .bySegment.any! (s => s.encodedName.among(" " , " ." , " .." )
749
+ || (s.hasSeparator && s.separator != Format.defaultSeparator)))
750
+ {
751
+ return this ;
752
+ }
753
+
761
754
Segment[] newnodes;
762
755
bool got_non_sep = false ;
763
756
foreach (n; this .bySegment) {
@@ -779,7 +772,31 @@ struct GenericPath(F) {
779
772
780
773
auto dst = appender! string ;
781
774
Format.toString(newnodes, dst);
782
- m_path = dst.data;
775
+
776
+ GenericPath ret;
777
+ ret.m_path = dst.data;
778
+ return ret;
779
+ }
780
+
781
+ // /
782
+ unittest {
783
+ assert (PosixPath(" foo/../bar" ).normalized == PosixPath(" bar" ));
784
+ assert (PosixPath(" foo//./bar/../baz" ).normalized == PosixPath(" foo/baz" ));
785
+ assert (PosixPath(" /foo/../bar" ).normalized == PosixPath(" /bar" ));
786
+ assert (WindowsPath(` \\PC/c$\foo/../bar/` ).normalized == WindowsPath(` \\PC\c$\bar\` ));
787
+ assert (PosixPath(" /foo/bar" ).normalized == PosixPath(" /foo/bar" ));
788
+ assert (PosixPath(" foo/bar/" ).normalized == PosixPath(" foo/bar/" ));
789
+ }
790
+
791
+
792
+ /* * Replaces the path representation with its normalized form.
793
+
794
+ This is a simple convenience wrapper around the functional style
795
+ `.normalized`, which is usually preferable.
796
+ */
797
+ void normalize ()
798
+ {
799
+ this .m_path = this .normalized.m_path;
783
800
}
784
801
785
802
// /
0 commit comments