This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
protocol RawHashableConvertible: RawRepresentable, Hashable, CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable { } | |
extension RawHashableConvertible where RawValue == String { | |
var description: String { | |
return rawValue | |
} | |
var debugDescription: String { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension String { | |
var javaScriptEscapedString: String { | |
// Because JSON is not a subset of JavaScript, the LINE_SEPARATOR and PARAGRAPH_SEPARATOR unicode | |
// characters embedded in (valid) JSON will cause the webview's JavaScript parser to error. So we | |
// must encode them first. See here: http://timelessrepo.com/json-isnt-a-javascript-subset | |
// Also here: http://media.giphy.com/media/wloGlwOXKijy8/giphy.gif | |
let str = self.replacingOccurrences(of: "\u{2028}", with: "\\u2028") | |
.replacingOccurrences(of: "\u{2029}", with: "\\u2029") | |
// Because escaping JavaScript is a non-trivial task (https://github.com/johnezang/JSONKit/blob/master/JSONKit.m#L1423) | |
// we proceed to hax instead: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension Task where Failure == Error { | |
// Start a new Task with a timeout. If the timeout expires before the operation is | |
// completed then the task is cancelled and an error is thrown. | |
init(priority: TaskPriority? = nil, timeout: TimeInterval, operation: @escaping @Sendable () async throws -> Success) { | |
self = Task(priority: priority) { | |
try await withThrowingTaskGroup(of: Success.self) { group -> Success in | |
group.addTask(operation: operation) | |
group.addTask { | |
try await _Concurrency.Task.sleep(nanoseconds: UInt64(timeout * 1_000_000_000)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
#if canImport(UIKit) | |
import UIKit | |
#elseif canImport(AppKit) | |
import AppKit | |
#elseif canImport(WatchKit) | |
import WatchKit | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import notify | |
import Combine | |
enum Notify {} | |
extension Notify { | |
struct Status: Error { | |
let rawValue: UInt32 | |
init(_ rawValue: UInt32) { | |
self.rawValue = rawValue |