⬆️ Nimble (7.3.2), Quick (1.3.2), Result (4.1.0)

This commit is contained in:
Ben Chatelain 2019-01-24 21:25:12 -07:00
parent eebf4d4945
commit d0004d6026
27 changed files with 236 additions and 85 deletions

View file

@ -1,4 +1,4 @@
github "Carthage/Commandant" "0.15.0"
github "Quick/Nimble" "v7.3.0"
github "Quick/Quick" "v1.3.1"
github "antitypical/Result" "4.0.0"
github "Quick/Nimble" "v7.3.2"
github "Quick/Quick" "v1.3.2"
github "antitypical/Result" "4.1.0"

View file

@ -28,11 +28,11 @@ struct LogOptions: OptionsProtocol {
return { verbose in { logName in LogOptions(lines: lines, verbose: verbose, logName: logName) } }
}
static func evaluate(_ mode: CommandMode) -> Result<LogOptions, CommandantError<YourErrorType>> {
static func evaluate(_ m: CommandMode) -> Result<LogOptions, CommandantError<YourErrorType>> {
return create
<*> mode <| Option(key: "lines", defaultValue: 0, usage: "the number of lines to read from the logs")
<*> mode <| Option(key: "verbose", defaultValue: false, usage: "show verbose output")
<*> mode <| Argument(usage: "the log to read")
<*> m <| Option(key: "lines", defaultValue: 0, usage: "the number of lines to read from the logs")
<*> m <| Option(key: "verbose", defaultValue: false, usage: "show verbose output")
<*> m <| Argument(usage: "the log to read")
}
}
```

View file

@ -69,8 +69,8 @@ public struct HelpOptions<ClientError: Error>: OptionsProtocol {
return self.init(verb: (verb == "" ? nil : verb))
}
public static func evaluate(_ mode: CommandMode) -> Result<HelpOptions, CommandantError<ClientError>> {
public static func evaluate(_ m: CommandMode) -> Result<HelpOptions, CommandantError<ClientError>> {
return create
<*> mode <| Argument(defaultValue: "", usage: "the command to display help for")
<*> m <| Argument(defaultValue: "", usage: "the command to display help for")
}
}

View file

@ -27,12 +27,12 @@ import Result
/// return { outputFilename in { shouldDelete in { logName in LogOptions(verbosity: verbosity, outputFilename: outputFilename, shouldDelete: shouldDelete, logName: logName) } } }
/// }
///
/// static func evaluate(_ mode: CommandMode) -> Result<LogOptions, CommandantError<YourErrorType>> {
/// static func evaluate(_ m: CommandMode) -> Result<LogOptions, CommandantError<YourErrorType>> {
/// return create
/// <*> mode <| Option(key: "verbose", defaultValue: 0, usage: "the verbosity level with which to read the logs")
/// <*> mode <| Option(key: "outputFilename", defaultValue: "", usage: "a file to print output to, instead of stdout")
/// <*> mode <| Switch(flag: "d", key: "delete", usage: "delete the logs when finished")
/// <*> mode <| Argument(usage: "the log to read")
/// <*> m <| Option(key: "verbose", defaultValue: 0, usage: "the verbosity level with which to read the logs")
/// <*> m <| Option(key: "outputFilename", defaultValue: "", usage: "a file to print output to, instead of stdout")
/// <*> m <| Switch(flag: "d", key: "delete", usage: "delete the logs when finished")
/// <*> m <| Argument(usage: "the log to read")
/// }
/// }
public protocol OptionsProtocol {
@ -41,14 +41,14 @@ public protocol OptionsProtocol {
/// Evaluates this set of options in the given mode.
///
/// Returns the parsed options or a `UsageError`.
static func evaluate(_ mode: CommandMode) -> Result<Self, CommandantError<ClientError>>
static func evaluate(_ m: CommandMode) -> Result<Self, CommandantError<ClientError>>
}
/// An `OptionsProtocol` that has no options.
public struct NoOptions<ClientError: Error>: OptionsProtocol {
public init() {}
public static func evaluate(_ mode: CommandMode) -> Result<NoOptions, CommandantError<ClientError>> {
public static func evaluate(_ m: CommandMode) -> Result<NoOptions, CommandantError<ClientError>> {
return .success(NoOptions())
}
}

View file

@ -157,19 +157,19 @@ struct TestOptions: OptionsProtocol, Equatable {
} } } } } } } } } }
}
static func evaluate(_ mode: CommandMode) -> Result<TestOptions, CommandantError<NoError>> {
static func evaluate(_ m: CommandMode) -> Result<TestOptions, CommandantError<NoError>> {
return create
<*> mode <| Option(key: "intValue", defaultValue: 42, usage: "Some integer value")
<*> mode <| Option(key: "stringValue", defaultValue: "foobar", usage: "Some string value")
<*> mode <| Option<[String]>(key: "stringsArray", defaultValue: [], usage: "Some array of arguments")
<*> mode <| Option<[String]?>(key: "optionalStringsArray", defaultValue: nil, usage: "Some array of arguments")
<*> mode <| Option<String?>(key: "optionalStringValue", defaultValue: nil, usage: "Some string value")
<*> mode <| Argument(usage: "A name you're required to specify")
<*> mode <| Argument(defaultValue: "filename", usage: "A filename that you can optionally specify")
<*> mode <| Option(key: "enabled", defaultValue: false, usage: "Whether to be enabled")
<*> mode <| Switch(flag: "f", key: "force", usage: "Whether to force")
<*> mode <| Switch(flag: "g", key: "glob", usage: "Whether to glob")
<*> mode <| Argument(defaultValue: [], usage: "An argument list that consumes the rest of positional arguments")
<*> m <| Option(key: "intValue", defaultValue: 42, usage: "Some integer value")
<*> m <| Option(key: "stringValue", defaultValue: "foobar", usage: "Some string value")
<*> m <| Option<[String]>(key: "stringsArray", defaultValue: [], usage: "Some array of arguments")
<*> m <| Option<[String]?>(key: "optionalStringsArray", defaultValue: nil, usage: "Some array of arguments")
<*> m <| Option<String?>(key: "optionalStringValue", defaultValue: nil, usage: "Some string value")
<*> m <| Argument(usage: "A name you're required to specify")
<*> m <| Argument(defaultValue: "filename", usage: "A filename that you can optionally specify")
<*> m <| Option(key: "enabled", defaultValue: false, usage: "Whether to be enabled")
<*> m <| Switch(flag: "f", key: "force", usage: "Whether to force")
<*> m <| Switch(flag: "g", key: "glob", usage: "Whether to glob")
<*> m <| Argument(defaultValue: [], usage: "An argument list that consumes the rest of positional arguments")
}
}

View file

@ -132,16 +132,16 @@ struct TestEnumOptions: OptionsProtocol, Equatable {
} } } } } } }
}
static func evaluate(_ mode: CommandMode) -> Result<TestEnumOptions, CommandantError<NoError>> {
static func evaluate(_ m: CommandMode) -> Result<TestEnumOptions, CommandantError<NoError>> {
return create
<*> mode <| Option(key: "strictIntValue", defaultValue: .theAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything, usage: "`0` - zero, `255` - max, `3` - three, `5` - five or `42` - The Answer")
<*> mode <| Option(key: "strictStringValue", defaultValue: .foobar, usage: "`foobar`, `bazbuzzz`, `a`, `b`, `c`, `one`, `two`, `c`")
<*> mode <| Option<[StrictStringValue]>(key: "strictStringsArray", defaultValue: [], usage: "Some array of arguments")
<*> mode <| Option<[StrictStringValue]?>(key: "optionalStrictStringsArray", defaultValue: nil, usage: "Some array of arguments")
<*> mode <| Option<StrictStringValue?>(key: "optionalStrictStringValue", defaultValue: nil, usage: "Some string value")
<*> mode <| Argument(usage: "A name you're required to specify")
<*> mode <| Argument(defaultValue: .min, usage: "A number that you can optionally specify")
<*> mode <| Argument(defaultValue: [], usage: "An argument list that consumes the rest of positional arguments")
<*> m <| Option(key: "strictIntValue", defaultValue: .theAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything, usage: "`0` - zero, `255` - max, `3` - three, `5` - five or `42` - The Answer")
<*> m <| Option(key: "strictStringValue", defaultValue: .foobar, usage: "`foobar`, `bazbuzzz`, `a`, `b`, `c`, `one`, `two`, `c`")
<*> m <| Option<[StrictStringValue]>(key: "strictStringsArray", defaultValue: [], usage: "Some array of arguments")
<*> m <| Option<[StrictStringValue]?>(key: "optionalStrictStringsArray", defaultValue: nil, usage: "Some array of arguments")
<*> m <| Option<StrictStringValue?>(key: "optionalStrictStringValue", defaultValue: nil, usage: "Some string value")
<*> m <| Argument(usage: "A name you're required to specify")
<*> m <| Argument(defaultValue: .min, usage: "A number that you can optionally specify")
<*> m <| Argument(defaultValue: [], usage: "An argument list that consumes the rest of positional arguments")
}
}

View file

@ -26,11 +26,17 @@ matrix:
- os: osx
env: TYPE=macos
osx_image: xcode9.4
- os: osx
env: TYPE=macos
osx_image: xcode10.1
- os: osx
env: TYPE=swiftpm
- os: osx
env: TYPE=swiftpm
osx_image: xcode9
- os: osx
env: TYPE=swiftpm
osx_image: xcode10.1
- os: linux
dist: trusty
sudo: required
@ -42,9 +48,33 @@ matrix:
sudo: required
env:
- TYPE=swiftpm
- SWIFT_VERSION=4.0.2
- SWIFT_VERSION=4.0.3
install:
- eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/9f442512a46d7a2af7b850d65a7e9bd31edfb09b/swiftenv-install.sh)"
- os: linux
dist: trusty
sudo: required
env:
- TYPE=swiftpm
- SWIFT_VERSION=4.1.3
install:
- eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/9f442512a46d7a2af7b850d65a7e9bd31edfb09b/swiftenv-install.sh)"
- os: linux
dist: trusty
sudo: required
env:
- TYPE=swiftpm
- SWIFT_VERSION=4.2.1
install:
- eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/9f442512a46d7a2af7b850d65a7e9bd31edfb09b/swiftenv-install.sh)"
# - os: linux
# dist: trusty
# sudo: required
# env:
# - TYPE=swiftpm
# - SWIFT_VERSION=5.0-DEVELOPMENT-SNAPSHOT-2019-01-13-a
# install:
# - eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/9f442512a46d7a2af7b850d65a7e9bd31edfb09b/swiftenv-install.sh)"
install:
- if [[ "$TYPE" == "podspec" ]]; then sudo gem install bundler; bundle install; fi
script:

View file

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Nimble"
s.version = "7.3.0"
s.version = "7.3.2"
s.summary = "A Matcher Framework for Swift and Objective-C"
s.description = <<-DESC
Use Nimble to express the expected outcomes of Swift or Objective-C expressions. Inspired by Cedar.

View file

@ -1081,9 +1081,9 @@
isa = PBXNativeTarget;
buildConfigurationList = 1F1A743F1940169200FFFC47 /* Build configuration list for PBXNativeTarget "Nimble-iOS" */;
buildPhases = (
1F1A74261940169200FFFC47 /* Headers */,
1F1A74241940169200FFFC47 /* Sources */,
1F1A74251940169200FFFC47 /* Frameworks */,
1F1A74261940169200FFFC47 /* Headers */,
1F1A74271940169200FFFC47 /* Resources */,
);
buildRules = (
@ -1120,9 +1120,9 @@
isa = PBXNativeTarget;
buildConfigurationList = 1F5DF16A1BDCA0CE00C3A531 /* Build configuration list for PBXNativeTarget "Nimble-tvOS" */;
buildPhases = (
1F5DF1521BDCA0CE00C3A531 /* Headers */,
1F5DF1501BDCA0CE00C3A531 /* Sources */,
1F5DF1511BDCA0CE00C3A531 /* Frameworks */,
1F5DF1521BDCA0CE00C3A531 /* Headers */,
1F5DF1531BDCA0CE00C3A531 /* Resources */,
);
buildRules = (
@ -1156,9 +1156,9 @@
isa = PBXNativeTarget;
buildConfigurationList = 1F925EC0195C0D6300ED456B /* Build configuration list for PBXNativeTarget "Nimble-macOS" */;
buildPhases = (
1F925EAA195C0D6300ED456B /* Headers */,
1F925EA8195C0D6300ED456B /* Sources */,
1F925EA9195C0D6300ED456B /* Frameworks */,
1F925EAA195C0D6300ED456B /* Headers */,
1F925EAB195C0D6300ED456B /* Resources */,
);
buildRules = (

View file

@ -3,7 +3,7 @@ import Foundation
/// "Global" state of Nimble is stored here. Only DSL functions should access / be aware of this
/// class' existence
internal class NimbleEnvironment {
internal class NimbleEnvironment: NSObject {
static var activeInstance: NimbleEnvironment {
get {
let env = Thread.current.threadDictionary["NimbleEnvironment"]
@ -29,7 +29,7 @@ internal class NimbleEnvironment {
var suppressTVOSAssertionWarning: Bool = false
var awaiter: Awaiter
init() {
override init() {
let timeoutQueue: DispatchQueue
if #available(OSX 10.10, *) {
timeoutQueue = DispatchQueue.global(qos: .userInitiated)
@ -40,6 +40,9 @@ internal class NimbleEnvironment {
awaiter = Awaiter(
waitLock: AssertionWaitLock(),
asyncQueue: .main,
timeoutQueue: timeoutQueue)
timeoutQueue: timeoutQueue
)
super.init()
}
}

View file

@ -23,14 +23,18 @@ private func async<T>(style: ExpectationStyle, predicate: Predicate<T>, timeout:
}
switch result {
case .completed: return lastPredicateResult!
case .timedOut: return PredicateResult(status: .fail, message: lastPredicateResult!.message)
case .timedOut:
let message = lastPredicateResult?.message ?? .fail("timed out before returning a value")
return PredicateResult(status: .fail, message: message)
case let .errorThrown(error):
return PredicateResult(status: .fail, message: .fail("unexpected error thrown: <\(error)>"))
case let .raisedException(exception):
return PredicateResult(status: .fail, message: .fail("unexpected exception raised: \(exception)"))
case .blockedRunLoop:
// swiftlint:disable:next line_length
return PredicateResult(status: .fail, message: lastPredicateResult!.message.appended(message: " (timed out, but main thread was unresponsive)."))
let message = lastPredicateResult?.message.appended(message: " (timed out, but main run loop was unresponsive).") ??
.fail("main run loop was unresponsive")
return PredicateResult(status: .fail, message: message)
case .incomplete:
internalError("Reached .incomplete state for \(fnName)(...).")
}

View file

@ -5,17 +5,41 @@ import Foundation
public func beIdenticalTo(_ expected: Any?) -> Predicate<Any> {
return Predicate.define { actualExpression in
#if os(Linux)
#if swift(>=4.0)
#if !swift(>=4.1.50)
let actual = try actualExpression.evaluate() as? AnyObject
#else
let actual = try actualExpression.evaluate() as AnyObject?
#endif
#else
#if !swift(>=3.4)
let actual = try actualExpression.evaluate() as? AnyObject
#else
let actual = try actualExpression.evaluate() as AnyObject?
#endif
#endif
#else
let actual = try actualExpression.evaluate() as AnyObject?
#endif
let bool: Bool
#if os(Linux)
#if swift(>=4.0)
#if !swift(>=4.1.50)
bool = actual === (expected as? AnyObject) && actual !== nil
#else
bool = actual === (expected as AnyObject?) && actual !== nil
#endif
#else
#if !swift(>=3.4)
bool = actual === (expected as? AnyObject) && actual !== nil
#else
bool = actual === (expected as AnyObject?) && actual !== nil
#endif
#endif
#else
bool = actual === (expected as AnyObject?) && actual !== nil
#endif
return PredicateResult(
bool: bool,
message: .expectedCustomValueTo(

View file

@ -263,7 +263,7 @@ internal class AwaitPromiseBuilder<T> {
self.trigger.timeoutSource.resume()
while self.promise.asyncResult.isIncomplete() {
// Stopping the run loop does not work unless we run only 1 mode
#if swift(>=4.2)
#if swift(>=4.2) && (os(macOS) || os(iOS) || os(tvOS))
_ = RunLoop.current.run(mode: .default, before: .distantFuture)
#else
_ = RunLoop.current.run(mode: .defaultRunLoopMode, before: .distantFuture)

View file

@ -3,10 +3,22 @@ import Foundation
internal func identityAsString(_ value: Any?) -> String {
let anyObject: AnyObject?
#if os(Linux)
#if swift(>=4.0)
#if !swift(>=4.1.50)
anyObject = value as? AnyObject
#else
anyObject = value as AnyObject?
#endif
#else
#if !swift(>=3.4)
anyObject = value as? AnyObject
#else
anyObject = value as AnyObject?
#endif
#endif
#else
anyObject = value as AnyObject?
#endif
if let value = anyObject {
return NSString(format: "<%p>", unsafeBitCast(value, to: Int.self)).description
} else {

View file

@ -80,7 +80,7 @@ function test_podspec {
function test_swiftpm {
if [ -d .build ]; then
run swift build --clean
run swift build --clean || swift package clean
fi
run swift build && swift test
}

View file

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Quick"
s.version = "1.3.1"
s.version = "1.3.2"
s.summary = "The Swift (and Objective-C) testing framework."
s.description = <<-DESC

View file

@ -994,9 +994,9 @@
isa = PBXNativeTarget;
buildConfigurationList = 1F118CE61BDCA4AB005013A2 /* Build configuration list for PBXNativeTarget "Quick-tvOS" */;
buildPhases = (
1F118CD21BDCA4AB005013A2 /* Headers */,
1F118CD01BDCA4AB005013A2 /* Sources */,
1F118CD11BDCA4AB005013A2 /* Frameworks */,
1F118CD21BDCA4AB005013A2 /* Headers */,
1F118CD31BDCA4AB005013A2 /* Resources */,
);
buildRules = (
@ -1048,9 +1048,9 @@
isa = PBXNativeTarget;
buildConfigurationList = 5A5D119319473F2100F6D13D /* Build configuration list for PBXNativeTarget "Quick-iOS" */;
buildPhases = (
5A5D117919473F2100F6D13D /* Headers */,
5A5D117719473F2100F6D13D /* Sources */,
5A5D117819473F2100F6D13D /* Frameworks */,
5A5D117919473F2100F6D13D /* Headers */,
5A5D117A19473F2100F6D13D /* Resources */,
);
buildRules = (
@ -1184,9 +1184,9 @@
isa = PBXNativeTarget;
buildConfigurationList = DAEB6BA41943873200289F44 /* Build configuration list for PBXNativeTarget "Quick-macOS" */;
buildPhases = (
DAEB6B8B1943873100289F44 /* Headers */,
DAEB6B891943873100289F44 /* Sources */,
DAEB6B8A1943873100289F44 /* Frameworks */,
DAEB6B8B1943873100289F44 /* Headers */,
DAEB6B8C1943873100289F44 /* Resources */,
);
buildRules = (

View file

@ -1 +1 @@
4.1
4.2

View file

@ -30,6 +30,18 @@ matrix:
os: osx
osx_image: xcode9.3
language: objective-c
- script:
- set -o pipefail
- xcodebuild $XCODE_ACTION -scheme Result-Mac | xcpretty
- xcodebuild $XCODE_ACTION -scheme Result-iOS -sdk iphonesimulator -destination "name=iPhone SE" | xcpretty
- xcodebuild $XCODE_ACTION -scheme Result-tvOS -sdk appletvsimulator -destination "name=Apple TV" | xcpretty
- xcodebuild build -scheme Result-watchOS -sdk watchsimulator | xcpretty
env:
- JOB=Xcode
- XCODE_ACTION="build-for-testing test-without-building"
os: osx
osx_image: xcode10
language: objective-c
- script:
- swift --version
- swift build
@ -46,6 +58,14 @@ matrix:
os: osx
osx_image: xcode9.3
language: objective-c
- script:
- swift --version
- swift build
- swift test
env: JOB=SPM
os: osx
osx_image: xcode10
language: objective-c
- script:
- swift --version
- swift build
@ -57,6 +77,18 @@ matrix:
language: generic
install:
- eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/9f442512a46d7a2af7b850d65a7e9bd31edfb09b/swiftenv-install.sh)"
- script:
- swift --version
- swift build
- swift test
env:
- JOB=Linux
- SWIFT_VERSION=5.0-DEVELOPMENT-SNAPSHOT-2018-12-28-a
sudo: required
dist: trusty
language: generic
install:
- eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/9f442512a46d7a2af7b850d65a7e9bd31edfb09b/swiftenv-install.sh)"
notifications:
email: false

View file

@ -0,0 +1,14 @@
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "Result",
products: [
.library(name: "Result", targets: ["Result"]),
],
targets: [
.target(name: "Result", dependencies: [], path: "Result"),
.testTarget(name: "ResultTests", dependencies: ["Result"]),
],
swiftLanguageVersions: [.v4, .v4_2, .v5]
)

View file

@ -28,12 +28,11 @@ func stringForKey(json: JSONObject, key: String) -> Result<String, JSONError> {
return .failure(.noSuchKey(key))
}
if let value = value as? String {
return .success(value)
}
else {
guard let value = value as? String else {
return .failure(.typeMismatch)
}
return .success(value)
}
```
@ -94,7 +93,7 @@ An in depth discussion of `map` and `flatMap` is beyond the scope of this docume
### Cocoapods
```ruby
pod 'Result', '~> 3.0.0'
pod 'Result', '~> 4.0.0'
```
### Swift Package Manager
@ -107,7 +106,7 @@ let package = Package(
targets: [],
dependencies: [
.Package(url: "https://github.com/antitypical/Result.git",
majorVersion: 3)
majorVersion: 4)
]
)
```

View file

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Result'
s.version = '4.0.0'
s.version = '4.1.0'
s.summary = 'Swift type modelling the success/failure of arbitrary operations'
s.homepage = 'https://github.com/antitypical/Result'
@ -14,6 +14,6 @@ Pod::Spec.new do |s|
s.watchos.deployment_target = '2.0'
s.tvos.deployment_target = '9.0'
s.swift_version = '4.0'
s.cocoapods_version = '>= 1.4.0'
s.swift_version = '4.2'
end

View file

@ -250,9 +250,9 @@
isa = PBXNativeTarget;
buildConfigurationList = 57FCDE441BA280DC00130C48 /* Build configuration list for PBXNativeTarget "Result-tvOS" */;
buildPhases = (
57FCDE411BA280DC00130C48 /* Headers */,
57FCDE3D1BA280DC00130C48 /* Sources */,
57FCDE401BA280DC00130C48 /* Frameworks */,
57FCDE411BA280DC00130C48 /* Headers */,
57FCDE431BA280DC00130C48 /* Resources */,
);
buildRules = (
@ -286,9 +286,9 @@
isa = PBXNativeTarget;
buildConfigurationList = D03579A01B2B788F005D26AE /* Build configuration list for PBXNativeTarget "Result-watchOS" */;
buildPhases = (
D035799D1B2B788F005D26AE /* Headers */,
D035799A1B2B788F005D26AE /* Sources */,
D035799C1B2B788F005D26AE /* Frameworks */,
D035799D1B2B788F005D26AE /* Headers */,
D035799F1B2B788F005D26AE /* Resources */,
);
buildRules = (
@ -304,9 +304,9 @@
isa = PBXNativeTarget;
buildConfigurationList = D45480721A9572F5009D7229 /* Build configuration list for PBXNativeTarget "Result-Mac" */;
buildPhases = (
D45480541A9572F5009D7229 /* Headers */,
D45480521A9572F5009D7229 /* Sources */,
D45480531A9572F5009D7229 /* Frameworks */,
D45480541A9572F5009D7229 /* Headers */,
D45480551A9572F5009D7229 /* Resources */,
);
buildRules = (
@ -340,9 +340,9 @@
isa = PBXNativeTarget;
buildConfigurationList = D45480941A957362009D7229 /* Build configuration list for PBXNativeTarget "Result-iOS" */;
buildPhases = (
D454807A1A957361009D7229 /* Headers */,
D45480781A957361009D7229 /* Sources */,
D45480791A957361009D7229 /* Frameworks */,
D454807A1A957361009D7229 /* Headers */,
D454807B1A957361009D7229 /* Resources */,
);
buildRules = (
@ -401,11 +401,11 @@
};
D454807C1A957361009D7229 = {
CreatedOnToolsVersion = 6.3;
LastSwiftMigration = 0920;
LastSwiftMigration = 1000;
};
D45480861A957362009D7229 = {
CreatedOnToolsVersion = 6.3;
LastSwiftMigration = 0920;
LastSwiftMigration = 1000;
};
};
};
@ -764,7 +764,7 @@
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
TVOS_DEPLOYMENT_TARGET = 9.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@ -820,7 +820,7 @@
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
TVOS_DEPLOYMENT_TARGET = 9.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";

View file

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.0.0</string>
<string>4.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View file

@ -5,6 +5,19 @@ public enum Result<Value, Error: Swift.Error>: ResultProtocol, CustomStringConve
case success(Value)
case failure(Error)
/// The compatibility alias for the Swift 5's `Result` in the standard library.
///
/// See https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md
/// and https://forums.swift.org/t/accepted-with-modifications-se-0235-add-result-to-the-standard-library/18603
/// for the details.
public typealias Success = Value
/// The compatibility alias for the Swift 5's `Result` in the standard library.
///
/// See https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md
/// and https://forums.swift.org/t/accepted-with-modifications-se-0235-add-result-to-the-standard-library/18603
/// for the details.
public typealias Failure = Error
// MARK: Constructors
/// Constructs a success wrapping a `value`.
@ -24,13 +37,23 @@ public enum Result<Value, Error: Swift.Error>: ResultProtocol, CustomStringConve
/// Constructs a result from a function that uses `throw`, failing with `Error` if throws.
public init(_ f: @autoclosure () throws -> Value) {
self.init(attempt: f)
self.init(catching: f)
}
/// Constructs a result from a function that uses `throw`, failing with `Error` if throws.
@available(*, deprecated, renamed: "init(catching:)")
public init(attempt f: () throws -> Value) {
self.init(catching: f)
}
/// The same as `init(attempt:)` aiming for the compatibility with the Swift 5's `Result` in the standard library.
///
/// See https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md
/// and https://forums.swift.org/t/accepted-with-modifications-se-0235-add-result-to-the-standard-library/18603
/// for the details.
public init(catching body: () throws -> Success) {
do {
self = .success(try f())
self = .success(try body())
} catch var error {
if Error.self == AnyError.self {
error = AnyError(error)
@ -42,7 +65,17 @@ public enum Result<Value, Error: Swift.Error>: ResultProtocol, CustomStringConve
// MARK: Deconstruction
/// Returns the value from `success` Results or `throw`s the error.
@available(*, deprecated, renamed: "get()")
public func dematerialize() throws -> Value {
return try get()
}
/// The same as `dematerialize()` aiming for the compatibility with the Swift 5's `Result` in the standard library.
///
/// See https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md
/// and https://forums.swift.org/t/accepted-with-modifications-se-0235-add-result-to-the-standard-library/18603
/// for the details.
public func get() throws -> Success {
switch self {
case let .success(value):
return value
@ -115,7 +148,7 @@ public enum Result<Value, Error: Swift.Error>: ResultProtocol, CustomStringConve
}
}
extension Result where Error == AnyError {
extension Result where Result.Failure == AnyError {
/// Constructs a result from an expression that uses `throw`, failing with `AnyError` if throws.
public init(_ f: @autoclosure () throws -> Value) {
self.init(attempt: f)
@ -140,7 +173,7 @@ public func materialize<T>(_ f: () throws -> T) -> Result<T, AnyError> {
@available(*, deprecated, renamed: "Result.init(_:)")
public func materialize<T>(_ f: @autoclosure () throws -> T) -> Result<T, AnyError> {
return Result(f)
return Result(try f())
}
// MARK: - ErrorConvertible conformance

View file

@ -11,7 +11,7 @@ public protocol ResultProtocol {
var result: Result<Value, Error> { get }
}
public extension Result {
extension Result {
/// Returns the value if self represents a success, `nil` otherwise.
public var value: Value? {
switch self {
@ -69,7 +69,7 @@ public extension Result {
}
}
public extension Result {
extension Result {
// MARK: Higher-order functions
@ -92,7 +92,7 @@ public protocol ErrorConvertible: Swift.Error {
static func error(from error: Swift.Error) -> Self
}
public extension Result where Error: ErrorConvertible {
extension Result where Result.Failure: ErrorConvertible {
/// Returns the result of applying `transform` to `Success`es values, or wrapping thrown errors.
public func tryMap<U>(_ transform: (Value) throws -> U) -> Result<U, Error> {
@ -111,7 +111,7 @@ public extension Result where Error: ErrorConvertible {
// MARK: - Operators
extension Result where Value: Equatable, Error: Equatable {
extension Result where Result.Success: Equatable, Result.Failure: Equatable {
/// 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 static func ==(left: Result<Value, Error>, right: Result<Value, Error>) -> Bool {
if let left = left.value, let right = right.value {
@ -124,9 +124,9 @@ extension Result where Value: Equatable, Error: Equatable {
}
#if swift(>=4.1)
extension Result: Equatable where Value: Equatable, Error: Equatable { }
extension Result: Equatable where Result.Success: Equatable, Result.Failure: Equatable { }
#else
extension Result where Value: Equatable, Error: Equatable {
extension Result where Result.Success: Equatable, Result.Failure: Equatable {
/// Returns `true` if `left` and `right` represent different cases, or if they represent the same case but different values.
public static func !=(left: Result<Value, Error>, right: Result<Value, Error>) -> Bool {
return !(left == right)

View file

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>4.0.0</string>
<string>4.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>