100% documentation please

This commit is contained in:
Max Howell
2019-01-19 14:36:27 -05:00
parent 29149da72b
commit 3eda9a9741
8 changed files with 146 additions and 9 deletions

View File

@@ -1,16 +1,32 @@
import Foundation
/**
Represents a platform filesystem absolute path.
The recommended conversions from string are:
let p1 = Path.root/pathString
let p2 = Path.root/url.path
let p3 = Path.cwd/relativePathString
let p4 = Path(userInput) ?? Path.cwd/userInput
- Note: There may not be an actual filename at the path.
*/
public struct Path: Equatable, Hashable, Comparable {
/// The underlying filesystem path
public let string: String
/// Returns a `Path` containing ``FileManager.default.currentDirectoryPath`.
public static var cwd: Path {
return Path(string: FileManager.default.currentDirectoryPath)
}
/// Returns a `Path` representing the root path.
public static var root: Path {
return Path(string: "/")
}
/// Returns a `Path` representing the users home directory
public static var home: Path {
let string: String
#if os(macOS)
@@ -25,21 +41,42 @@ public struct Path: Equatable, Hashable, Comparable {
return Path(string: string)
}
/**
Returns the filename extension of this path.
- Remark: Implemented via `NSString.pathExtension`.
*/
@inlinable
public var `extension`: String {
return (string as NSString).pathExtension
}
/// - Note: always returns a valid path, `Path.root.parent` *is* `Path.root`
/**
Returns the parent directory for this path.
Path is not aware of the nature of the underlying file, but this is
irrlevant since the operation is the same irrespective of this fact.
- Note: always returns a valid path, `Path.root.parent` *is* `Path.root`.
*/
public var parent: Path {
return Path(string: (string as NSString).deletingLastPathComponent)
}
/// Returns a `URL` representing this file path.
@inlinable
public var url: URL {
return URL(fileURLWithPath: string)
}
/**
The basename for the provided file, optionally dropping the file extension.
Path.root.join("foo.swift").basename() // => "foo.swift"
Path.root.join("foo.swift").basename(dropExtension: true) // => "foo"
- Returns: A string that is the filenames basename.
- Parameter dropExtension: If `true` returns the basename without its file extension.
*/
public func basename(dropExtension: Bool = false) -> String {
let str = string as NSString
if !dropExtension {
@@ -54,7 +91,13 @@ public struct Path: Equatable, Hashable, Comparable {
}
}
//TODO another variant that returns `nil` if result would start with `..`
/**
Returns a string representing the relative path to `base`.
- Note: If `base` is not a logical prefix for `self` your result will be prefixed some number of `../` components.
- Parameter base: The base to which we calculate the relative path.
- ToDo: Another variant that returns `nil` if result would start with `..`
*/
public func relative(to base: Path) -> String {
// Split the two paths into their components.
// FIXME: The is needs to be optimized to avoid unncessary copying.
@@ -85,27 +128,59 @@ public struct Path: Equatable, Hashable, Comparable {
}
}
public func join<S>(_ part: S) -> Path where S: StringProtocol {
/**
Joins a path and a string to produce a new path.
Path.root.join("a") // => /a
Path.root.join("a/b") // => /a/b
Path.root.join("a").join("b") // => /a/b
Path.root.join("a").join("/b") // => /a/b
- Parameter pathComponent: The string to join with this path.
- Returns: A new joined path.
- SeeAlso: /(:Path,:String)
*/
public func join<S>(_ pathComponent: S) -> Path where S: StringProtocol {
//TODO standardizingPath does more than we want really (eg tilde expansion)
let str = (string as NSString).appendingPathComponent(String(part))
let str = (string as NSString).appendingPathComponent(String(pathComponent))
return Path(string: (str as NSString).standardizingPath)
}
/// Returns the locale-aware sort order for the two paths.
@inlinable
public static func <(lhs: Path, rhs: Path) -> Bool {
return lhs.string.compare(rhs.string, locale: .current) == .orderedAscending
}
/// A file entry from a directory listing.
public struct Entry {
/// The kind of this directory entry.
public enum Kind {
/// The path is a file.
case file
/// The path is a directory.
case directory
}
/// The kind of this entry.
public let kind: Kind
/// The path of this entry.
public let path: Path
}
}
/**
Joins a path and a string to produce a new path.
Path.root/"a" // => /a
Path.root/"a/b" // => /a/b
Path.root/"a"/"b" // => /a/b
Path.root/"a"/"/b" // => /a/b
- Parameter lhs: The base path to join with `rhs`.
- Parameter rhs: The string to join with this `lhs`.
- Returns: A new joined path.
- SeeAlso: Path.join(_:)
*/
@inlinable
public func /<S>(lhs: Path, rhs: S) -> Path where S: StringProtocol {
return lhs.join(rhs)