I would absolutely love to see an API like AbsolutePath / RelativePath for file 
system operations!

> On 22. Aug 2017, at 21:02, Dave DeLong via swift-evolution 
> <[email protected]> wrote:
> 
> I suppose, if you squint at it weirdly.
> 
> My current Path API is a “Path” protocol, with “AbsolutePath” and 
> “RelativePath” struct versions. The protocol defines a path to be an array of 
> path components. The only real difference between an AbsolutePath and a 
> RelativePath is that all file system operations would only take an 
> AbsolutePath. A URL would also only provide an AbsolutePath as its “path” bit.
> 
> public enum PathComponent {
>     case this // “."
>     case up   // “..” 
>     case item(name: String, extension: String?)
> }
> 
> public protocol Path {   
>     var components: Array<PathComponent> { get }
>     init(_ components: Array<PathComponent>) // used on protocol extensions 
> that mutate paths, such as appending components
> }
> 
> public struct AbsolutePath: Path { }
> public struct RelativePath: Path { }
> 
> By separating out the concept of an Absolute and a Relative path, I can put 
> additional functionality on each one to make semantic sense (you cannot 
> concatenate two absolute paths, but you can concat any path with a relative 
> path, for example). Or all file system operations must take an AbsolutePath. 
> 
> One of the key things I realized is that a “Path” type should not be 
> ExpressibleByStringLiteral, because you cannot statically determine if a Path 
> should be absolute or relative. However, one of the initializers for an 
> AbsolutePath would handle things like expanding a tilde, and both types try 
> to reduce a set of components as much as possible (by filtering out “.this” 
> components, and handling “.up” components where possible, etc). Also in my 
> experience, it’s fairly rare to want to deal with a known-at-compile-time, 
> hard-coded path. Usually you’re dealing with paths relative to known 
> “containers” that are determined at runtime (current user’s home folder, 
> app’s sandboxed documents directory, etc).
> 
> Another thing I’ve done is that no direct file system operations exist on 
> AbsolutePath (like “.exists” or “.createDirectory(…)” or whatever); those are 
> still on FileManager/FileHandle/etc in the form of extensions to handle the 
> new types. In my app, a path is just a path, and it only has meaning based on 
> the thing that is using it. An AbsolutePath for a URL is used differently 
> than an AbsolutePath on a file system, although they are represented with the 
> same “AbsolutePath” type.
> 
> I’m not saying this is a perfect API of course, or even that a hypothetical 
> stdlib-provided Path should mimic this. I’m just saying that for my use-case, 
> this has vastly simplified how I deal with paths, because both URL and String 
> smell really bad for what I’m doing.
> 
> Dave
> 
>> On Aug 22, 2017, at 12:37 PM, Taylor Swift <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> So are you saying we need three distinct “URI” types for local-absolute, 
>> local-relative, and remote? That’s a lot of API surface to support.
>> 
>> On Tue, Aug 22, 2017 at 12:24 PM, Dave DeLong <[email protected] 
>> <mailto:[email protected]>> wrote:
>> I completely agree. URL packs a lot of punch, but IMO it’s the wrong 
>> abstraction for file system paths.
>> 
>> I maintain an app that deals a lot with file system paths, and using URL has 
>> always felt cumbersome, but String is the absolute wrong type to use. Lately 
>> as I’ve been working on it, I’ve been experimenting with a concrete “Path” 
>> type, similar to PathKit (https://github.com/kylef/PathKit/ 
>> <https://github.com/kylef/PathKit/>). Working in terms of AbsolutePath and 
>> RelativePath (what I’ve been calling things) has been extremely refreshing, 
>> because it allows me to better articulate the kind of data I’m dealing with. 
>> URL doesn’t handle pure-relative paths very well, and it’s always a bit of a 
>> mystery how resilient I need to be about checking .isFileURL or whatever. 
>> All the extra properties (port, user, password, host) feel hugely 
>> unnecessary as well.
>> 
>> Dave
>> 
>>> On Aug 20, 2017, at 11:23 PM, Félix Cloutier via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> I'm not convinced that URLs are the appropriate abstraction for a file 
>>> system path. For the record, I'm not a fan of existing Foundation methods 
>>> that create objects from an URL. There is a useful and fundamental 
>>> difference between a local path and a remote path, and conflating the two 
>>> has been a security pain point in many languages and frameworks that allow 
>>> it. Examples include remote file inclusion in PHP and malicious doctypes in 
>>> XML. Windows also had its share of issues with UNC paths.
>>> 
>>> Even when loading an arbitrary URL looks innocuous, many de-anonymizing 
>>> hacks work by causing a program to access an URL controlled by an attacker 
>>> to make it disclose the user's IP address or some other identifier.
>>> 
>>> IMO, this justifies that there should be separate types to handle local and 
>>> remote resources, so that at least developers have to be explicit about 
>>> allowing remote resources. This makes a new URL type less necessary towards 
>>> supporting file I/O.
>>> 
>>> Félix
>>> 
>>>> Le 20 août 2017 à 21:37, Taylor Swift via swift-evolution 
>>>> <[email protected] <mailto:[email protected]>> a écrit :
>>>> 
>>>> Okay so a few days ago there was a discussion 
>>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170814/038923.html>
>>>>  about getting pure swift file system support into Foundation or another 
>>>> core library, and in my opinion, doing this requires a total overhaul of 
>>>> the `URL` type (which is currently little more than a wrapper for NSURL), 
>>>> so I’ve just started a pure Swift URL library project at 
>>>> <https://github.com/kelvin13/url <https://github.com/kelvin13/url>>.
>>>> 
>>>> The library’s parsing and validation core (~1K loc pure swift) is already 
>>>> in place and functional; the goal is to eventually support all of the 
>>>> Foundation URL functionality.
>>>> 
>>>> The new `URL` type is implemented as a value type with utf8 storage backed 
>>>> by an array buffer. The URLs are just 56 bytes long each, so they should 
>>>> be able to fit into cache lines. (NSURL by comparison is over 128 bytes in 
>>>> size; it’s only saved by the fact that the thing is passed as a reference 
>>>> type.)
>>>> 
>>>> As I said, this is still really early on and not a mature library at all 
>>>> but everyone is invited to observe, provide feedback, or contribute!
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> 
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to