+1

-Thorsten 

> Am 23.08.2017 um 12:03 schrieb Jakob Egger via swift-evolution 
> <[email protected]>:
> 
> 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]> 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]> 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/). 
>>>> 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]> 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]> a écrit :
>>>>>> 
>>>>>> Okay so a few days ago there was a discussion 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>.
>>>>>> 
>>>>>> 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]
>>>>>> 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
> 
> _______________________________________________
> 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