Initial Commit

This commit is contained in:
2025-09-23 20:22:59 -04:00
commit 743fc51873
135 changed files with 12240 additions and 0 deletions

View File

@@ -0,0 +1,171 @@
/**
* Plot
* Copyright (c) John Sundell 2019
* MIT license, see LICENSE file for details
*/
import Foundation
/// let someUrl:URL = try URL("hello") ?! AppError("What")
infix operator ?!: NilCoalescingPrecedence
public func ?!<T>(value: T?, error: @autoclosure () -> Error) throws -> T {
if let value = value { return value }
throw error()
}
internal extension String {
func asSubstring() -> Substring {
return self[self.startIndex..<self.endIndex]
}
func escaped() -> String {
var pendingAmpersandString: String?
func flushPendingAmpersandString(
withSuffix suffix: String? = nil,
resettingTo newValue: String? = nil
) -> String {
let pending = pendingAmpersandString
pendingAmpersandString = newValue
return pending.map { "&amp;\($0)\(suffix ?? "")" } ?? suffix ?? ""
}
return String(flatMap { character -> String in
switch character {
case "<":
return flushPendingAmpersandString(withSuffix: "&lt;")
case ">":
return flushPendingAmpersandString(withSuffix: "&gt;")
case "&":
return flushPendingAmpersandString(resettingTo: "")
case ";":
let pending = pendingAmpersandString.map { "&\($0);" }
pendingAmpersandString = nil
return pending ?? ";"
case "#" where pendingAmpersandString?.isEmpty == true:
pendingAmpersandString = "#"
return ""
default:
if let pending = pendingAmpersandString {
guard character.isLetter || character.isNumber else {
return flushPendingAmpersandString(withSuffix: String(character))
}
pendingAmpersandString = "\(pending)\(character)"
return ""
}
return "\(character)"
}
}) + flushPendingAmpersandString()
}
static func parseList(_ value:String?, _ separator:String = " ") throws -> [String] {
guard let value = value else { return [] }
var iterator = value.componentsIterator(separatedBy: separator)
return iterator.map({String($0)})
}
}
extension Array where Element: RawRepresentable, Element.RawValue == String {
/// Converts an array of String-backed enums to an array of their raw string values.
func toStringList(_ seperator:String) -> String {
let strList = self.map { $0.rawValue }
return strList.joined(separator: seperator)
}
}
extension Array where Element == String {
/// Converts an array of String-backed enums to an array of their raw string values.
func toStringList(_ seperator:String) -> String {
let strList = self.map { $0 }
return strList.joined(separator: seperator)
}
}
extension Array where Element == URL {
/// Converts an array of String-backed enums to an array of their raw string values.
func toStringList(_ seperator:String) -> String {
let strList = self.map { $0.absoluteString }
return strList.joined(separator: seperator)
}
}
extension Array where Element == Float {
/// Converts an array of String-backed enums to an array of their raw string values.
func toStringList(_ seperator:String) -> String {
let strList = self.map { String($0) }
return strList.joined(separator: seperator)
}
}
extension Set where Element: RawRepresentable, Element.RawValue == String {
/// Converts an array of String-backed enums to an array of their raw string values.
func toStringList(_ seperator:String) -> String {
let strList = self.map { $0.rawValue }
return strList.joined(separator: seperator)
}
}
extension Float {
static func parseList(_ value:String?, _ separator:String = " ") throws -> [Float] {
guard let value = value else { return [] }
var iterator = value.componentsIterator(separatedBy: separator)
return try iterator.map({ try Float.expect($0) })
}
static func expect(_ value:String) throws -> Float {
if let result = Float(value) {
return result
}
throw AppError("Unable to map value to float")
}
static func expect(_ value:Substring) throws -> Float {
if let result = Float(value) {
return result
}
throw AppError("Unable to map value to float")
}
}
extension URL {
static func parseList(_ value:String?, _ separator:String = " ") throws -> [URL] {
guard let value = value else { return [] }
var iterator = value.componentsIterator(separatedBy: separator)
return try iterator.map({
guard let result = URL(string:String($0)) else {
throw AppError("Invalid URL: \(String($0))")
}
return result
})
}
}
extension Bool {
public init(expect: String) throws {
if (expect == "true") {
self = true
return
}
if (expect == "false") {
self = false
return
}
throw AppError("Unexpected value for bool: \(expect)")
}
public init(expectYesOrNo: String) throws {
if (expectYesOrNo == "yes") {
self = true
return
}
if (expectYesOrNo == "no") {
self = false
return
}
throw AppError("Unexpected value for bool: \(expectYesOrNo)")
}
}