Skip to content

Commit

Permalink
fixup
Browse files Browse the repository at this point in the history
  • Loading branch information
Geod24 committed Dec 31, 2024
1 parent 473dbec commit 090eab8
Showing 1 changed file with 142 additions and 27 deletions.
169 changes: 142 additions & 27 deletions source/dub/internal/vibecompat/inet/path.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,144 @@
*/
module dub.internal.vibecompat.inet.path;

version (Have_vibe_core) public import vibe.core.path;
import std.traits : isInstanceOf;

/// Represents a path on Windows operating systems.
alias WindowsPath = NormalizedGenericPath!WindowsPathFormat;

/// Represents a path on Unix/Posix systems.
alias PosixPath = NormalizedGenericPath!PosixPathFormat;

/// Represents a path as part of an URI.
alias InetPath = NormalizedGenericPath!InetPathFormat;

/// The path type native to the target operating system.
version (Windows) alias NativePath = WindowsPath;
else alias NativePath = PosixPath;

// GenericPath no longer normalize on `opBinary!"~"` since v2. We relied on this
// behavior heavily and this clutch is used to avoid a breaking change.
private struct NormalizedGenericPath (T) {
@safe:
private GenericPath!T data;

public this (string data) scope @safe pure {
this.data = GenericPath!T(data);
}

public this (GenericPath!T data) scope @safe pure nothrow @nogc {
this.data = data;
}

this(Segment segment) { this(GenericPath!T(segment)); }

/** Constructs a path from an input range of `Segment`s.
Throws:
Since path segments are pre-validated, this constructor does not
throw an exception.
*/
this(R)(R segments)
if (isInputRange!R && is(ElementType!R : Segment))
{
this(GenericPath!T(segments));
}

// Tried this approach but it's just shooting yourself in the foot
//public alias data this;

NormalizedGenericPath opBinary(string op : "~")(string subpath) const {
return this ~ NormalizedGenericPath(subpath);
}
/// ditto
NormalizedGenericPath opBinary(string op : "~")(Segment subpath) const {
return this ~ NormalizedGenericPath(GenericPath!T(subpath));
}
/// ditto
NormalizedGenericPath opBinary(string op : "~")(NormalizedGenericPath subpath) const {
auto result = this.data.opBinary!"~"(subpath.data);
result.normalize();
return NormalizedGenericPath(result);
}
/// Appends a relative path to this path.
void opOpAssign(string op : "~", T)(T op) { this = this ~ op; }

// Just forward, `alias this` is hopeless
public alias Segment = GenericPath!T.Segment;

/// Tests if the path is represented by an empty string.
@property bool empty() const nothrow @nogc { return this.data.empty(); }

/// Tests if the path is absolute.
@property bool absolute() const nothrow @nogc { return this.data.absolute(); }

/// Determines whether the path ends with a path separator (i.e. represents a folder specifically).
@property bool endsWithSlash() const nothrow @nogc { return this.data.endsWithSlash(); }
/// ditto
@property void endsWithSlash(bool v) nothrow { this.data.endsWithSlash(v); }

/** Iterates over the individual segments of the path.
Returns a forward range of `Segment`s.
*/
@property auto bySegment() const { return this.data.bySegment(); }

///
string toString() const nothrow @nogc { return this.data.toString(); }

/// Computes a hash sum, enabling storage within associative arrays.
size_t toHash() const nothrow @trusted { return this.data.toHash(); }

/** Compares two path objects.
Note that the exact string representation of the two paths will be
compared. To get a basic semantic comparison, the paths must be
normalized first.
*/
bool opEquals(NormalizedGenericPath other) const @nogc { return this.data.opEquals(other.data); }

///
@property Segment head() const @nogc { return this.data.head(); }

///
@property bool hasParentPath() const @nogc { return this.data.hasParentPath(); }

///
@property NormalizedGenericPath parentPath() const @nogc { return NormalizedGenericPath(this.data.parentPath()); }

///
void normalize() { return this.data.normalize(); }

///
NormalizedGenericPath normalized() const { return NormalizedGenericPath(this.data.normalized()); }

///
bool startsWith(NormalizedGenericPath prefix) const nothrow { return this.data.startsWith(prefix.data); }

///
static NormalizedGenericPath fromTrustedString(string p) nothrow @nogc {
return NormalizedGenericPath(GenericPath!T.fromTrustedString(p));
}
}

Path relativeTo(Path)(in Path path, in Path base_path) @safe
if (isInstanceOf!(NormalizedGenericPath, Path))
{
return Path(relativeTo(path.data, base_path.data));
}

/** Converts a path to its system native string representation.
*/
string toNativeString(T)(NormalizedGenericPath!T path)
{
return path.data.toString();
}

version (Have_vibe_core) import vibe.core.path;
else:

private:

import std.algorithm.searching : commonPrefix, endsWith, startsWith;
import std.algorithm.comparison : equal, min;
import std.algorithm.iteration : map;
Expand Down Expand Up @@ -191,28 +326,6 @@ Path relativeToWeb(Path)(Path path, Path base_path) @safe
assert(InetPath("/some/path/").relativeToWeb(InetPath("/some/other/path")) == InetPath("../path/"));
}+/


/** Converts a path to its system native string representation.
*/
string toNativeString(P)(P path)
{
return (cast(NativePath)path).toString();
}


/// Represents a path on Windows operating systems.
alias WindowsPath = GenericPath!WindowsPathFormat;

/// Represents a path on Unix/Posix systems.
alias PosixPath = GenericPath!PosixPathFormat;

/// Represents a path as part of an URI.
alias InetPath = GenericPath!InetPathFormat;

/// The path type native to the target operating system.
version (Windows) alias NativePath = WindowsPath;
else alias NativePath = PosixPath;

/// Provides a common interface to operate on paths of various kinds.
struct GenericPath(F) {
@safe:
Expand Down Expand Up @@ -651,7 +764,7 @@ struct GenericPath(F) {
}

///
unittest {
version (none) unittest {
assert(InetPath("foo/bar/baz").byPrefix
.equal([
InetPath("foo/"),
Expand Down Expand Up @@ -874,9 +987,11 @@ unittest {
assert(WindowsPath("hello\\w/orld").bySegment.equal([WindowsPath.Segment("hello",'\\'), WindowsPath.Segment("w",'/'), WindowsPath.Segment("orld")]));
assert(WindowsPath("hello/w\\orld").bySegment.equal([WindowsPath.Segment("hello",'/'), WindowsPath.Segment("w",'\\'), WindowsPath.Segment("orld")]));

version (none) {
assert(PosixPath("hello/world").byPrefix.equal([PosixPath("hello/"), PosixPath("hello/world")]));
assert(PosixPath("/hello/world/").byPrefix.equal([PosixPath("/"), PosixPath("/hello/"), PosixPath("/hello/world/")]));
assert(WindowsPath("C:\\Windows").byPrefix.equal([WindowsPath("C:\\"), WindowsPath("C:\\Windows")]));
}
}

unittest
Expand All @@ -899,11 +1014,11 @@ unittest

assert(WindowsPath("C:\\Windows").absolute);
assert((cast(InetPath)WindowsPath("C:\\Windows")).toString() == "/C:/Windows");
assert((WindowsPath("C:\\Windows") ~ InetPath("test/this")).toString() == "C:\\Windows\\test/this");
version (none) assert((WindowsPath("C:\\Windows") ~ InetPath("test/this")).toString() == "C:\\Windows\\test/this");
assert(InetPath("/C:/Windows").absolute);
assert((cast(WindowsPath)InetPath("/C:/Windows")).toString() == "C:/Windows");
assert((InetPath("/C:/Windows") ~ WindowsPath("test\\this")).toString() == "/C:/Windows/test/this");
assert((InetPath("") ~ WindowsPath("foo\\bar")).toString() == "foo/bar");
version (none) assert((InetPath("/C:/Windows") ~ WindowsPath("test\\this")).toString() == "/C:/Windows/test/this");
version (none) assert((InetPath("") ~ WindowsPath("foo\\bar")).toString() == "foo/bar");
assert((cast(InetPath)WindowsPath("C:\\Windows\\")).toString() == "/C:/Windows/");

assert(NativePath("").empty);
Expand Down

0 comments on commit 090eab8

Please sign in to comment.