Skip to content

Instantly share code, notes, and snippets.

View ollieatkinson's full-sized avatar

Oliver Atkinson ollieatkinson

View GitHub Profile
@ollieatkinson
ollieatkinson / AnyResult.swift
Last active December 23, 2020 22:04
AnyResult
protocol AnyResult {
associatedtype Success
associatedtype Failure: Error
static func success(_ success: Success) -> Self
static func failure(_ failure: Failure) -> Self
func map<NewSuccess>(_ transform: (Success) -> NewSuccess) -> Result<NewSuccess, Failure>
func mapError<NewFailure>(_ transform: (Failure) -> NewFailure) -> Result<Success, NewFailure> where NewFailure : Error
@ollieatkinson
ollieatkinson / FileSystemEventStream.swift
Created October 22, 2020 10:27
sane `fsevents` in Swift
import Foundation
import Combine
public struct Event: Identifiable {
public let id: FSEventStreamEventId
public let path: String
public let flags: Flags
}
public class FileSystemEventStream {
@ollieatkinson
ollieatkinson / JSON.swift
Last active December 29, 2020 17:09
Hacking around with JSON represented as an indirect enum
import Foundation
public indirect enum JSON: Hashable {
public enum Leaf: Hashable {
case null
case boolean(Bool)
case number(NSNumber)
case string(String)
case error(Error)
@ollieatkinson
ollieatkinson / Dictionary+KeyPath.swift
Last active January 7, 2024 03:30
KeyPath to get/set from a Swift JSON object ([String: Any] or [Any])
import Foundation
extension Dictionary where Key == String, Value == Any {
public subscript(keyPath: JSON.Path.Index...) -> Value? {
get { self[keyPath: .init(path: keyPath)] }
set { self[keyPath: .init(path: keyPath)] = newValue }
}
public subscript(keyPath keyPath: JSON.Path) -> Value? {
@ollieatkinson
ollieatkinson / JSONObject.swift
Last active April 8, 2024 21:41
JSON Equatable in Swift
public let null = NSNull() as AnyHashable
public enum JSONObject {
case array([Any])
case dictionary([String: Any])
case fragment(Any)
}
extension JSONObject {
@inlinable public static func with(_ data: Data, options: JSONSerialization.ReadingOptions = []) throws -> JSONObject {
@ollieatkinson
ollieatkinson / AnyEquatable.swift
Last active September 30, 2020 21:22
Equatable for Any
extension Equatable {
public static func isEqual(_ l: Any, _ r: Any) -> Bool {
(l as? Self).map { isEqual($0, r) } ?? false
}
public static func isEqual(_ l: Self, _ r: Any) -> Bool {
isEqual(r, l)
}
public static func isEqual(_ l: Any, _ r: Self) -> Bool {
(l as? Self).map{ $0 == r } ?? false
}
@ollieatkinson
ollieatkinson / NotificationCenter.swift
Last active June 14, 2022 11:39
Making NotificationCenter easier to work with and allowing type-safe rules
extension NotificationCenter {
public func observe(
name: NSNotification.Name,
object obj: Any? = nil,
queue: OperationQueue? = .main,
using block: @escaping (Notification?) -> Void
) -> Notification.Token {
return Notification.Token(
on: self,
@ollieatkinson
ollieatkinson / NSRegularExpression+Sugar.swift
Last active September 15, 2020 14:41
Candy for NSRegularExpression matching. Match allows for indexed and named capture groups
import Foundation
extension NSRegularExpression {
@dynamicMemberLookup
public struct Match {
let string: String
let result: [NSTextCheckingResult]
private lazy var iterator = result.makeIterator()
public init(_ string: String, _ result: [NSTextCheckingResult]) {
@ollieatkinson
ollieatkinson / Measurement+UnitInformationStorage+Pivot.Swift
Last active June 14, 2022 11:40
Measurement sugar for UnitInformationStorage
extension Measurement where UnitType == UnitInformationStorage {
@inlinable public var B: Self { converted(to: .bytes) }
@inlinable public var kB: Self { converted(to: .kilobytes) }
@inlinable public var MB: Self { converted(to: .megabytes) }
@inlinable public var GB: Self { converted(to: .gigabytes) }
@inlinable public var TB: Self { converted(to: .terabytes) }
@inlinable public var PB: Self { converted(to: .petabytes) }
@inlinable public var EB: Self { converted(to: .exabytes) }
@ollieatkinson
ollieatkinson / Publisher+Scan.swift
Created September 10, 2020 08:13
scan() and scan(count:) extension on Combine.Publisher
extension Publisher {
@inlinable public func scan() -> AnyPublisher<(newValue: Output, oldValue: Output), Failure> {
scan(count: 2)
.map { ($0[1], $0[0]) }
.eraseToAnyPublisher()
}
@inlinable public func scan(count: Int) -> AnyPublisher<[Output], Failure> {
scan([]) { ($0 + [$1]).suffix(count) }