@@ -17,23 +17,7 @@ NOTE: `Path(::AbstractString)` can also work for custom paths if
1717function Path end
1818
1919Path (fp:: AbstractPath ) = fp
20-
21- # May want to support using the registry for other constructors as well
22- function Path (str:: AbstractString ; debug= false )
23- types = filter (t -> ispathtype (t, str), PATH_TYPES)
24-
25- if length (types) > 1
26- @debug (
27- string (
28- " Found multiple path types that match the string specified ($types ). " ,
29- " Please use a specific constructor if $(first (types)) is not the correct type."
30- )
31- )
32- end
33-
34- return first (types)(str)
35- end
36-
20+ Path (str:: AbstractString ) = parse (AbstractPath, str)
3721function Path (fp:: T , segments:: Tuple{Vararg{String}} ) where T <: AbstractPath
3822 T ((s === :segments ? segments : getfield (fp, s) for s in fieldnames (T)). .. )
3923end
@@ -78,8 +62,49 @@ function Base.show(io::IO, fp::AbstractPath)
7862 get (io, :compact , false ) ? print (io, fp) : print (io, " p\" $fp \" " )
7963end
8064
81- Base. parse (:: Type{<:AbstractPath} , x:: AbstractString ) = Path (x)
82- Base. convert (:: Type{<:AbstractPath} , x:: AbstractString ) = Path (x)
65+ # Default string constructors for AbstractPath types should fall back to calling `parse`.
66+ (:: Type{T} )(str:: AbstractString ) where {T<: AbstractPath } = parse (T, str)
67+
68+ function Base. parse (:: Type{P} , str:: AbstractString ; kwargs... ) where P<: AbstractPath
69+ result = tryparse (P, str; kwargs... )
70+ result === nothing && throw (ArgumentError (" $str cannot be parsed as $P " ))
71+ return result
72+ end
73+
74+ function Base. tryparse (:: Type{AbstractPath} , str:: AbstractString ; debug= false )
75+ result = nothing
76+ types = Vector {eltype(PATH_TYPES)} ()
77+
78+ for P in PATH_TYPES
79+ r = tryparse (P, str)
80+
81+ # If we successfully parsed the path then save that result
82+ # and break if we aren't in debug mode, otherwise record how many
83+ if r != = nothing
84+ # Only assign the result if it's currently `nothing`
85+ result = result === nothing ? r : result
86+
87+ if debug
88+ push! (types, P)
89+ else
90+ break
91+ end
92+ end
93+ end
94+
95+ if length (types) > 1
96+ @debug (
97+ string (
98+ " Found multiple path types that could parse the string specified ($types ). " ,
99+ " Please use a specific `parse` method if $(first (types)) is not the correct type."
100+ )
101+ )
102+ end
103+
104+ return result
105+ end
106+
107+ Base. convert (T:: Type{<:AbstractPath} , x:: AbstractString ) = parse (T, x)
83108Base. convert (:: Type{String} , x:: AbstractPath ) = string (x)
84109Base. promote_rule (:: Type{String} , :: Type{<:AbstractPath} ) = String
85110Base. isless (a:: P , b:: P ) where P<: AbstractPath = isless (a. segments, b. segments)
@@ -221,7 +246,7 @@ p"foobar"
221246```
222247"""
223248function Base.:(* )(a:: T , b:: Union{T, AbstractString, AbstractChar} ...) where T <: AbstractPath
224- T ( * (string (a), string .(b)... ))
249+ return parse (T, * (string (a), string .(b)... ))
225250end
226251
227252"""
@@ -393,18 +418,18 @@ function absolute(fp::AbstractPath)
393418end
394419
395420"""
396- relative{T<:AbstractPath}(fp::T, start::T=T("." ))
421+ relative{T<:AbstractPath}(fp::T, start::T=cwd( ))
397422
398423Creates a relative path from either the current directory or an arbitrary start directory.
399424"""
400- function relative (fp:: T , start:: T = T ( " . " )) where {T <: AbstractPath }
425+ function relative (fp:: T , start:: T = cwd ( )) where {T<: AbstractPath }
401426 curdir = " ."
402427 pardir = " .."
403428
404429 p = absolute (fp). segments
405430 s = absolute (start). segments
406431
407- p == s && return T ( curdir)
432+ p == s && return parse (T, curdir)
408433
409434 i = 0
410435 while i < min (length (p), length (s))
@@ -431,7 +456,7 @@ function relative(fp::T, start::T=T(".")) where {T <: AbstractPath}
431456 else
432457 relpath_ = tuple (pathpart... )
433458 end
434- return isempty (relpath_) ? T ( curdir) : Path (fp, relpath_)
459+ return isempty (relpath_) ? parse (T, curdir) : Path (fp, relpath_)
435460end
436461
437462"""
0 commit comments