diff --git a/Sources/FoundationExtensions/CollectionOfUInt8.swift b/Sources/FoundationExtensions/CollectionOfUInt8.swift index 390f05f..bd104bb 100644 --- a/Sources/FoundationExtensions/CollectionOfUInt8.swift +++ b/Sources/FoundationExtensions/CollectionOfUInt8.swift @@ -1,6 +1,13 @@ // Created by Wade Tregaskis on 2024-03-02. public extension Collection where Element == UInt8 { + /// - Parameters: + /// - uppercase: Whether to use "A" through "F", or "a" through "f". + /// - delimiterEvery: Insert `delimiter` every this number of elements (``UInt8``s). If zero, no delimiters are inserted. + /// + /// The sign is ignored, so e.g. -2 means 2. + /// - delimiter: The delimiter to use. Has no effect if `delimiterEvery` is zero. + /// - Returns: A string presenting the contents of the collection in human-readable hexadecimal. func asHexString(uppercase: Bool = true, delimiterEvery: Int = 0, delimiter: String = " ") -> String { @@ -48,6 +55,9 @@ public extension Collection where Element == UInt8 { } } + /// An ASCII representation of the given collection's ``UInt8`` contents, in uppercase and without any spaces. + /// + /// This is equivalent to calling ``asHexString(uppercase:delimiterEvery:delimiter:)`` with default arguments. It is provided as a convenience so that the parentheses may be omitted. var asHexString: String { asHexString() } diff --git a/Sources/FoundationExtensions/Comparable.swift b/Sources/FoundationExtensions/Comparable.swift index 02167f8..5eedff2 100644 --- a/Sources/FoundationExtensions/Comparable.swift +++ b/Sources/FoundationExtensions/Comparable.swift @@ -1,12 +1,18 @@ // Created by Wade Tregaskis on 2024-03-06 extension Comparable { + /// Conforms the value to the given range. + /// + /// i.e. if it is below the range's lower bound, it is set to that lower bound. Otherwise it is not modified. mutating func clamp(_ range: PartialRangeFrom) { if self < range.lowerBound { self = range.lowerBound } } + /// Returns the value conformed to the given range. + /// + /// i.e. if it is below the range's lower bound, that lower bound is returned instead. Otherwise it is returned as-is. func clamped(_ range: PartialRangeFrom) -> Self { if self < range.lowerBound { range.lowerBound @@ -15,12 +21,18 @@ extension Comparable { } } + /// Conforms the value to the given range. + /// + /// i.e. if it is above the range's upper bound, it is set to that upper bound. Otherwise it is not modified. mutating func clamp(_ range: PartialRangeThrough) { if self > range.upperBound { self = range.upperBound } } + /// Returns the value conformed to the given range. + /// + /// i.e. if it is above the range's upper bound, that upper bound is returned instead. Otherwise it is returned as-is. func clamped(_ range: PartialRangeThrough) -> Self { if self > range.upperBound { range.upperBound @@ -29,6 +41,13 @@ extension Comparable { } } + /// Conforms the value to the given range. + /// + /// If it is below the range's lower bound, it is set to that lower bound. + /// + /// If it is above the range's upper bound, it is set to that upper bound. + /// + /// Otherwise it is not modified. mutating func clamp(_ range: ClosedRange) { if self < range.lowerBound { self = range.lowerBound @@ -37,6 +56,13 @@ extension Comparable { } } + /// Returns the value conformed to the given range. + /// + /// If it is below the range's lower bound, that lower bound is returned instead. + /// + /// If it is above the range's upper bound, that upper bound is returned instead. + /// + /// Otherwise it is returned as-is. func clamped(_ range: ClosedRange) -> Self { if self < range.lowerBound { range.lowerBound @@ -49,6 +75,13 @@ extension Comparable { } extension Comparable where Self: Strideable { + /// Conforms the value to the given range. + /// + /// If it is below the range's lower bound, it is set to that lower bound. + /// + /// If it is above the range's upper bound, it is set to that upper bound. + /// + /// Otherwise it is not modified. mutating func clamp(_ range: Range) { if self < range.lowerBound { self = range.lowerBound @@ -57,6 +90,13 @@ extension Comparable where Self: Strideable { } } + /// Returns the value conformed to the given range. + /// + /// If it is below the range's lower bound, that lower bound is returned instead. + /// + /// If it is above the range's upper bound, that upper bound is returned instead. + /// + /// Otherwise it is returned as-is. func clamped(_ range: Range) -> Self { if self < range.lowerBound { range.lowerBound @@ -67,12 +107,18 @@ extension Comparable where Self: Strideable { } } + /// Conforms the value to the given range. + /// + /// i.e. if it is above the range's upper bound, it is set to that upper bound. Otherwise it is not modified. mutating func clamp(_ range: PartialRangeUpTo) { if self >= range.upperBound { self = range.upperBound.advanced(by: -1) } } + /// Returns the value conformed to the given range. + /// + /// i.e. if it is above the range's upper bound, that upper bound is returned instead. Otherwise it is returned as-is. func clamped(_ range: PartialRangeUpTo) -> Self { if self >= range.upperBound { range.upperBound.advanced(by: -1) diff --git a/Sources/FoundationExtensions/Data.swift b/Sources/FoundationExtensions/Data.swift index e561f8a..0d6a0ee 100644 --- a/Sources/FoundationExtensions/Data.swift +++ b/Sources/FoundationExtensions/Data.swift @@ -4,10 +4,14 @@ import Foundation public extension Data { + /// A convenience wrapper over ``String(data:encoding:)``, to make it usable with optional chaining. + /// - Parameter encoding: The encoding method that the data should be compliant with. + /// - Returns: The decoded string, or nil if the data is not compliant with the given string encoding. func asString(encoding: String.Encoding) -> String? { String(data: self, encoding: encoding) } + // The data as a valid UTF-8 string, or nil if the data is not a valid UTF-8 string. var asString: String? { asString(encoding: .utf8) } diff --git a/Sources/FoundationExtensions/Date.swift b/Sources/FoundationExtensions/Date.swift index e36e08f..01c2b27 100644 --- a/Sources/FoundationExtensions/Date.swift +++ b/Sources/FoundationExtensions/Date.swift @@ -12,6 +12,9 @@ public extension Date { return formatter }() + /// Returns a human-readable, localised description of how long ago the date was, e.g. "2 hours ago". + /// + /// The description may be approximate, typically limited to only the first significant date & time component (e.g. just "2 hours ago" for deltas ranging from 1.5 to 2.5 hours ago). var timeAgo: String { Date.relativeDateTimeFormatter.localizedString(for: self, relativeTo: Date.now) } diff --git a/Sources/FoundationExtensions/Locale.swift b/Sources/FoundationExtensions/Locale.swift index a1b797a..0c6731d 100644 --- a/Sources/FoundationExtensions/Locale.swift +++ b/Sources/FoundationExtensions/Locale.swift @@ -4,6 +4,7 @@ import Foundation public extension Locale { + /// The POSIX locale (en\_US\_POSIX). static var POSIX: Locale { Locale(identifier: "en_US_POSIX") } diff --git a/Sources/FoundationExtensions/Optional.swift b/Sources/FoundationExtensions/Optional.swift index b3ded90..7bca893 100644 --- a/Sources/FoundationExtensions/Optional.swift +++ b/Sources/FoundationExtensions/Optional.swift @@ -4,6 +4,7 @@ import Foundation public extension Optional { + /// Returns the description (from ``String(describing:)``) of the value if it is non-nil, else the string "nil". var orNilString: String { if let value = self { return String(describing: value) @@ -14,6 +15,7 @@ public extension Optional { } public extension Optional where Wrapped == String { + /// Returns the string if it is non-nil, else the string "nil". var orNilString: String { if let self { return self diff --git a/Sources/FoundationExtensions/StringProtocol.swift b/Sources/FoundationExtensions/StringProtocol.swift index 3a3769c..1e2bf4d 100644 --- a/Sources/FoundationExtensions/StringProtocol.swift +++ b/Sources/FoundationExtensions/StringProtocol.swift @@ -7,6 +7,13 @@ private let backslashesAndQuotes = CharacterSet(["\"", "\\"]) public extension StringProtocol { + /// Returns the string enclosed in quotes, with nested quotes & backslashes escaped with backslashes. + /// + /// e.g. `Hello` → `"Hello"` + /// + /// e.g. `Hello, "world"!` → `"Hello, \"world\"!"` + /// + /// e.g. `Hello, \"world\"!!"` → `"Hello, \\\"world\\\"!!"` var quoted: String { var result = "\""