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 | |
@dynamicMemberLookup | |
enum JSON: Codable, CustomStringConvertible { | |
var description: String { | |
switch self { | |
case .string(let string): return "\"\(string)\"" | |
case .number(let double): | |
if let int = Int(exactly: double) { | |
return "\(int)" |
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
// I know you meant it to be exaggerated, but I still think this is the better approach in practice: | |
enum ClassError: Error { | |
case propertyNotFound(name: String) | |
case typeMismatch(propertyName: String) | |
} | |
class Foo { | |
var properties: [(String, Any)] = [] | |
private func validateValue(_ value: Any, for property: String) throws { // Note that I pass the name just for the error; that's ok IMO |
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
public typealias JSON = [String:Any] | |
public enum JSONInitializableError: Error { | |
case initializationError(key: String) | |
} | |
public protocol JSONInitializable { | |
associatedtype Key: RawRepresentable | |
init(with json: JSON) throws | |
} |
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
// Swift3 gets rid of dispatch_once and recommends replacing it with a lazy global. | |
// That's very straightforward when dispach_once is used to initialize something, but | |
// isn't an exact match when you want something to execute once, and then become a noop | |
// in a thread-safe way. | |
// The following approach seems completely "correct" and I guess actually a bit elegant, | |
// if by "elegant" you mean "terse and not immediately obvious to the reader, which makes | |
// you look very clever." | |
var doOnce: () -> Void = { |
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
// A value that can be expressed as some Double amount of a unit. In general you should not use | |
// .doubleUnitValue except for generic algorithms, since this loses what the double represents. | |
// For example, in a Mass, you would prefer .kilogramValue rather than .doubleUnitValue so that | |
// it's clear in the code that this is in kg, and not grams or pounds or something else. | |
protocol DoubleUnit: Comparable { | |
init(doubleUnitValue: Double) | |
var doubleUnitValue: Double { get } | |
} | |
func == <T: DoubleUnit>(lhs: T, rhs: T) -> Bool { |
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
// FIXME: This seems unnecessary. My cells define an intrinsicContentSize, which I thought would be used by the flow layout | |
// but this is the only way I've been able to get it to be honored. I feel I'm missing something with auto-sizing cells. | |
extension TypeGeneratorViewController: NSCollectionViewDelegateFlowLayout { | |
public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize { | |
let cell = ForwardedProtocolItem() | |
cell.representedObject = protocols[indexPath.item] | |
return cell.view.intrinsicContentSize | |
} | |
} |
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
// Vectors can be inverted | |
private prefix func - (operand: CGVector) -> CGVector { | |
return CGVector(dx: -operand.dx, dy: -operand.dy) | |
} | |
// Vectors can be added and subtracted | |
private func + (lhs: CGVector, rhs: CGVector) -> CGVector { | |
return CGVector(dx: lhs.dx + rhs.dx, dy: lhs.dy + rhs.dy) | |
} | |
private func - (lhs: CGVector, rhs: CGVector) -> CGVector { |
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
func tomorrowsDateString(dateString: String) -> String? { | |
if let date = dateFormatter.date(from: dateString), | |
let newDate = calendar.date(byAdding: oneDayOffset, to: date) { | |
return dateFormatter.string(from: newDate) | |
} | |
return nil | |
} |
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
// This is primarily for bridging strong types into and out of Core Data which relies on NSNumber. | |
protocol NumberConvertible: CustomStringConvertible, Comparable { | |
init(number: NSNumber) | |
var numberValue: NSNumber { get } | |
} | |
// CustomStringConvertible | |
extension NumberConvertible { | |
var description: String { return numberValue.description } |
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 Darwin | |
extension Integer { | |
static func makeRandomValue() -> Self { | |
var result: Self = 0 | |
withUnsafeMutablePointer(&result) { resultPtr in | |
arc4random_buf(UnsafeMutablePointer(resultPtr), sizeof(Self.self)) | |
} | |
return result | |
} |