Skip to content

Commit

Permalink
Upgrade to Swift 5
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Mar 26, 2019
1 parent 90cad3c commit 7b999da
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 177 deletions.
8 changes: 4 additions & 4 deletions Gifski.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@
TargetAttributes = {
E3AE62821E5CD2F300035A2F = {
CreatedOnToolsVersion = 8.2.1;
LastSwiftMigration = 1000;
LastSwiftMigration = 1020;
SystemCapabilities = {
com.apple.HardenedRuntime = {
enabled = 1;
Expand All @@ -252,7 +252,7 @@
};
buildConfigurationList = E3AE627E1E5CD2F300035A2F /* Build configuration list for PBXProject "Gifski" */;
compatibilityVersion = "Xcode 10.0";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
Base,
Expand Down Expand Up @@ -529,7 +529,7 @@
SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OBJC_BRIDGING_HEADER = "Gifski/Gifski-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
USER_HEADER_SEARCH_PATHS = "";
};
name = Debug;
Expand Down Expand Up @@ -564,7 +564,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Gifski/Gifski-Bridging-Header.h";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
USER_HEADER_SEARCH_PATHS = "";
};
name = Release;
Expand Down
15 changes: 11 additions & 4 deletions Gifski/Vendor/CircularProgress+Util.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import AppKit

extension NSBezierPath {
static func circle(radius: Double, center: CGPoint, startAngle: Double = 0, endAngle: Double = 360) -> NSBezierPath {
let path = NSBezierPath()
static func circle(
radius: Double,
center: CGPoint,
startAngle: Double = 0,
endAngle: Double = 360
) -> Self {
let path = self.init()
path.appendArc(
withCenter: center,
radius: CGFloat(radius),
Expand Down Expand Up @@ -75,8 +80,10 @@ extension CALayer {
}

extension CAShapeLayer {
static func circle(radius: Double, center: CGPoint) -> CAShapeLayer {
return CAShapeLayer(path: NSBezierPath.circle(radius: radius, center: center))
static func circle(radius: Double, center: CGPoint) -> Self {
let layer = self.init()
layer.path = NSBezierPath.circle(radius: radius, center: center).cgPath
return layer
}

convenience init(path: NSBezierPath) {
Expand Down
3 changes: 1 addition & 2 deletions Gifski/Vendor/CircularProgress.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import Cocoa
@IBDesignable
public final class CircularProgress: NSView {
private var lineWidth: Double = 2
// TODO: Remove the closure here when targeting Swift 5
private lazy var radius = { bounds.width < bounds.height ? bounds.midX * 0.8 : bounds.midY * 0.8 }()
private lazy var radius = bounds.width < bounds.height ? bounds.midX * 0.8 : bounds.midY * 0.8
private var _progress: Double = 0
private var progressObserver: NSKeyValueObservation?
private var finishedObserver: NSKeyValueObservation?
Expand Down
9 changes: 6 additions & 3 deletions Gifski/Vendor/DockProgress.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Vendored from: https://github.com/sindresorhus/DockProgress
// TODO: Use Carthage and frameworks again when targeting Swift 5 as it should be ABI stable
// TODO: Use Carthage and frameworks again when targeting macOS 10.14.4 since it's ABI stable
import Cocoa

public final class DockProgress {
Expand Down Expand Up @@ -257,9 +257,10 @@ let label = with(NSTextField()) {


extension NSBezierPath {
static func progressCircle(radius: Double, center: CGPoint) -> NSBezierPath {
/// For making a circle progress indicator
static func progressCircle(radius: Double, center: CGPoint) -> Self {
let startAngle: CGFloat = 90
let path = NSBezierPath()
let path = self.init()
path.appendArc(
withCenter: center,
radius: CGFloat(radius),
Expand Down Expand Up @@ -341,6 +342,8 @@ extension NSBezierPath {
path.addCurve(to: points[2], control1: points[0], control2: points[1])
case .closePath:
path.closeSubpath()
@unknown default:
assertionFailure("NSBezierPath received a new enum case. Please handle it.")
}
}

Expand Down
175 changes: 12 additions & 163 deletions Gifski/util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,13 @@ extension NSWindow {

static let defaultStyleMask: NSWindow.StyleMask = [.titled, .closable, .miniaturizable, .resizable]

static func centeredWindow(size: CGSize = defaultContentSize) -> NSWindow {
let window = NSWindow()
static func centeredWindow(size: CGSize = defaultContentSize) -> Self {
let window = self.init(
contentRect: NSWindow.defaultContentRect,
styleMask: NSWindow.defaultStyleMask,
backing: .buffered,
defer: true
)
window.setContentSize(size)
window.centerNatural()
return window
Expand Down Expand Up @@ -312,18 +317,9 @@ extension AVAssetImageGenerator {
let isFinished: Bool
}

// TODO: Remove this when using Swift 5 and use `CancellationError` in the cancellation case
enum Error: CancellableError {
case cancelled

var isCancelled: Bool {
return self == .cancelled
}
}

func generateCGImagesAsynchronously(
forTimePoints timePoints: [CMTime],
completionHandler: @escaping (CoreResult<CompletionHandlerResult, Error>) -> Void
completionHandler: @escaping (Swift.Result<CompletionHandlerResult, Error>) -> Void
) {
let times = timePoints.map { NSValue(time: $0) }
let totalCount = times.count
Expand All @@ -348,9 +344,11 @@ extension AVAssetImageGenerator {
)
)
case .failed:
completionHandler(.failure(error! as! Error))
completionHandler(.failure(error!))
case .cancelled:
completionHandler(.failure(.cancelled))
completionHandler(.failure(CancellationError()))
@unknown default:
assertionFailure("AVAssetImageGenerator.generateCGImagesAsynchronously() received a new enum case. Please handle it.")
}
}
}
Expand Down Expand Up @@ -1193,155 +1191,6 @@ extension CGRect {
}
}

// TODO: Remove when using Swift 5
/// Polyfill for Swift 5
/// https://github.com/moiseev/swift/blob/47740c012943020aa89df93129b4fc2f33618c00/stdlib/public/core/Result.swift
///
/// A value that represents either a success or a failure, including an
/// associated value in each case.
public enum Result<Success, Failure: Swift.Error> {
/// A success, storing a `Success` value.
case success(Success)

/// A failure, storing a `Failure` value.
case failure(Failure)

/// Returns a new result, mapping any success value using the given
/// transformation.
///
/// Use this method when you need to transform the value of a `Result`
/// instance when it represents a success. The following example transforms
/// the integer success value of a result into a string:
///
/// func getNextInteger() -> Result<Int, Error> { ... }
///
/// let integerResult = getNextInteger()
/// // integerResult == .success(5)
/// let stringResult = integerResult.map({ String($0) })
/// // stringResult == .success("5")
///
/// - Parameter transform: A closure that takes the success value of this
/// instance.
/// - Returns: A `Result` instance with the result of evaluating `transform`
/// as the new success value if this instance represents a success.
public func map<NewSuccess>(
_ transform: (Success) -> NewSuccess
) -> Result<NewSuccess, Failure> {
switch self {
case let .success(success):
return .success(transform(success))
case let .failure(failure):
return .failure(failure)
}
}

/// Returns a new result, mapping any failure value using the given
/// transformation.
///
/// Use this method when you need to transform the value of a `Result`
/// instance when it represents a failure. The following example transforms
/// the error value of a result by wrapping it in a custom `Error` type:
///
/// struct DatedError: Error {
/// var error: Error
/// var date: Date
///
/// init(_ error: Error) {
/// self.error = error
/// self.date = Date()
/// }
/// }
///
/// let result: Result<Int, Error> = ...
/// // result == .failure(<error value>)
/// let resultWithDatedError = result.mapError({ e in DatedError(e) })
/// // result == .failure(DatedError(error: <error value>, date: <date>))
///
/// - Parameter transform: A closure that takes the failure value of the
/// instance.
/// - Returns: A `Result` instance with the result of evaluating `transform`
/// as the new failure value if this instance represents a failure.
public func mapError<NewFailure>(
_ transform: (Failure) -> NewFailure
) -> Result<Success, NewFailure> {
switch self {
case let .success(success):
return .success(success)
case let .failure(failure):
return .failure(transform(failure))
}
}

/// Returns a new result, mapping any success value using the given
/// transformation and unwrapping the produced result.
///
/// - Parameter transform: A closure that takes the success value of the
/// instance.
/// - Returns: A `Result` instance with the result of evaluating `transform`
/// as the new failure value if this instance represents a failure.
public func flatMap<NewSuccess>(
_ transform: (Success) -> Result<NewSuccess, Failure>
) -> Result<NewSuccess, Failure> {
switch self {
case let .success(success):
return transform(success)
case let .failure(failure):
return .failure(failure)
}
}

/// Returns a new result, mapping any failure value using the given
/// transformation and unwrapping the produced result.
///
/// - Parameter transform: A closure that takes the failure value of the
/// instance.
/// - Returns: A `Result` instance, either from the closure or the previous
/// `.success`.
public func flatMapError<NewFailure>(
_ transform: (Failure) -> Result<Success, NewFailure>
) -> Result<Success, NewFailure> {
switch self {
case let .success(success):
return .success(success)
case let .failure(failure):
return transform(failure)
}
}

/// Returns the success value as a throwing expression.
///
/// Use this method to retrieve the value of this result if it represents a
/// success, or to catch the value if it represents a failure.
///
/// let integerResult: Result<Int, Error> = .success(5)
/// do {
/// let value = try integerResult.get()
/// print("The value is \(value).")
/// } catch error {
/// print("Error retrieving the value: \(error)")
/// }
/// // Prints "The value is 5."
///
/// - Returns: The success value, if the instance represent a success.
/// - Throws: The failure value, if the instance represents a failure.
public func get() throws -> Success {
switch self {
case let .success(success):
return success
case let .failure(failure):
throw failure
}
}
}

extension Result: Equatable where Success: Equatable, Failure: Equatable {}
extension Result: Hashable where Success: Hashable, Failure: Hashable {}

// To be able to use it in places that already have a local result
// TODO: Remove this when using Swift 5
typealias CoreResult = Result


public protocol CancellableError: Error {
/// Returns true if this Error represents a cancelled condition
var isCancelled: Bool { get }
Expand Down
2 changes: 1 addition & 1 deletion gifski-api/gifski.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CA604FAB06E35E768CFD9133;
productRefGroup = CA601B394EBE421D4EA7417A /* Products */;
Expand Down

0 comments on commit 7b999da

Please sign in to comment.