Revert to Swift 1.2

This commit is contained in:
Andrew Naylor 2015-08-10 23:17:27 +08:00
parent cb16a0ec92
commit bdf66136df
14 changed files with 224 additions and 284 deletions

View file

@ -3,7 +3,7 @@
/// Wraps a type `T` in a reference type.
///
/// Typically this is used to work around limitations of value types (for example, the lack of codegen for recursive value types and type-parameterized enums with >1 case). It is also useful for sharing a single (presumably large) value without copying it.
public final class Box<T>: BoxType, CustomStringConvertible {
public final class Box<T>: BoxType, Printable {
/// Initializes a `Box` with the given value.
public init(_ value: T) {
self.value = value
@ -28,6 +28,6 @@ public final class Box<T>: BoxType, CustomStringConvertible {
// MARK: Printable
public var description: String {
return String(value)
return toString(value)
}
}

View file

@ -5,7 +5,7 @@
/// While this, like `Box<T>` could be used to work around limitations of value types, it is much more useful for sharing a single mutable value such that mutations are shared.
///
/// As with all mutable state, this should be used carefully, for example as an optimization, rather than a default design choice. Most of the time, `Box<T>` will suffice where any `BoxType` is needed.
public final class MutableBox<T>: MutableBoxType, CustomStringConvertible {
public final class MutableBox<T>: MutableBoxType, Printable {
/// Initializes a `MutableBox` with the given value.
public init(_ value: T) {
self.value = value
@ -22,6 +22,6 @@ public final class MutableBox<T>: MutableBoxType, CustomStringConvertible {
// MARK: Printable
public var description: String {
return String(value)
return toString(value)
}
}

View file

@ -37,7 +37,7 @@ private func ==(lhs: RawArgument, rhs: RawArgument) -> Bool {
}
}
extension RawArgument: CustomStringConvertible {
extension RawArgument: Printable {
private var description: String {
switch self {
case let .Key(key):
@ -67,8 +67,8 @@ public final class ArgumentParser {
rawArguments.extend(options.map { arg in
if arg.hasPrefix("-") {
// Do we have `--{key}` or `-{flags}`.
let opt = dropFirst(arg.characters)
return String(opt).hasPrefix("-") ? .Key(String(dropFirst(opt))) : .Flag(Set(opt))
var opt = dropFirst(arg)
return opt.hasPrefix("-") ? .Key(dropFirst(opt)) : .Flag(Set(opt))
} else {
return .Value(arg)
}
@ -77,7 +77,7 @@ public final class ArgumentParser {
// Remaining arguments are all positional parameters.
if params.count == 2 {
let positional = params.last!
rawArguments.extend(Array(positional.map { .Value($0) }))
rawArguments.extend(positional.map { .Value($0) })
}
}
@ -130,13 +130,13 @@ public final class ArgumentParser {
}
}
return .Failure(missingArgumentError("--\(key)"))
return .failure(missingArgumentError("--\(key)"))
} else {
rawArguments.append(arg)
}
}
return .Success(foundValue)
return .success(foundValue)
}
/// Returns the next positional argument that hasn't yet been returned, or
@ -168,7 +168,7 @@ public final class ArgumentParser {
/// Returns whether the given flag was specified and removes it from the
/// list of arguments remaining.
internal func consumeBooleanFlag(flag: Character) -> Bool {
for (index, arg) in rawArguments.enumerate() {
for (index, arg) in enumerate(rawArguments) {
switch arg {
case var .Flag(flags) where flags.contains(flag):
flags.remove(flag)

View file

@ -58,7 +58,7 @@ public final class CommandRegistry<ClientError> {
/// All available commands.
public var commands: [CommandOf<ClientError>] {
return commandsByVerb.values.sort { return $0.verb < $1.verb }
return sorted(commandsByVerb.values) { return $0.verb < $1.verb }
}
public init() {}
@ -100,7 +100,7 @@ extension CommandRegistry {
/// If a matching command could not be found or a usage error occurred,
/// a helpful error message will be written to `stderr`, then the process
/// will exit with a failure error code.
@noreturn public func main(defaultVerb defaultVerb: String, errorHandler: ClientError -> ()) {
@noreturn public func main(#defaultVerb: String, errorHandler: ClientError -> ()) {
var arguments = Process.arguments
assert(arguments.count >= 1)
@ -119,12 +119,12 @@ extension CommandRegistry {
exit(EXIT_SUCCESS)
case let .Some(.Failure(error)):
switch error {
switch error.value {
case let .UsageError(description):
fputs(description + "\n", stderr)
case let .CommandError(error):
errorHandler(error)
errorHandler(error.value)
}
exit(EXIT_FAILURE)

View file

@ -12,22 +12,22 @@ import Foundation
///
/// `ClientError` should be the type of error (if any) that can occur when
/// running commands.
public enum CommandantError<ClientError>: ErrorType {
public enum CommandantError<ClientError> {
/// An option was used incorrectly.
case UsageError(description: String)
/// An error occurred while running a command.
case CommandError(ClientError)
case CommandError(Box<ClientError>)
}
extension CommandantError: CustomStringConvertible {
extension CommandantError: Printable {
public var description: String {
switch self {
case let .UsageError(description):
return description
case let .CommandError(error):
return String(error)
return toString(error)
}
}
}
@ -47,7 +47,7 @@ internal func missingArgumentError<ClientError>(argumentName: String) -> Command
internal func informativeUsageError<ClientError>(keyValueExample: String, usage: String) -> CommandantError<ClientError> {
let lines = usage.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
return .UsageError(description: lines.reduce(keyValueExample) { previous, value in
return .UsageError(description: reduce(lines, keyValueExample) { previous, value in
return previous + "\n\t" + value
})
}
@ -56,9 +56,9 @@ internal func informativeUsageError<ClientError>(keyValueExample: String, usage:
/// example of key (and value, if applicable) usage.
internal func informativeUsageError<T, ClientError>(keyValueExample: String, option: Option<T>) -> CommandantError<ClientError> {
if option.defaultValue != nil {
return informativeUsageError("[\(keyValueExample)]", usage: option.usage)
return informativeUsageError("[\(keyValueExample)]", option.usage)
} else {
return informativeUsageError(keyValueExample, usage: option.usage)
return informativeUsageError(keyValueExample, option.usage)
}
}
@ -81,7 +81,7 @@ internal func informativeUsageError<T: ArgumentType, ClientError>(option: Option
example += valueExample
}
return informativeUsageError(example, option: option)
return informativeUsageError(example, option)
}
/// Constructs an error that describes how to use the given boolean option.
@ -91,9 +91,9 @@ internal func informativeUsageError<ClientError>(option: Option<Bool>) -> Comman
let key = option.key!
if let defaultValue = option.defaultValue {
return informativeUsageError((defaultValue ? "--no-\(key)" : "--\(key)"), option: option)
return informativeUsageError((defaultValue ? "--no-\(key)" : "--\(key)"), option)
} else {
return informativeUsageError("--(no-)\(key)", option: option)
return informativeUsageError("--(no-)\(key)", option)
}
}

View file

@ -34,27 +34,28 @@ public struct HelpCommand<ClientError>: CommandType {
.flatMap { options in
if let verb = options.verb {
if let command = self.registry[verb] {
print(command.function + "\n")
println(command.function)
println()
return command.run(.Usage)
} else {
fputs("Unrecognized command: '\(verb)'\n", stderr)
}
}
print("Available commands:\n")
println("Available commands:\n")
let maxVerbLength = self.registry.commands.map { $0.verb.characters.count }.maxElement() ?? 0
let maxVerbLength = maxElement(self.registry.commands.map { count($0.verb) })
for command in self.registry.commands {
let padding = Repeat<Character>(count: maxVerbLength - command.verb.characters.count, repeatedValue: " ")
let padding = Repeat<Character>(count: maxVerbLength - count(command.verb), repeatedValue: " ")
var formattedVerb = command.verb
formattedVerb.extend(padding)
print(" \(formattedVerb) \(command.function)")
println(" \(formattedVerb) \(command.function)")
}
return .Success(())
return .success(())
}
}
}
@ -67,7 +68,7 @@ private struct HelpOptions<ClientError>: OptionsType {
}
static func create(verb: String) -> HelpOptions {
return self.init(verb: (verb == "" ? nil : verb))
return self(verb: (verb == "" ? nil : verb))
}
static func evaluate(m: CommandMode) -> Result<HelpOptions, CommandantError<ClientError>> {

View file

@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<string>org.carthage.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>0.6.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View file

@ -81,7 +81,7 @@ public struct Option<T> {
}
}
extension Option: CustomStringConvertible {
extension Option: Printable {
public var description: String {
if let key = key {
return "--\(key)"
@ -104,18 +104,10 @@ extension Int: ArgumentType {
public static let name = "integer"
public static func fromString(string: String) -> Int? {
return Int(string)
return string.toInt()
}
}
extension UInt64: ArgumentType {
public static let name = "integer"
public static func fromString(string: String) -> UInt64? {
return UInt64(string, radix: 10)
}
}
extension String: ArgumentType {
public static let name = "string"
@ -174,17 +166,17 @@ public func <*> <T, U, ClientError>(f: T -> U, value: Result<T, CommandantError<
public func <*> <T, U, ClientError>(f: Result<(T -> U), CommandantError<ClientError>>, value: Result<T, CommandantError<ClientError>>) -> Result<U, CommandantError<ClientError>> {
switch (f, value) {
case let (.Failure(left), .Failure(right)):
return .Failure(combineUsageErrors(left, rhs: right))
return .failure(combineUsageErrors(left.value, right.value))
case let (.Failure(left), .Success):
return .Failure(left)
return .failure(left.value)
case let (.Success, .Failure(right)):
return .Failure(right)
return .failure(right.value)
case let (.Success(f), .Success(value)):
let newValue = f(value)
return .Success(newValue)
let newValue = f.value(value.value)
return .success(newValue)
}
}
@ -199,12 +191,12 @@ public func <| <T: ArgumentType, ClientError>(mode: CommandMode, option: Option<
if let key = option.key {
switch arguments.consumeValueForKey(key) {
case let .Success(value):
stringValue = value
stringValue = value.value
case let .Failure(error):
switch error {
switch error.value {
case let .UsageError(description):
return .Failure(.UsageError(description: description))
return .failure(.UsageError(description: description))
case .CommandError:
fatalError("CommandError should be impossible when parameterized over NoError")
@ -216,18 +208,18 @@ public func <| <T: ArgumentType, ClientError>(mode: CommandMode, option: Option<
if let stringValue = stringValue {
if let value = T.fromString(stringValue) {
return .Success(value)
return .success(value)
}
return .Failure(option.invalidUsageError(stringValue))
return .failure(option.invalidUsageError(stringValue))
} else if let defaultValue = option.defaultValue {
return .Success(defaultValue)
return .success(defaultValue)
} else {
return .Failure(missingArgumentError(option.description))
return .failure(missingArgumentError(option.description))
}
case .Usage:
return .Failure(informativeUsageError(option))
return .failure(informativeUsageError(option))
}
}
@ -241,14 +233,14 @@ public func <| <ClientError>(mode: CommandMode, option: Option<Bool>) -> Result<
switch mode {
case let .Arguments(arguments):
if let value = arguments.consumeBooleanKey(option.key!) {
return .Success(value)
return .success(value)
} else if let defaultValue = option.defaultValue {
return .Success(defaultValue)
return .success(defaultValue)
} else {
return .Failure(missingArgumentError(option.description))
return .failure(missingArgumentError(option.description))
}
case .Usage:
return .Failure(informativeUsageError(option))
return .failure(informativeUsageError(option))
}
}

View file

@ -33,7 +33,7 @@ public struct Switch {
}
}
extension Switch: CustomStringConvertible {
extension Switch: Printable {
public var description: String {
var options = "--\(key)"
if let flag = self.flag {
@ -54,9 +54,9 @@ public func <| <ClientError> (mode: CommandMode, option: Switch) -> Result<Bool,
if let flag = option.flag {
enabled = arguments.consumeBooleanFlag(flag)
}
return .Success(enabled)
return .success(enabled)
case .Usage:
return .Failure(informativeUsageError(option.description, usage: option.usage))
return .failure(informativeUsageError(option.description, option.usage))
}
}

View file

@ -1,183 +1,163 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
/// An enum representing either a failure with an explanatory error, or a success with a result value.
public enum Result<T, Error: ErrorType>: ResultType, CustomStringConvertible, CustomDebugStringConvertible {
case Success(T)
case Failure(Error)
// MARK: Constructors
/// Constructs a success wrapping a `value`.
public init(value: T) {
self = .Success(value)
}
/// Constructs a failure wrapping an `error`.
public init(error: Error) {
self = .Failure(error)
}
/// Constructs a result from an Optional, failing with `Error` if `nil`
public init(_ value: T?, @autoclosure failWith: () -> Error) {
self = value.map(Result.Success) ?? .Failure(failWith())
}
/// Constructs a result from a function that uses `throw`, failing with `Error` if throws
public init(@autoclosure _ f: () throws -> T) {
do {
self = .Success(try f())
} catch {
self = .Failure(error as! Error)
}
}
// MARK: Deconstruction
/// Returns the value from `Success` Results or `throw`s the error
public func dematerialize() throws -> T {
switch self {
case let .Success(value):
return value
case let .Failure(error):
throw error
}
}
/// Case analysis for Result.
///
/// Returns the value produced by applying `ifFailure` to `Failure` Results, or `ifSuccess` to `Success` Results.
public func analysis<Result>(@noescape ifSuccess ifSuccess: T -> Result, @noescape ifFailure: Error -> Result) -> Result {
switch self {
case let .Success(value):
return ifSuccess(value)
case let .Failure(value):
return ifFailure(value)
}
}
// MARK: Higher-order functions
/// Returns a new Result by mapping `Success`es values using `transform`, or re-wrapping `Failure`s errors.
public func map<U>(@noescape transform: T -> U) -> Result<U, Error> {
return flatMap { .Success(transform($0)) }
}
/// Returns the result of applying `transform` to `Success`es values, or re-wrapping `Failure`s errors.
public func flatMap<U>(@noescape transform: T -> Result<U, Error>) -> Result<U, Error> {
return analysis(
ifSuccess: transform,
ifFailure: Result<U, Error>.Failure)
}
/// Returns `self.value` if this result is a .Success, or the given value otherwise. Equivalent with `??`
public func recover(@autoclosure value: () -> T) -> T {
return self.value ?? value()
}
/// Returns this result if it is a .Success, or the given result otherwise. Equivalent with `??`
public func recoverWith(@autoclosure result: () -> Result<T,Error>) -> Result<T,Error> {
return analysis(
ifSuccess: { _ in self },
ifFailure: { _ in result() })
}
/// Transform a function from one that uses `throw` to one that returns a `Result`
// public static func materialize<T, U>(f: T throws -> U) -> T -> Result<U, ErrorType> {
// return { x in
// do {
// return .Success(try f(x))
// } catch {
// return .Failure(error)
// }
// }
// }
// MARK: Errors
/// The domain for errors constructed by Result.
public static var errorDomain: String { return "com.antitypical.Result" }
/// The userInfo key for source functions in errors constructed by Result.
public static var functionKey: String { return "\(errorDomain).function" }
/// The userInfo key for source file paths in errors constructed by Result.
public static var fileKey: String { return "\(errorDomain).file" }
/// The userInfo key for source file line numbers in errors constructed by Result.
public static var lineKey: String { return "\(errorDomain).line" }
/// Constructs an error.
public static func error(message: String? = nil, function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__) -> NSError {
var userInfo: [String: AnyObject] = [
functionKey: function,
fileKey: file,
lineKey: line,
]
if let message = message {
userInfo[NSLocalizedDescriptionKey] = message
}
return NSError(domain: errorDomain, code: 0, userInfo: userInfo)
}
// MARK: CustomStringConvertible
public var description: String {
return analysis(
ifSuccess: { ".Success(\($0))" },
ifFailure: { ".Failure(\($0))" })
}
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return description
}
public enum Result<T, Error>: Printable, DebugPrintable {
case Success(Box<T>)
case Failure(Box<Error>)
// MARK: Constructors
/// Constructs a success wrapping a `value`.
public init(value: T) {
self = .Success(Box(value))
}
/// Constructs a failure wrapping an `error`.
public init(error: Error) {
self = .Failure(Box(error))
}
/// Constructs a result from an Optional, failing with `Error` if `nil`
public init(_ value: T?, @autoclosure failWith: () -> Error) {
self = value.map { .success($0) } ?? .failure(failWith())
}
/// Constructs a success wrapping a `value`.
public static func success(value: T) -> Result {
return Result(value: value)
}
/// Constructs a failure wrapping an `error`.
public static func failure(error: Error) -> Result {
return Result(error: error)
}
// MARK: Deconstruction
/// Returns the value from `Success` Results, `nil` otherwise.
public var value: T? {
return analysis(ifSuccess: { $0 }, ifFailure: { _ in nil })
}
/// Returns the error from `Failure` Results, `nil` otherwise.
public var error: Error? {
return analysis(ifSuccess: { _ in nil }, ifFailure: { $0 })
}
/// Case analysis for Result.
///
/// Returns the value produced by applying `ifFailure` to `Failure` Results, or `ifSuccess` to `Success` Results.
public func analysis<Result>(@noescape #ifSuccess: T -> Result, @noescape ifFailure: Error -> Result) -> Result {
switch self {
case let .Success(value):
return ifSuccess(value.value)
case let .Failure(value):
return ifFailure(value.value)
}
}
// MARK: Higher-order functions
/// Returns a new Result by mapping `Success`es values using `transform`, or re-wrapping `Failure`s errors.
public func map<U>(@noescape transform: T -> U) -> Result<U, Error> {
return flatMap { .success(transform($0)) }
}
/// Returns the result of applying `transform` to `Success`es values, or re-wrapping `Failure`s errors.
public func flatMap<U>(@noescape transform: T -> Result<U, Error>) -> Result<U, Error> {
return analysis(
ifSuccess: transform,
ifFailure: Result<U, Error>.failure)
}
/// Returns `self.value` if this result is a .Success, or the given value otherwise. Equivalent with `??`
public func recover(@autoclosure value: () -> T) -> T {
return self.value ?? value()
}
/// Returns this result if it is a .Success, or the given result otherwise. Equivalent with `??`
public func recoverWith(@autoclosure result: () -> Result<T,Error>) -> Result<T,Error> {
return analysis(
ifSuccess: { _ in self },
ifFailure: { _ in result() })
}
// MARK: Errors
/// The domain for errors constructed by Result.
public static var errorDomain: String { return "com.antitypical.Result" }
/// The userInfo key for source functions in errors constructed by Result.
public static var functionKey: String { return "\(errorDomain).function" }
/// The userInfo key for source file paths in errors constructed by Result.
public static var fileKey: String { return "\(errorDomain).file" }
/// The userInfo key for source file line numbers in errors constructed by Result.
public static var lineKey: String { return "\(errorDomain).line" }
/// Constructs an error.
public static func error(message: String? = nil, function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__) -> NSError {
var userInfo: [String: AnyObject] = [
functionKey: function,
fileKey: file,
lineKey: line,
]
if let message = message {
userInfo[NSLocalizedDescriptionKey] = message
}
return NSError(domain: errorDomain, code: 0, userInfo: userInfo)
}
// MARK: Printable
public var description: String {
return analysis(
ifSuccess: { ".Success(\($0))" },
ifFailure: { ".Failure(\($0))" })
}
// MARK: DebugPrintable
public var debugDescription: String {
return description
}
}
/// Returns `true` if `left` and `right` are both `Success`es and their values are equal, or if `left` and `right` are both `Failure`s and their errors are equal.
public func == <T: Equatable, Error: Equatable> (left: Result<T, Error>, right: Result<T, Error>) -> Bool {
if let left = left.value, right = right.value {
return left == right
} else if let left = left.error, right = right.error {
return left == right
}
return false
if let left = left.value, right = right.value {
return left == right
} else if let left = left.error, right = right.error {
return left == right
}
return false
}
/// Returns `true` if `left` and `right` represent different cases, or if they represent the same case but different values.
public func != <T: Equatable, Error: Equatable> (left: Result<T, Error>, right: Result<T, Error>) -> Bool {
return !(left == right)
return !(left == right)
}
/// Returns the value of `left` if it is a `Success`, or `right` otherwise. Short-circuits.
public func ?? <T, Error> (left: Result<T, Error>, @autoclosure right: () -> T) -> T {
return left.recover(right())
return left.recover(right())
}
/// Returns `left` if it is a `Success`es, or `right` otherwise. Short-circuits.
public func ?? <T, Error> (left: Result<T, Error>, @autoclosure right: () -> Result<T, Error>) -> Result<T, Error> {
return left.recoverWith(right())
return left.recoverWith(right())
}
// MARK: - Derive result from failable closure
// Disable until http://www.openradar.me/21341337 is fixed.
//public func materialize<T>(f: () throws -> T) -> Result<T, ErrorType> {
// do {
// return .Success(try f())
// } catch {
// return .Failure(error)
// }
//}
// MARK: - Cocoa API conveniences
@ -186,9 +166,9 @@ public func ?? <T, Error> (left: Result<T, Error>, @autoclosure right: () -> Res
/// This is convenient for wrapping Cocoa API which returns an object or `nil` + an error, by reference. e.g.:
///
/// Result.try { NSData(contentsOfURL: URL, options: .DataReadingMapped, error: $0) }
public func `try`<T>(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__, `try`: NSErrorPointer -> T?) -> Result<T, NSError> {
var error: NSError?
return `try`(&error).map(Result.Success) ?? .Failure(error ?? Result<T, NSError>.error(function: function, file: file, line: line))
public func try<T>(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__, try: NSErrorPointer -> T?) -> Result<T, NSError> {
var error: NSError?
return try(&error).map(Result.success) ?? Result.failure(error ?? Result<T, NSError>.error(function: function, file: file, line: line))
}
/// Constructs a Result with the result of calling `try` with an error pointer.
@ -196,43 +176,43 @@ public func `try`<T>(function: String = __FUNCTION__, file: String = __FILE__, l
/// This is convenient for wrapping Cocoa API which returns a `Bool` + an error, by reference. e.g.:
///
/// Result.try { NSFileManager.defaultManager().removeItemAtURL(URL, error: $0) }
public func `try`(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__, `try`: NSErrorPointer -> Bool) -> Result<(), NSError> {
var error: NSError?
return `try`(&error) ?
.Success(())
: .Failure(error ?? Result<(), NSError>.error(function: function, file: file, line: line))
public func try(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__, try: NSErrorPointer -> Bool) -> Result<(), NSError> {
var error: NSError?
return try(&error) ?
.success(())
: .failure(error ?? Result<(), NSError>.error(function: function, file: file, line: line))
}
// MARK: - Operators
infix operator >>- {
// Left-associativity so that chaining works like youd expect, and for consistency with Haskell, Runes, swiftz, etc.
associativity left
// Left-associativity so that chaining works like youd expect, and for consistency with Haskell, Runes, swiftz, etc.
associativity left
// Higher precedence than function application, but lower than function composition.
precedence 100
// Higher precedence than function application, but lower than function composition.
precedence 100
}
infix operator &&& {
/// Same associativity as &&.
associativity left
/// Same associativity as &&.
associativity left
/// Same precedence as &&.
precedence 120
/// Same precedence as &&.
precedence 120
}
/// Returns the result of applying `transform` to `Success`es values, or re-wrapping `Failure`s errors.
///
/// This is a synonym for `flatMap`.
public func >>- <T, U, Error> (result: Result<T, Error>, @noescape transform: T -> Result<U, Error>) -> Result<U, Error> {
return result.flatMap(transform)
return result.flatMap(transform)
}
/// Returns a Result with a tuple of `left` and `right` values if both are `Success`es, or re-wrapping the error of the earlier `Failure`.
public func &&& <T, U, Error> (left: Result<T, Error>, @autoclosure right: () -> Result<U, Error>) -> Result<(T, U), Error> {
return left.flatMap { left in right().map { right in (left, right) } }
return left.flatMap { left in right().map { right in (left, right) } }
}
import Foundation
import Foundation

View file

@ -1,31 +0,0 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
/// A type that can represent either failure with an error or success with a result value.
public protocol ResultType {
typealias Value
typealias Error: ErrorType
/// Constructs a successful result wrapping a `value`.
init(value: Value)
/// Constructs a failed result wrapping an `error`.
init(error: Error)
/// Case analysis for ResultType.
///
/// Returns the value produced by appliying `ifFailure` to the error if self represents a failure, or `ifSuccess` to the result value if self represents a success.
func analysis<U>(@noescape ifSuccess ifSuccess: Value -> U, @noescape ifFailure: Error -> U) -> U
}
public extension ResultType {
/// Returns the value if self represents a success, `nil` otherwise.
var value: Value? {
return analysis(ifSuccess: { $0 }, ifFailure: { _ in nil })
}
/// Returns the error if self represents a failure, `nil` otherwise.
var error: Error? {
return analysis(ifSuccess: { _ in nil }, ifFailure: { $0 })
}
}

View file

@ -15,7 +15,6 @@
ED128ECE1B6C2A0B00C4050A /* Option.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128EC71B6C2A0B00C4050A /* Option.swift */; };
ED128ECF1B6C2A0B00C4050A /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128EC81B6C2A0B00C4050A /* Switch.swift */; };
ED128ED31B6C2AA200C4050A /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128ED21B6C2AA200C4050A /* Result.swift */; };
ED128ED51B6C2AB700C4050A /* ResultType.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128ED41B6C2AB700C4050A /* ResultType.swift */; };
ED128EDC1B6C2B4400C4050A /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128ED91B6C2B4400C4050A /* Box.swift */; };
ED128EDD1B6C2B4400C4050A /* BoxType.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128EDA1B6C2B4400C4050A /* BoxType.swift */; };
ED128EDE1B6C2B4400C4050A /* MutableBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED128EDB1B6C2B4400C4050A /* MutableBox.swift */; };
@ -48,7 +47,6 @@
ED128EC81B6C2A0B00C4050A /* Switch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Switch.swift; sourceTree = "<group>"; };
ED128ED11B6C2A8B00C4050A /* Result.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Result.h; sourceTree = "<group>"; };
ED128ED21B6C2AA200C4050A /* Result.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = "<group>"; };
ED128ED41B6C2AB700C4050A /* ResultType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResultType.swift; sourceTree = "<group>"; };
ED128ED81B6C2B4400C4050A /* Box.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box.h; sourceTree = "<group>"; };
ED128ED91B6C2B4400C4050A /* Box.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Box.swift; sourceTree = "<group>"; };
ED128EDA1B6C2B4400C4050A /* BoxType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoxType.swift; sourceTree = "<group>"; };
@ -303,7 +301,6 @@
children = (
ED128ED11B6C2A8B00C4050A /* Result.h */,
ED128ED21B6C2AA200C4050A /* Result.swift */,
ED128ED41B6C2AB700C4050A /* ResultType.swift */,
);
path = Result;
sourceTree = "<group>";
@ -598,7 +595,6 @@
ED128EDE1B6C2B4400C4050A /* MutableBox.swift in Sources */,
ED128ECA1B6C2A0B00C4050A /* ArgumentParser.swift in Sources */,
ED128ECB1B6C2A0B00C4050A /* Command.swift in Sources */,
ED128ED51B6C2AB700C4050A /* ResultType.swift in Sources */,
ED128ECE1B6C2A0B00C4050A /* Option.swift in Sources */,
ED128ECD1B6C2A0B00C4050A /* HelpCommand.swift in Sources */,
ED128ED31B6C2AA200C4050A /* Result.swift in Sources */,
@ -694,6 +690,7 @@
);
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "mas-cli/mas-cli-Bridging-Header.h";
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/mas-cli/Headers/**";
};
name = Debug;
};
@ -706,6 +703,7 @@
);
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "mas-cli/mas-cli-Bridging-Header.h";
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/mas-cli/Headers/**";
};
name = Release;
};

View file

@ -24,7 +24,7 @@
- (BOOL)isTrialVersionOfBundleIdentifier:(id)arg1;
- (id)receiptFromBundleAtPath:(id)arg1;
- (id)productForPath:(id)arg1;
- (NSArray<CKSoftwareProduct *>*)allProducts;
- (NSArray*)allProducts;
- (CKSoftwareProduct *)productForItemIdentifier:(unsigned long long)arg1;
- (CKSoftwareProduct *)productForBundleIdentifier:(NSString *)arg1;
- (void)removeProductsObserver:(id)arg1;

View file

@ -20,7 +20,7 @@ func primaryAccount() -> ISStoreAccount {
if let activePhase = download.status.activePhase {
let percentage = String(Int(floor(download.status.percentComplete * 100))) + "%"
// let phase = String(activePhase.phaseType)
print("\u{001B}[2K\r" + percentage + " " + download.metadata.title, appendNewline: false)
print("\u{001B}[2K\r" + percentage + " " + download.metadata.title)
}
}
@ -79,7 +79,7 @@ struct AccountCommand: CommandType {
default:
break
}
return .Success(())
return .success(())
}
}
@ -102,13 +102,13 @@ struct InstallCommand: CommandType {
struct InstallOptions: OptionsType {
let appId: UInt64
static func create(appId: UInt64) -> InstallOptions {
return InstallOptions(appId: appId)
static func create(appId: Int) -> InstallOptions {
return InstallOptions(appId: UInt64(appId))
}
static func evaluate(m: CommandMode) -> Result<InstallOptions, CommandantError<MASError>> {
return create
<*> m <| Option(usage: "the app ID to install")
<*> m <| Option(key: nil, defaultValue: nil, usage: "the app ID to install")
}
}
@ -124,7 +124,7 @@ struct ListUpdatesCommand: CommandType {
default:
break
}
return .Success(())
return .success(())
}
}
@ -145,11 +145,11 @@ struct ListInstalledCommand: CommandType {
default:
break
}
return .Success(())
return .success(())
}
}
public enum MASError: ErrorType, Equatable {
public enum MASError: Equatable {
public var description: String {
return ""
}