🔥 Remove obsolete Result sources

This commit is contained in:
Ben Chatelain 2019-12-13 17:47:44 -07:00
parent fe528500a5
commit f28355374e
72 changed files with 0 additions and 5742 deletions

View file

@ -1 +0,0 @@
github "antitypical/Result" ~> 4.0

View file

@ -1,9 +0,0 @@
.DS_Store
xcuserdata
*.xcuserdatad
*.xccheckout
*.mode*
*.pbxuser
Carthage/Build
.build

View file

@ -1,94 +0,0 @@
branches:
only:
- master
matrix:
include:
- 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
- gem update cocoapods && rm .swift-version && pod lib lint
env:
- JOB=Xcode
- XCODE_ACTION="build-for-testing test-without-building"
os: osx
osx_image: xcode9.2
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
- rm .swift-version && pod lib lint
env:
- JOB=Xcode
- XCODE_ACTION="build-for-testing test-without-building"
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
- swift test
env: JOB=SPM
os: osx
osx_image: xcode9.2
language: objective-c
- script:
- swift --version
- swift build
- swift test
env: JOB=SPM
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
- swift test
env:
- JOB=Linux
sudo: required
dist: trusty
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

@ -1,23 +0,0 @@
We love that you're interested in contributing to this project!
To make the process as painless as possible, we have just a couple of guidelines
that should make life easier for everyone involved.
## Prefer Pull Requests
If you know exactly how to implement the feature being suggested or fix the bug
being reported, please open a pull request instead of an issue. Pull requests are easier than
patches or inline code blocks for discussing and merging the changes.
If you can't make the change yourself, please open an issue after making sure
that one isn't already logged.
## Contributing Code
Fork this repository, make it awesomer (preferably in a branch named for the
topic), send a pull request!
All code contributions should match our [coding
conventions](https://github.com/github/swift-style-guide).
Thanks for contributing! :boom::camel:

View file

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 Rob Rix
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,14 +0,0 @@
// swift-tools-version:4.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: [4]
)

View file

@ -1,14 +0,0 @@
// 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

@ -1,112 +0,0 @@
# Result
[![Build Status](https://travis-ci.org/antitypical/Result.svg?branch=master)](https://travis-ci.org/antitypical/Result)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![CocoaPods](https://img.shields.io/cocoapods/v/Result.svg)](https://cocoapods.org/)
[![Reference Status](https://www.versioneye.com/objective-c/result/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/result/references)
This is a Swift µframework providing `Result<Value, Error>`.
`Result<Value, Error>` values are either successful (wrapping `Value`) or failed (wrapping `Error`). This is similar to Swifts native `Optional` type: `success` is like `some`, and `failure` is like `none` except with an associated `Error` value. The addition of an associated `Error` allows errors to be passed along for logging or displaying to the user.
Using this µframework instead of rolling your own `Result` type allows you to easily interface with other frameworks that also use `Result`.
## Use
Use `Result` whenever an operation has the possibility of failure. Consider the following example of a function that tries to extract a `String` for a given key from a JSON `Dictionary`.
```swift
typealias JSONObject = [String: Any]
enum JSONError: Error {
case noSuchKey(String)
case typeMismatch
}
func stringForKey(json: JSONObject, key: String) -> Result<String, JSONError> {
guard let value = json[key] else {
return .failure(.noSuchKey(key))
}
guard let value = value as? String else {
return .failure(.typeMismatch)
}
return .success(value)
}
```
This function provides a more robust wrapper around the default subscripting provided by `Dictionary`. Rather than return `Any?`, it returns a `Result` that either contains the `String` value for the given key, or an `ErrorType` detailing what went wrong.
One simple way to handle a `Result` is to deconstruct it using a `switch` statement.
```swift
switch stringForKey(json, key: "email") {
case let .success(email):
print("The email is \(email)")
case let .failure(.noSuchKey(key)):
print("\(key) is not a valid key")
case .failure(.typeMismatch):
print("Didn't have the right type")
}
```
Using a `switch` statement allows powerful pattern matching, and ensures all possible results are covered. Swift 2.0 offers new ways to deconstruct enums like the `if-case` statement, but be wary as such methods do not ensure errors are handled.
Other methods available for processing `Result` are detailed in the [API documentation](http://cocoadocs.org/docsets/Result/).
## Result vs. Throws
Swift 2.0 introduces error handling via throwing and catching `Error`. `Result` accomplishes the same goal by encapsulating the result instead of hijacking control flow. The `Result` abstraction enables powerful functionality such as `map` and `flatMap`, making `Result` more composable than `throw`.
Since dealing with APIs that throw is common, you can convert such functions into a `Result` by using the `materialize` method. Conversely, a `Result` can be used to throw an error by calling `dematerialize`.
## Higher Order Functions
`map` and `flatMap` operate the same as `Optional.map` and `Optional.flatMap` except they apply to `Result`.
`map` transforms a `Result` into a `Result` of a new type. It does this by taking a function that transforms the `Value` type into a new value. This transformation is only applied in the case of a `success`. In the case of a `failure`, the associated error is re-wrapped in the new `Result`.
```swift
// transforms a Result<Int, JSONError> to a Result<String, JSONError>
let idResult = intForKey(json, key:"id").map { id in String(id) }
```
Here, the final result is either the id as a `String`, or carries over the `failure` from the previous result.
`flatMap` is similar to `map` in that it transforms the `Result` into another `Result`. However, the function passed into `flatMap` must return a `Result`.
An in depth discussion of `map` and `flatMap` is beyond the scope of this documentation. If you would like a deeper understanding, read about functors and monads. This article is a good place to [start](http://www.javiersoto.me/post/106875422394).
## Integration
### Carthage
1. Add this repository as a submodule and/or [add it to your Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile) if youre using [carthage](https://github.com/Carthage/Carthage/) to manage your dependencies.
2. Drag `Result.xcodeproj` into your project or workspace.
3. Link your target against `Result.framework`.
4. Application targets should ensure that the framework gets copied into their application bundle. (Framework targets should instead require the application linking them to include Result.)
### Cocoapods
```ruby
pod 'Result', '~> 4.0.0'
```
### Swift Package Manager
```swift
import PackageDescription
let package = Package(
name: "MyProject",
targets: [],
dependencies: [
.Package(url: "https://github.com/antitypical/Result.git",
majorVersion: 4)
]
)
```

View file

@ -1,19 +0,0 @@
Pod::Spec.new do |s|
s.name = 'Result'
s.version = '4.1.0'
s.summary = 'Swift type modelling the success/failure of arbitrary operations'
s.homepage = 'https://github.com/antitypical/Result'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Rob Rix' => 'rob.rix@github.com' }
s.source = { :git => 'https://github.com/antitypical/Result.git', :tag => s.version }
s.source_files = 'Result/*.swift'
s.requires_arc = true
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.9'
s.watchos.deployment_target = '2.0'
s.tvos.deployment_target = '9.0'
s.cocoapods_version = '>= 1.4.0'
s.swift_version = '4.2'
end

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Result.xcodeproj">
</FileRef>
</Workspace>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View file

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480561A9572F5009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-Mac"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480661A9572F5009D7229"
BuildableName = "Result-MacTests.xctest"
BlueprintName = "Result-MacTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480661A9572F5009D7229"
BuildableName = "Result-MacTests.xctest"
BlueprintName = "Result-MacTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480561A9572F5009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-Mac"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480561A9572F5009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-Mac"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480561A9572F5009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-Mac"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D454807C1A957361009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-iOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480861A957362009D7229"
BuildableName = "Result-iOSTests.xctest"
BlueprintName = "Result-iOSTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480861A957362009D7229"
BuildableName = "Result-iOSTests.xctest"
BlueprintName = "Result-iOSTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D454807C1A957361009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-iOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D454807C1A957361009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-iOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D454807C1A957361009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-iOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE3C1BA280DC00130C48"
BuildableName = "Result.framework"
BlueprintName = "Result-tvOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE491BA280E000130C48"
BuildableName = "Result-tvOSTests.xctest"
BlueprintName = "Result-tvOSTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE3C1BA280DC00130C48"
BuildableName = "Result.framework"
BlueprintName = "Result-tvOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE3C1BA280DC00130C48"
BuildableName = "Result.framework"
BlueprintName = "Result-tvOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE3C1BA280DC00130C48"
BuildableName = "Result.framework"
BlueprintName = "Result-tvOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579991B2B788F005D26AE"
BuildableName = "Result.framework"
BlueprintName = "Result-watchOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579A51B2B78A1005D26AE"
BuildableName = "Result-watchOSTests.xctest"
BlueprintName = "Result-watchOSTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579991B2B788F005D26AE"
BuildableName = "Result.framework"
BlueprintName = "Result-watchOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579991B2B788F005D26AE"
BuildableName = "Result.framework"
BlueprintName = "Result-watchOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579991B2B788F005D26AE"
BuildableName = "Result.framework"
BlueprintName = "Result-watchOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -1,46 +0,0 @@
import Foundation
/// A type-erased error which wraps an arbitrary error instance. This should be
/// useful for generic contexts.
public struct AnyError: Swift.Error {
/// The underlying error.
public let error: Swift.Error
public init(_ error: Swift.Error) {
if let anyError = error as? AnyError {
self = anyError
} else {
self.error = error
}
}
}
extension AnyError: ErrorConvertible {
public static func error(from error: Error) -> AnyError {
return AnyError(error)
}
}
extension AnyError: CustomStringConvertible {
public var description: String {
return String(describing: error)
}
}
extension AnyError: LocalizedError {
public var errorDescription: String? {
return error.localizedDescription
}
public var failureReason: String? {
return (error as? LocalizedError)?.failureReason
}
public var helpAnchor: String? {
return (error as? LocalizedError)?.helpAnchor
}
public var recoverySuggestion: String? {
return (error as? LocalizedError)?.recoverySuggestion
}
}

View file

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015 Rob Rix. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View file

@ -1,10 +0,0 @@
/// An error that is impossible to construct.
///
/// This can be used to describe `Result`s where failures will never
/// be generated. For example, `Result<Int, NoError>` describes a result that
/// contains an `Int`eger and is guaranteed never to be a `failure`.
public enum NoError: Swift.Error, Equatable {
public static func ==(lhs: NoError, rhs: NoError) -> Bool {
return true
}
}

View file

@ -1,8 +0,0 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
/// Project version number for Result.
extern double ResultVersionNumber;
/// Project version string for Result.
extern const unsigned char ResultVersionString[];

View file

@ -1,229 +0,0 @@
// 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<Value, Error: Swift.Error>: ResultProtocol, CustomStringConvertible, CustomDebugStringConvertible {
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`.
public init(value: Value) {
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: Value?, failWith: @autoclosure () -> Error) {
self = value.map(Result.success) ?? .failure(failWith())
}
/// Constructs a result from a function that uses `throw`, failing with `Error` if throws.
public init(_ f: @autoclosure () throws -> Value) {
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 body())
} catch var error {
if Error.self == AnyError.self {
error = AnyError(error)
}
self = .failure(error as! Error)
}
}
// 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
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>(ifSuccess: (Value) -> Result, ifFailure: (Error) -> Result) -> Result {
switch self {
case let .success(value):
return ifSuccess(value)
case let .failure(value):
return ifFailure(value)
}
}
// 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: Any] = [
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 {
switch self {
case let .success(value): return ".success(\(value))"
case let .failure(error): return ".failure(\(error))"
}
}
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return description
}
// MARK: ResultProtocol
public var result: Result<Value, Error> {
return self
}
}
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)
}
/// Constructs a result from a closure that uses `throw`, failing with `AnyError` if throws.
public init(attempt f: () throws -> Value) {
do {
self = .success(try f())
} catch {
self = .failure(AnyError(error))
}
}
}
// MARK: - Derive result from failable closure
@available(*, deprecated, renamed: "Result.init(attempt:)")
public func materialize<T>(_ f: () throws -> T) -> Result<T, AnyError> {
return Result(attempt: f)
}
@available(*, deprecated, renamed: "Result.init(_:)")
public func materialize<T>(_ f: @autoclosure () throws -> T) -> Result<T, AnyError> {
return Result(try f())
}
// MARK: - ErrorConvertible conformance
extension NSError: ErrorConvertible {
public static func error(from error: Swift.Error) -> Self {
func cast<T: NSError>(_ error: Swift.Error) -> T {
return error as! T
}
return cast(error)
}
}
// MARK: - migration support
@available(*, unavailable, message: "Use the overload which returns `Result<T, AnyError>` instead")
public func materialize<T>(_ f: () throws -> T) -> Result<T, NSError> {
fatalError()
}
@available(*, unavailable, message: "Use the overload which returns `Result<T, AnyError>` instead")
public func materialize<T>(_ f: @autoclosure () throws -> T) -> Result<T, NSError> {
fatalError()
}
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
/// Constructs a `Result` with the result of calling `try` with an error pointer.
///
/// 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) }
@available(*, unavailable, message: "This has been removed. Use `Result.init(attempt:)` instead. See https://github.com/antitypical/Result/issues/85 for the details.")
public func `try`<T>(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> T?) -> Result<T, NSError> {
fatalError()
}
/// Constructs a `Result` with the result of calling `try` with an error pointer.
///
/// 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) }
@available(*, unavailable, message: "This has been removed. Use `Result.init(attempt:)` instead. See https://github.com/antitypical/Result/issues/85 for the details.")
public func `try`(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> Bool) -> Result<(), NSError> {
fatalError()
}
#endif
// MARK: -
import Foundation

View file

@ -1,152 +0,0 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
/// A protocol that can be used to constrain associated types as `Result`.
public protocol ResultProtocol {
associatedtype Value
associatedtype Error: Swift.Error
init(value: Value)
init(error: Error)
var result: Result<Value, Error> { get }
}
extension Result {
/// Returns the value if self represents a success, `nil` otherwise.
public var value: Value? {
switch self {
case let .success(value): return value
case .failure: return nil
}
}
/// Returns the error if self represents a failure, `nil` otherwise.
public var error: Error? {
switch self {
case .success: return nil
case let .failure(error): return error
}
}
/// Returns a new Result by mapping `Success`es values using `transform`, or re-wrapping `Failure`s errors.
public func map<U>(_ transform: (Value) -> 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>(_ transform: (Value) -> Result<U, Error>) -> Result<U, Error> {
switch self {
case let .success(value): return transform(value)
case let .failure(error): return .failure(error)
}
}
/// Returns a Result with a tuple of the receiver and `other` values if both
/// are `Success`es, or re-wrapping the error of the earlier `Failure`.
public func fanout<U>(_ other: @autoclosure () -> Result<U, Error>) -> Result<(Value, U), Error> {
return self.flatMap { left in other().map { right in (left, right) } }
}
/// Returns a new Result by mapping `Failure`'s values using `transform`, or re-wrapping `Success`es values.
public func mapError<Error2>(_ transform: (Error) -> Error2) -> Result<Value, Error2> {
return flatMapError { .failure(transform($0)) }
}
/// Returns the result of applying `transform` to `Failure`s errors, or re-wrapping `Success`es values.
public func flatMapError<Error2>(_ transform: (Error) -> Result<Value, Error2>) -> Result<Value, Error2> {
switch self {
case let .success(value): return .success(value)
case let .failure(error): return transform(error)
}
}
/// Returns a new Result by mapping `Success`es values using `success`, and by mapping `Failure`'s values using `failure`.
public func bimap<U, Error2>(success: (Value) -> U, failure: (Error) -> Error2) -> Result<U, Error2> {
switch self {
case let .success(value): return .success(success(value))
case let .failure(error): return .failure(failure(error))
}
}
}
extension Result {
// MARK: Higher-order functions
/// Returns `self.value` if this result is a .Success, or the given value otherwise. Equivalent with `??`
public func recover(_ value: @autoclosure () -> Value) -> Value {
return self.value ?? value()
}
/// Returns this result if it is a .Success, or the given result otherwise. Equivalent with `??`
public func recover(with result: @autoclosure () -> Result<Value, Error>) -> Result<Value, Error> {
switch self {
case .success: return self
case .failure: return result()
}
}
}
/// Protocol used to constrain `tryMap` to `Result`s with compatible `Error`s.
public protocol ErrorConvertible: Swift.Error {
static func error(from error: Swift.Error) -> Self
}
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> {
return flatMap { value in
do {
return .success(try transform(value))
}
catch {
let convertedError = Error.error(from: error)
// Revisit this in a future version of Swift. https://twitter.com/jckarter/status/672931114944696321
return .failure(convertedError)
}
}
}
}
// MARK: - Operators
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 {
return left == right
} else if let left = left.error, let right = right.error {
return left == right
}
return false
}
}
#if swift(>=4.1)
extension Result: Equatable where Result.Success: Equatable, Result.Failure: Equatable { }
#else
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)
}
}
#endif
extension Result {
/// Returns the value of `left` if it is a `Success`, or `right` otherwise. Short-circuits.
public static func ??(left: Result<Value, Error>, right: @autoclosure () -> Value) -> Value {
return left.recover(right())
}
/// Returns `left` if it is a `Success`es, or `right` otherwise. Short-circuits.
public static func ??(left: Result<Value, Error>, right: @autoclosure () -> Result<Value, Error>) -> Result<Value, Error> {
return left.recover(with: right())
}
}
// MARK: - migration support
@available(*, unavailable, renamed: "ErrorConvertible")
public protocol ErrorProtocolConvertible: ErrorConvertible {}

View file

@ -1,8 +0,0 @@
import XCTest
import ResultTests
var tests = [XCTestCaseEntry]()
tests += ResultTests.__allTests()
XCTMain(tests)

View file

@ -1,12 +0,0 @@
import Foundation
import XCTest
import Result
final class AnyErrorTests: XCTestCase {
func testAnyError() {
let error = Error.a
let anyErrorFromError = AnyError(error)
let anyErrorFromAnyError = AnyError(anyErrorFromError)
XCTAssertTrue(anyErrorFromError == anyErrorFromAnyError)
}
}

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>4.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View file

@ -1,11 +0,0 @@
import Foundation
import XCTest
import Result
final class NoErrorTests: XCTestCase {
func testEquatable() {
let foo = Result<Int, NoError>(1)
let bar = Result<Int, NoError>(1)
XCTAssertTrue(foo == bar)
}
}

View file

@ -1,256 +0,0 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
final class ResultTests: XCTestCase {
func testMapTransformsSuccesses() {
XCTAssertEqual(success.map { $0.count } ?? 0, 7)
}
func testMapRewrapsFailures() {
XCTAssertEqual(failure.map { $0.count } ?? 0, 0)
}
func testInitOptionalSuccess() {
XCTAssert(Result("success" as String?, failWith: error) == success)
}
func testInitOptionalFailure() {
XCTAssert(Result(nil, failWith: error) == failure)
}
func testFanout() {
let resultSuccess = success.fanout(success)
if let (x, y) = resultSuccess.value {
XCTAssertTrue(x == "success" && y == "success")
} else {
XCTFail()
}
let resultFailureBoth = failure.fanout(failure2)
XCTAssert(resultFailureBoth.error == error)
let resultFailureLeft = failure.fanout(success)
XCTAssert(resultFailureLeft.error == error)
let resultFailureRight = success.fanout(failure2)
XCTAssert(resultFailureRight.error == error2)
}
func testBimapTransformsSuccesses() {
XCTAssertEqual(success.bimap(
success: { $0.count },
failure: { $0 }
) ?? 0, 7)
}
func testBimapTransformsFailures() {
XCTAssert(failure.bimap(
success: { $0 },
failure: { _ in error2 }
) == failure2)
}
// MARK: Errors
func testErrorsIncludeTheSourceFile() {
let file = #file
XCTAssert(Result<(), NSError>.error().file == file)
}
func testErrorsIncludeTheSourceLine() {
let (line, error) = (#line, Result<(), NSError>.error())
XCTAssertEqual(error.line ?? -1, line)
}
func testErrorsIncludeTheCallingFunction() {
let function = #function
XCTAssert(Result<(), NSError>.error().function == function)
}
func testAnyErrorDelegatesLocalizedDescriptionToUnderlyingError() {
XCTAssertEqual(error.errorDescription, "localized description")
XCTAssertEqual(error.localizedDescription, "localized description")
XCTAssertEqual(error3.errorDescription, "localized description")
XCTAssertEqual(error3.localizedDescription, "localized description")
}
func testAnyErrorDelegatesLocalizedFailureReasonToUnderlyingError() {
XCTAssertEqual(error.failureReason, "failure reason")
}
func testAnyErrorDelegatesLocalizedRecoverySuggestionToUnderlyingError() {
XCTAssertEqual(error.recoverySuggestion, "recovery suggestion")
}
func testAnyErrorDelegatesLocalizedHelpAnchorToUnderlyingError() {
XCTAssertEqual(error.helpAnchor, "help anchor")
}
// MARK: Try - Catch
func testTryCatchProducesSuccesses() {
let result: Result<String, AnyError> = Result(try tryIsSuccess("success"))
XCTAssert(result == success)
}
func testTryCatchProducesFailures() {
let result: Result<String, AnyError> = Result(try tryIsSuccess(nil))
XCTAssert(result.error == error)
}
func testTryCatchWithFunctionProducesSuccesses() {
let function = { try tryIsSuccess("success") }
let result: Result<String, AnyError> = Result(attempt: function)
XCTAssert(result == success)
}
func testTryCatchWithFunctionCatchProducesFailures() {
let function = { try tryIsSuccess(nil) }
let result: Result<String, AnyError> = Result(attempt: function)
XCTAssert(result.error == error)
}
func testTryCatchWithFunctionThrowingNonAnyErrorCanProducesAnyErrorFailures() {
let nsError = NSError(domain: "", code: 0)
let function: () throws -> String = { throw nsError }
let result: Result<String, AnyError> = Result(attempt: function)
XCTAssert(result.error == AnyError(nsError))
}
func testMaterializeProducesSuccesses() {
let result1: Result<String, AnyError> = Result(try tryIsSuccess("success"))
XCTAssert(result1 == success)
let result2: Result<String, AnyError> = Result(attempt: { try tryIsSuccess("success") })
XCTAssert(result2 == success)
}
func testMaterializeProducesFailures() {
let result1: Result<String, AnyError> = Result(try tryIsSuccess(nil))
XCTAssert(result1.error == error)
let result2: Result<String, AnyError> = Result(attempt: { try tryIsSuccess(nil) })
XCTAssert(result2.error == error)
}
func testMaterializeInferrence() {
let result = Result(attempt: { try tryIsSuccess(nil) })
XCTAssert((type(of: result) as Any.Type) is Result<String, AnyError>.Type)
}
// MARK: Recover
func testRecoverProducesLeftForLeftSuccess() {
let left = Result<String, Error>.success("left")
XCTAssertEqual(left.recover("right"), "left")
}
func testRecoverProducesRightForLeftFailure() {
let left = Result<String, Error>.failure(Error.a)
XCTAssertEqual(left.recover("right"), "right")
}
// MARK: Recover With
func testRecoverWithProducesLeftForLeftSuccess() {
let left = Result<String, NSError>.success("left")
let right = Result<String, NSError>.success("right")
XCTAssertEqual(left.recover(with: right).value, "left")
}
func testRecoverWithProducesRightSuccessForLeftFailureAndRightSuccess() {
struct Error: Swift.Error {}
let left = Result<String, Error>.failure(Error())
let right = Result<String, Error>.success("right")
XCTAssertEqual(left.recover(with: right).value, "right")
}
func testRecoverWithProducesRightFailureForLeftFailureAndRightFailure() {
enum Error: Swift.Error { case left, right }
let left = Result<String, Error>.failure(.left)
let right = Result<String, Error>.failure(.right)
XCTAssertEqual(left.recover(with: right).error, .right)
}
func testTryMapProducesSuccess() {
let result = success.tryMap(tryIsSuccess)
XCTAssert(result == success)
}
func testTryMapProducesFailure() {
let result = Result<String, AnyError>.success("fail").tryMap(tryIsSuccess)
XCTAssert(result == failure)
}
}
// MARK: - Fixtures
enum Error: Swift.Error, LocalizedError {
case a, b
var errorDescription: String? {
return "localized description"
}
var failureReason: String? {
return "failure reason"
}
var helpAnchor: String? {
return "help anchor"
}
var recoverySuggestion: String? {
return "recovery suggestion"
}
}
let success = Result<String, AnyError>.success("success")
let error = AnyError(Error.a)
let error2 = AnyError(Error.b)
let error3 = AnyError(NSError(domain: "Result", code: 42, userInfo: [NSLocalizedDescriptionKey: "localized description"]))
let failure = Result<String, AnyError>.failure(error)
let failure2 = Result<String, AnyError>.failure(error2)
// MARK: - Helpers
extension AnyError: Equatable {
public static func ==(lhs: AnyError, rhs: AnyError) -> Bool {
return lhs.error._code == rhs.error._code
&& lhs.error._domain == rhs.error._domain
}
}
func tryIsSuccess(_ text: String?) throws -> String {
guard let text = text, text == "success" else {
throw error
}
return text
}
extension NSError {
var function: String? {
return userInfo[Result<(), NSError>.functionKey] as? String
}
var file: String? {
return userInfo[Result<(), NSError>.fileKey] as? String
}
var line: Int? {
return userInfo[Result<(), NSError>.lineKey] as? Int
}
}
import Foundation
import Result
import XCTest

View file

@ -1,57 +0,0 @@
import XCTest
extension AnyErrorTests {
static let __allTests = [
("testAnyError", testAnyError),
]
}
extension NoErrorTests {
static let __allTests = [
("testEquatable", testEquatable),
]
}
extension ResultTests {
static let __allTests = [
("testAnyErrorDelegatesLocalizedDescriptionToUnderlyingError", testAnyErrorDelegatesLocalizedDescriptionToUnderlyingError),
("testAnyErrorDelegatesLocalizedFailureReasonToUnderlyingError", testAnyErrorDelegatesLocalizedFailureReasonToUnderlyingError),
("testAnyErrorDelegatesLocalizedHelpAnchorToUnderlyingError", testAnyErrorDelegatesLocalizedHelpAnchorToUnderlyingError),
("testAnyErrorDelegatesLocalizedRecoverySuggestionToUnderlyingError", testAnyErrorDelegatesLocalizedRecoverySuggestionToUnderlyingError),
("testBimapTransformsFailures", testBimapTransformsFailures),
("testBimapTransformsSuccesses", testBimapTransformsSuccesses),
("testErrorsIncludeTheCallingFunction", testErrorsIncludeTheCallingFunction),
("testErrorsIncludeTheSourceFile", testErrorsIncludeTheSourceFile),
("testErrorsIncludeTheSourceLine", testErrorsIncludeTheSourceLine),
("testFanout", testFanout),
("testInitOptionalFailure", testInitOptionalFailure),
("testInitOptionalSuccess", testInitOptionalSuccess),
("testMapRewrapsFailures", testMapRewrapsFailures),
("testMapTransformsSuccesses", testMapTransformsSuccesses),
("testMaterializeInferrence", testMaterializeInferrence),
("testMaterializeProducesFailures", testMaterializeProducesFailures),
("testMaterializeProducesSuccesses", testMaterializeProducesSuccesses),
("testRecoverProducesLeftForLeftSuccess", testRecoverProducesLeftForLeftSuccess),
("testRecoverProducesRightForLeftFailure", testRecoverProducesRightForLeftFailure),
("testRecoverWithProducesLeftForLeftSuccess", testRecoverWithProducesLeftForLeftSuccess),
("testRecoverWithProducesRightFailureForLeftFailureAndRightFailure", testRecoverWithProducesRightFailureForLeftFailureAndRightFailure),
("testRecoverWithProducesRightSuccessForLeftFailureAndRightSuccess", testRecoverWithProducesRightSuccessForLeftFailureAndRightSuccess),
("testTryCatchProducesFailures", testTryCatchProducesFailures),
("testTryCatchProducesSuccesses", testTryCatchProducesSuccesses),
("testTryCatchWithFunctionCatchProducesFailures", testTryCatchWithFunctionCatchProducesFailures),
("testTryCatchWithFunctionProducesSuccesses", testTryCatchWithFunctionProducesSuccesses),
("testTryCatchWithFunctionThrowingNonAnyErrorCanProducesAnyErrorFailures", testTryCatchWithFunctionThrowingNonAnyErrorCanProducesAnyErrorFailures),
("testTryMapProducesFailure", testTryMapProducesFailure),
("testTryMapProducesSuccess", testTryMapProducesSuccess),
]
}
#if !os(macOS)
public func __allTests() -> [XCTestCaseEntry] {
return [
testCase(AnyErrorTests.__allTests),
testCase(NoErrorTests.__allTests),
testCase(ResultTests.__allTests),
]
}
#endif

View file

@ -1,13 +0,0 @@
Copyright © 2017 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View file

@ -1,9 +0,0 @@
import PackageDescription
let package = Package(
name: "CwlCatchException",
targets: [
Target(name: "CwlCatchException", dependencies: ["CwlCatchExceptionSupport"]),
Target(name: "CwlCatchExceptionSupport")
]
)

View file

@ -1,46 +0,0 @@
# CwlCatchException
A simple Swift wrapper around an Objective-C `@try`/`@catch` statement that selectively catches Objective-C exceptions by `NSException` subtype, rethrowing if any caught exception is not the expected subtype.
Look at [CwlCatchExceptionTests.swift](https://github.com/mattgallagher/CwlCatchException/blob/master/CwlCatchExceptionTests/CwlCatchExceptionTests.swift?ts=4) for syntax.
## Adding to your project
This project can be used by direct inclusion in your projects or through any of the Swift Package Manager, CocoaPods or Carthage.
Minimum requirements are iOS 8 or macOS 10.9.
### Manual inclusion
1. In a subdirectory of your project's directory, run `git clone https://github.com/mattgallagher/CwlCatchException.git`
2. Drag the "CwlCatchException.xcodeproj" file from the Finder into your own project's file tree in Xcode
3. Add the "CwlCatchException.framework" from the "Products" folder of the CwlCatchException project's file tree to the "Copy Files (Frameworks)" build phases of any target that you want to include this module.
That third step is a little tricky if you're unfamiliar with Xcode but it involves:
a. click on your project in the file tree
b. click on the target to whih you want to add this module
c. select the "Build Phases" tab
d. if you don't already have a "Copy File" build phase with a "Destination: Frameworks", add one using the "+" button in the top left of the tab
e. click the "+" within the "Copy File (Frameworks)" phase and from the list that appears, select the "CwlCatchException.framework" (if there are multiple frameworks with the same name, look for the one that appears *above* the corresponding macOS or iOS CwlCatchException testing target).
### Swift Package Manager
Add the following to the `dependencies` array in your "Package.swift" file:
.Package(url: "https://github.com/mattgallagher/CwlCatchException.git", majorVersion: 1),
Or, if you're using the `swift-tools-version:4.0` package manager, add the following to the `dependencies` array in your "Package.swift" file:
.package(url: "https://github.com/mattgallagher/CwlCatchException.git", majorVersion: 1)
### CocoaPods
Add the following to your target in your "Podfile":
pod 'CwlCatchException', :git => 'https://github.com/mattgallagher/CwlCatchException.git'
### Carthage
Add the following line to your Cartfile:
git "https://github.com/mattgallagher/CwlCatchException.git" "master"

View file

@ -1,35 +0,0 @@
//
// CwlCatchException.swift
// CwlAssertionTesting
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
import Foundation
#if SWIFT_PACKAGE
import CwlCatchExceptionSupport
#endif
private func catchReturnTypeConverter<T: NSException>(_ type: T.Type, block: () -> Void) -> T? {
return catchExceptionOfKind(type, block) as? T
}
extension NSException {
public static func catchException(in block: () -> Void) -> Self? {
return catchReturnTypeConverter(self, block: block)
}
}

View file

@ -1,37 +0,0 @@
//
// CwlCatchException.m
// CwlAssertionTesting
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
#import "CwlCatchException.h"
#if !SWIFT_PACKAGE && NON_SWIFT_PACKAGE
__attribute__((visibility("hidden")))
#endif
NSException* catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)(void)) {
@try {
inBlock();
} @catch (NSException *exception) {
if ([exception isKindOfClass:type]) {
return exception;
} else {
@throw;
}
}
return nil;
}

View file

@ -1,32 +0,0 @@
//
// CwlCatchException.h
// CwlCatchException
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
#import <Foundation/Foundation.h>
//! Project version number for CwlCatchException.
FOUNDATION_EXPORT double CwlCatchExceptionVersionNumber;
//! Project version string for CwlCatchException.
FOUNDATION_EXPORT const unsigned char CwlCatchExceptionVersionString[];
#if !SWIFT_PACKAGE && NON_SWIFT_PACKAGE
__attribute__((visibility("hidden")))
#endif
NSException* __nullable catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)(void));

View file

@ -1,32 +0,0 @@
//
// CwlPreconditionTesting.h
// CwlPreconditionTesting
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
#import <Foundation/Foundation.h>
extern bool _swift_reportFatalErrorsToDebugger;
//! Project version number for CwlUtils.
FOUNDATION_EXPORT double CwlPreconditionTestingVersionNumber;
//! Project version string for CwlUtils.
FOUNDATION_EXPORT const unsigned char CwlAssertingTestingVersionString[];
#include "CwlMachBadInstructionHandler.h"
#include "CwlCatchException.h"

View file

@ -1,29 +0,0 @@
//
// CwlPreconditionTesting.h
// CwlPreconditionTesting
//
// Created by Matt Gallagher on 2016/01/10.
// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
#import <Foundation/Foundation.h>
extern bool _swift_reportFatalErrorsToDebugger;
//! Project version number for CwlUtils.
FOUNDATION_EXPORT double CwlPreconditionTesting_POSIXVersionNumber;
//! Project version string for CwlUtils.
FOUNDATION_EXPORT const unsigned char CwlAssertingTesting_POSIXVersionString[];

View file

@ -1,49 +0,0 @@
#if canImport(Darwin)
import Foundation
extension NSString {
private static var invalidCharacters: CharacterSet = {
var invalidCharacters = CharacterSet()
let invalidCharacterSets: [CharacterSet] = [
.whitespacesAndNewlines,
.illegalCharacters,
.controlCharacters,
.punctuationCharacters,
.nonBaseCharacters,
.symbols
]
for invalidSet in invalidCharacterSets {
invalidCharacters.formUnion(invalidSet)
}
return invalidCharacters
}()
/// This API is not meant to be used outside Quick, so will be unavailable in
/// a next major version.
@objc(qck_c99ExtendedIdentifier)
public var c99ExtendedIdentifier: String {
let validComponents = components(separatedBy: NSString.invalidCharacters)
let result = validComponents.joined(separator: "_")
return result.isEmpty ? "_" : result
}
}
/// Extension methods or properties for NSObject subclasses are invisible from
/// the Objective-C runtime on static linking unless the consumers add `-ObjC`
/// linker flag, so let's make a wrapper class to mitigate that situation.
///
/// See: https://github.com/Quick/Quick/issues/785 and https://github.com/Quick/Quick/pull/803
@objc
class QCKObjCStringUtils: NSObject {
override private init() {}
@objc
static func c99ExtendedIdentifier(from string: String) -> String {
return string.c99ExtendedIdentifier
}
}
#endif

View file

@ -1,30 +0,0 @@
@testable import Quick
import Nimble
@discardableResult
public func qck_runSpec(_ specClass: QuickSpec.Type) -> TestRun? {
return qck_runSpecs([specClass])
}
@discardableResult
public func qck_runSpecs(_ specClasses: [QuickSpec.Type]) -> TestRun? {
Quick.World.sharedWorld.isRunningAdditionalSuites = true
var executionCount: UInt = 0
var hadUnexpectedFailure = false
let fails = gatherFailingExpectations(silently: true) {
for specClass in specClasses {
for (_, test) in specClass.allTests {
do {
try test(specClass.init())()
} catch {
hadUnexpectedFailure = true
}
executionCount += 1
}
}
}
return TestRun(executionCount: executionCount, hasSucceeded: fails.isEmpty && !hadUnexpectedFailure)
}

View file

@ -1,9 +0,0 @@
public struct TestRun {
public var executionCount: UInt
public var hasSucceeded: Bool
public init(executionCount: UInt, hasSucceeded: Bool) {
self.executionCount = executionCount
self.hasSucceeded = hasSucceeded
}
}

View file

@ -1,17 +0,0 @@
#import <Quick/Quick.h>
NS_ASSUME_NONNULL_BEGIN
@interface QuickSpec (QuickSpec_MethodList)
/**
* This method will instantiate an instance of the class on which it is called,
* returning a list of selector names for it.
*
* @return a set of NSStrings representing the list of selectors it contains
*/
+ (NSSet<NSString *> *)allSelectors;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,23 +0,0 @@
#import "QuickSpec+QuickSpec_MethodList.h"
#import <objc/runtime.h>
@implementation QuickSpec (QuickSpec_MethodList)
+ (NSSet<NSString*> *)allSelectors {
QuickSpec *specInstance = [[[self class] alloc] init];
NSMutableSet<NSString *> *allSelectors = [NSMutableSet set];
unsigned int methodCount = 0;
Method *methodList = class_copyMethodList(object_getClass(specInstance), &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {
SEL selector = method_getName(methodList[i]);
[allSelectors addObject:NSStringFromSelector(selector)];
}
free(methodList);
return [allSelectors copy];
}
@end

View file

@ -1,20 +0,0 @@
#import <XCTest/XCTest.h>
/**
Add the ability to temporarily disable internal XCTest execution observation in
order to run isolated XCTestSuite instances while the QuickTests test suite is running.
*/
@interface XCTestObservationCenter (QCKSuspendObservation)
/**
Suspends test suite observation for XCTest-provided observers for the duration that
the block is executing. Any test suites that are executed within the block do not
generate any log output. Failures are still reported.
Use this method to run XCTestSuite objects while another XCTestSuite is running.
Without this method, tests fail with the message: "Timed out waiting for IDE
barrier message to complete" or "Unexpected TestSuiteDidStart".
*/
- (void)qck_suspendObservationForBlock:(void (^)(void))block;
@end

View file

@ -1,54 +0,0 @@
@import XCTest;
#import <objc/runtime.h>
@interface XCTestObservationCenter (Redeclaration)
- (id)observers;
- (void)removeTestObserver:(id<XCTestObservation>)testObserver;
@end
@implementation XCTestObservationCenter (QCKSuspendObservation)
/// This allows us to only suspend observation for observers by provided by Apple
/// as a part of the XCTest framework. In particular it is important that we not
/// suspend the observer added by Nimble, otherwise it is unable to properly
/// report assertion failures.
static BOOL (^isFromApple)(id) = ^BOOL(id observer){
return [[NSBundle bundleForClass:[observer class]].bundleIdentifier containsString:@"com.apple.dt.XCTest"];
};
- (void)qck_suspendObservationForBlock:(void (^)(void))block {
id originalObservers = [[self observers] copy];
NSMutableArray *suspendedObservers = [NSMutableArray new];
for (id observer in originalObservers) {
if (isFromApple(observer)) {
[suspendedObservers addObject:observer];
if ([self respondsToSelector:@selector(removeTestObserver:)]) {
[self removeTestObserver:observer];
}
else if ([[self observers] respondsToSelector:@selector(removeObject:)]) {
[[self observers] removeObject:observer];
}
else {
NSAssert(NO, @"unexpected type: unable to remove observers: %@", originalObservers);
}
}
}
@try {
block();
}
@finally {
for (id observer in suspendedObservers) {
if ([[self observers] respondsToSelector:@selector(addObject:)]) {
[[self observers] addObject:observer];
}
else if ([self respondsToSelector:@selector(addTestObserver:)]) {
[self addTestObserver:observer];
}
}
}
}
@end

View file

@ -1,9 +0,0 @@
.DS_Store
xcuserdata
*.xcuserdatad
*.xccheckout
*.mode*
*.pbxuser
Carthage/Build
.build

View file

@ -1 +0,0 @@
4.2

View file

@ -1,94 +0,0 @@
branches:
only:
- master
matrix:
include:
- 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
- gem update cocoapods && rm .swift-version && pod lib lint
env:
- JOB=Xcode
- XCODE_ACTION="build-for-testing test-without-building"
os: osx
osx_image: xcode9.2
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
- rm .swift-version && pod lib lint
env:
- JOB=Xcode
- XCODE_ACTION="build-for-testing test-without-building"
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
- swift test
env: JOB=SPM
os: osx
osx_image: xcode9.2
language: objective-c
- script:
- swift --version
- swift build
- swift test
env: JOB=SPM
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
- swift test
env:
- JOB=Linux
sudo: required
dist: trusty
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

@ -1,23 +0,0 @@
We love that you're interested in contributing to this project!
To make the process as painless as possible, we have just a couple of guidelines
that should make life easier for everyone involved.
## Prefer Pull Requests
If you know exactly how to implement the feature being suggested or fix the bug
being reported, please open a pull request instead of an issue. Pull requests are easier than
patches or inline code blocks for discussing and merging the changes.
If you can't make the change yourself, please open an issue after making sure
that one isn't already logged.
## Contributing Code
Fork this repository, make it awesomer (preferably in a branch named for the
topic), send a pull request!
All code contributions should match our [coding
conventions](https://github.com/github/swift-style-guide).
Thanks for contributing! :boom::camel:

View file

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 Rob Rix
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,14 +0,0 @@
// swift-tools-version:4.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: [4]
)

View file

@ -1,14 +0,0 @@
// 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

@ -1,112 +0,0 @@
# Result
[![Build Status](https://travis-ci.org/antitypical/Result.svg?branch=master)](https://travis-ci.org/antitypical/Result)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![CocoaPods](https://img.shields.io/cocoapods/v/Result.svg)](https://cocoapods.org/)
[![Reference Status](https://www.versioneye.com/objective-c/result/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/result/references)
This is a Swift µframework providing `Result<Value, Error>`.
`Result<Value, Error>` values are either successful (wrapping `Value`) or failed (wrapping `Error`). This is similar to Swifts native `Optional` type: `success` is like `some`, and `failure` is like `none` except with an associated `Error` value. The addition of an associated `Error` allows errors to be passed along for logging or displaying to the user.
Using this µframework instead of rolling your own `Result` type allows you to easily interface with other frameworks that also use `Result`.
## Use
Use `Result` whenever an operation has the possibility of failure. Consider the following example of a function that tries to extract a `String` for a given key from a JSON `Dictionary`.
```swift
typealias JSONObject = [String: Any]
enum JSONError: Error {
case noSuchKey(String)
case typeMismatch
}
func stringForKey(json: JSONObject, key: String) -> Result<String, JSONError> {
guard let value = json[key] else {
return .failure(.noSuchKey(key))
}
guard let value = value as? String else {
return .failure(.typeMismatch)
}
return .success(value)
}
```
This function provides a more robust wrapper around the default subscripting provided by `Dictionary`. Rather than return `Any?`, it returns a `Result` that either contains the `String` value for the given key, or an `ErrorType` detailing what went wrong.
One simple way to handle a `Result` is to deconstruct it using a `switch` statement.
```swift
switch stringForKey(json, key: "email") {
case let .success(email):
print("The email is \(email)")
case let .failure(.noSuchKey(key)):
print("\(key) is not a valid key")
case .failure(.typeMismatch):
print("Didn't have the right type")
}
```
Using a `switch` statement allows powerful pattern matching, and ensures all possible results are covered. Swift 2.0 offers new ways to deconstruct enums like the `if-case` statement, but be wary as such methods do not ensure errors are handled.
Other methods available for processing `Result` are detailed in the [API documentation](http://cocoadocs.org/docsets/Result/).
## Result vs. Throws
Swift 2.0 introduces error handling via throwing and catching `Error`. `Result` accomplishes the same goal by encapsulating the result instead of hijacking control flow. The `Result` abstraction enables powerful functionality such as `map` and `flatMap`, making `Result` more composable than `throw`.
Since dealing with APIs that throw is common, you can convert such functions into a `Result` by using the `materialize` method. Conversely, a `Result` can be used to throw an error by calling `dematerialize`.
## Higher Order Functions
`map` and `flatMap` operate the same as `Optional.map` and `Optional.flatMap` except they apply to `Result`.
`map` transforms a `Result` into a `Result` of a new type. It does this by taking a function that transforms the `Value` type into a new value. This transformation is only applied in the case of a `success`. In the case of a `failure`, the associated error is re-wrapped in the new `Result`.
```swift
// transforms a Result<Int, JSONError> to a Result<String, JSONError>
let idResult = intForKey(json, key:"id").map { id in String(id) }
```
Here, the final result is either the id as a `String`, or carries over the `failure` from the previous result.
`flatMap` is similar to `map` in that it transforms the `Result` into another `Result`. However, the function passed into `flatMap` must return a `Result`.
An in depth discussion of `map` and `flatMap` is beyond the scope of this documentation. If you would like a deeper understanding, read about functors and monads. This article is a good place to [start](http://www.javiersoto.me/post/106875422394).
## Integration
### Carthage
1. Add this repository as a submodule and/or [add it to your Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile) if youre using [carthage](https://github.com/Carthage/Carthage/) to manage your dependencies.
2. Drag `Result.xcodeproj` into your project or workspace.
3. Link your target against `Result.framework`.
4. Application targets should ensure that the framework gets copied into their application bundle. (Framework targets should instead require the application linking them to include Result.)
### Cocoapods
```ruby
pod 'Result', '~> 4.0.0'
```
### Swift Package Manager
```swift
import PackageDescription
let package = Package(
name: "MyProject",
targets: [],
dependencies: [
.Package(url: "https://github.com/antitypical/Result.git",
majorVersion: 4)
]
)
```

View file

@ -1,19 +0,0 @@
Pod::Spec.new do |s|
s.name = 'Result'
s.version = '4.1.0'
s.summary = 'Swift type modelling the success/failure of arbitrary operations'
s.homepage = 'https://github.com/antitypical/Result'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Rob Rix' => 'rob.rix@github.com' }
s.source = { :git => 'https://github.com/antitypical/Result.git', :tag => s.version }
s.source_files = 'Result/*.swift'
s.requires_arc = true
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.9'
s.watchos.deployment_target = '2.0'
s.tvos.deployment_target = '9.0'
s.cocoapods_version = '>= 1.4.0'
s.swift_version = '4.2'
end

File diff suppressed because it is too large Load diff

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Result.xcodeproj">
</FileRef>
</Workspace>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View file

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480561A9572F5009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-Mac"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480661A9572F5009D7229"
BuildableName = "Result-MacTests.xctest"
BlueprintName = "Result-MacTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480661A9572F5009D7229"
BuildableName = "Result-MacTests.xctest"
BlueprintName = "Result-MacTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480561A9572F5009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-Mac"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480561A9572F5009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-Mac"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480561A9572F5009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-Mac"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D454807C1A957361009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-iOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480861A957362009D7229"
BuildableName = "Result-iOSTests.xctest"
BlueprintName = "Result-iOSTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D45480861A957362009D7229"
BuildableName = "Result-iOSTests.xctest"
BlueprintName = "Result-iOSTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D454807C1A957361009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-iOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D454807C1A957361009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-iOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D454807C1A957361009D7229"
BuildableName = "Result.framework"
BlueprintName = "Result-iOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE3C1BA280DC00130C48"
BuildableName = "Result.framework"
BlueprintName = "Result-tvOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE491BA280E000130C48"
BuildableName = "Result-tvOSTests.xctest"
BlueprintName = "Result-tvOSTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE3C1BA280DC00130C48"
BuildableName = "Result.framework"
BlueprintName = "Result-tvOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE3C1BA280DC00130C48"
BuildableName = "Result.framework"
BlueprintName = "Result-tvOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "57FCDE3C1BA280DC00130C48"
BuildableName = "Result.framework"
BlueprintName = "Result-tvOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579991B2B788F005D26AE"
BuildableName = "Result.framework"
BlueprintName = "Result-watchOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579A51B2B78A1005D26AE"
BuildableName = "Result-watchOSTests.xctest"
BlueprintName = "Result-watchOSTests"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579991B2B788F005D26AE"
BuildableName = "Result.framework"
BlueprintName = "Result-watchOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579991B2B788F005D26AE"
BuildableName = "Result.framework"
BlueprintName = "Result-watchOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D03579991B2B788F005D26AE"
BuildableName = "Result.framework"
BlueprintName = "Result-watchOS"
ReferencedContainer = "container:Result.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -1,46 +0,0 @@
import Foundation
/// A type-erased error which wraps an arbitrary error instance. This should be
/// useful for generic contexts.
public struct AnyError: Swift.Error {
/// The underlying error.
public let error: Swift.Error
public init(_ error: Swift.Error) {
if let anyError = error as? AnyError {
self = anyError
} else {
self.error = error
}
}
}
extension AnyError: ErrorConvertible {
public static func error(from error: Error) -> AnyError {
return AnyError(error)
}
}
extension AnyError: CustomStringConvertible {
public var description: String {
return String(describing: error)
}
}
extension AnyError: LocalizedError {
public var errorDescription: String? {
return error.localizedDescription
}
public var failureReason: String? {
return (error as? LocalizedError)?.failureReason
}
public var helpAnchor: String? {
return (error as? LocalizedError)?.helpAnchor
}
public var recoverySuggestion: String? {
return (error as? LocalizedError)?.recoverySuggestion
}
}

View file

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015 Rob Rix. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View file

@ -1,10 +0,0 @@
/// An error that is impossible to construct.
///
/// This can be used to describe `Result`s where failures will never
/// be generated. For example, `Result<Int, NoError>` describes a result that
/// contains an `Int`eger and is guaranteed never to be a `failure`.
public enum NoError: Swift.Error, Equatable {
public static func ==(lhs: NoError, rhs: NoError) -> Bool {
return true
}
}

View file

@ -1,8 +0,0 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
/// Project version number for Result.
extern double ResultVersionNumber;
/// Project version string for Result.
extern const unsigned char ResultVersionString[];

View file

@ -1,229 +0,0 @@
// 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<Value, Error: Swift.Error>: ResultProtocol, CustomStringConvertible, CustomDebugStringConvertible {
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`.
public init(value: Value) {
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: Value?, failWith: @autoclosure () -> Error) {
self = value.map(Result.success) ?? .failure(failWith())
}
/// Constructs a result from a function that uses `throw`, failing with `Error` if throws.
public init(_ f: @autoclosure () throws -> Value) {
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 body())
} catch var error {
if Error.self == AnyError.self {
error = AnyError(error)
}
self = .failure(error as! Error)
}
}
// 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
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>(ifSuccess: (Value) -> Result, ifFailure: (Error) -> Result) -> Result {
switch self {
case let .success(value):
return ifSuccess(value)
case let .failure(value):
return ifFailure(value)
}
}
// 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: Any] = [
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 {
switch self {
case let .success(value): return ".success(\(value))"
case let .failure(error): return ".failure(\(error))"
}
}
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return description
}
// MARK: ResultProtocol
public var result: Result<Value, Error> {
return self
}
}
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)
}
/// Constructs a result from a closure that uses `throw`, failing with `AnyError` if throws.
public init(attempt f: () throws -> Value) {
do {
self = .success(try f())
} catch {
self = .failure(AnyError(error))
}
}
}
// MARK: - Derive result from failable closure
@available(*, deprecated, renamed: "Result.init(attempt:)")
public func materialize<T>(_ f: () throws -> T) -> Result<T, AnyError> {
return Result(attempt: f)
}
@available(*, deprecated, renamed: "Result.init(_:)")
public func materialize<T>(_ f: @autoclosure () throws -> T) -> Result<T, AnyError> {
return Result(try f())
}
// MARK: - ErrorConvertible conformance
extension NSError: ErrorConvertible {
public static func error(from error: Swift.Error) -> Self {
func cast<T: NSError>(_ error: Swift.Error) -> T {
return error as! T
}
return cast(error)
}
}
// MARK: - migration support
@available(*, unavailable, message: "Use the overload which returns `Result<T, AnyError>` instead")
public func materialize<T>(_ f: () throws -> T) -> Result<T, NSError> {
fatalError()
}
@available(*, unavailable, message: "Use the overload which returns `Result<T, AnyError>` instead")
public func materialize<T>(_ f: @autoclosure () throws -> T) -> Result<T, NSError> {
fatalError()
}
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
/// Constructs a `Result` with the result of calling `try` with an error pointer.
///
/// 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) }
@available(*, unavailable, message: "This has been removed. Use `Result.init(attempt:)` instead. See https://github.com/antitypical/Result/issues/85 for the details.")
public func `try`<T>(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> T?) -> Result<T, NSError> {
fatalError()
}
/// Constructs a `Result` with the result of calling `try` with an error pointer.
///
/// 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) }
@available(*, unavailable, message: "This has been removed. Use `Result.init(attempt:)` instead. See https://github.com/antitypical/Result/issues/85 for the details.")
public func `try`(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> Bool) -> Result<(), NSError> {
fatalError()
}
#endif
// MARK: -
import Foundation

View file

@ -1,152 +0,0 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
/// A protocol that can be used to constrain associated types as `Result`.
public protocol ResultProtocol {
associatedtype Value
associatedtype Error: Swift.Error
init(value: Value)
init(error: Error)
var result: Result<Value, Error> { get }
}
extension Result {
/// Returns the value if self represents a success, `nil` otherwise.
public var value: Value? {
switch self {
case let .success(value): return value
case .failure: return nil
}
}
/// Returns the error if self represents a failure, `nil` otherwise.
public var error: Error? {
switch self {
case .success: return nil
case let .failure(error): return error
}
}
/// Returns a new Result by mapping `Success`es values using `transform`, or re-wrapping `Failure`s errors.
public func map<U>(_ transform: (Value) -> 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>(_ transform: (Value) -> Result<U, Error>) -> Result<U, Error> {
switch self {
case let .success(value): return transform(value)
case let .failure(error): return .failure(error)
}
}
/// Returns a Result with a tuple of the receiver and `other` values if both
/// are `Success`es, or re-wrapping the error of the earlier `Failure`.
public func fanout<U>(_ other: @autoclosure () -> Result<U, Error>) -> Result<(Value, U), Error> {
return self.flatMap { left in other().map { right in (left, right) } }
}
/// Returns a new Result by mapping `Failure`'s values using `transform`, or re-wrapping `Success`es values.
public func mapError<Error2>(_ transform: (Error) -> Error2) -> Result<Value, Error2> {
return flatMapError { .failure(transform($0)) }
}
/// Returns the result of applying `transform` to `Failure`s errors, or re-wrapping `Success`es values.
public func flatMapError<Error2>(_ transform: (Error) -> Result<Value, Error2>) -> Result<Value, Error2> {
switch self {
case let .success(value): return .success(value)
case let .failure(error): return transform(error)
}
}
/// Returns a new Result by mapping `Success`es values using `success`, and by mapping `Failure`'s values using `failure`.
public func bimap<U, Error2>(success: (Value) -> U, failure: (Error) -> Error2) -> Result<U, Error2> {
switch self {
case let .success(value): return .success(success(value))
case let .failure(error): return .failure(failure(error))
}
}
}
extension Result {
// MARK: Higher-order functions
/// Returns `self.value` if this result is a .Success, or the given value otherwise. Equivalent with `??`
public func recover(_ value: @autoclosure () -> Value) -> Value {
return self.value ?? value()
}
/// Returns this result if it is a .Success, or the given result otherwise. Equivalent with `??`
public func recover(with result: @autoclosure () -> Result<Value, Error>) -> Result<Value, Error> {
switch self {
case .success: return self
case .failure: return result()
}
}
}
/// Protocol used to constrain `tryMap` to `Result`s with compatible `Error`s.
public protocol ErrorConvertible: Swift.Error {
static func error(from error: Swift.Error) -> Self
}
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> {
return flatMap { value in
do {
return .success(try transform(value))
}
catch {
let convertedError = Error.error(from: error)
// Revisit this in a future version of Swift. https://twitter.com/jckarter/status/672931114944696321
return .failure(convertedError)
}
}
}
}
// MARK: - Operators
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 {
return left == right
} else if let left = left.error, let right = right.error {
return left == right
}
return false
}
}
#if swift(>=4.1)
extension Result: Equatable where Result.Success: Equatable, Result.Failure: Equatable { }
#else
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)
}
}
#endif
extension Result {
/// Returns the value of `left` if it is a `Success`, or `right` otherwise. Short-circuits.
public static func ??(left: Result<Value, Error>, right: @autoclosure () -> Value) -> Value {
return left.recover(right())
}
/// Returns `left` if it is a `Success`es, or `right` otherwise. Short-circuits.
public static func ??(left: Result<Value, Error>, right: @autoclosure () -> Result<Value, Error>) -> Result<Value, Error> {
return left.recover(with: right())
}
}
// MARK: - migration support
@available(*, unavailable, renamed: "ErrorConvertible")
public protocol ErrorProtocolConvertible: ErrorConvertible {}

View file

@ -1,8 +0,0 @@
import XCTest
import ResultTests
var tests = [XCTestCaseEntry]()
tests += ResultTests.__allTests()
XCTMain(tests)

View file

@ -1,12 +0,0 @@
import Foundation
import XCTest
import Result
final class AnyErrorTests: XCTestCase {
func testAnyError() {
let error = Error.a
let anyErrorFromError = AnyError(error)
let anyErrorFromAnyError = AnyError(anyErrorFromError)
XCTAssertTrue(anyErrorFromError == anyErrorFromAnyError)
}
}

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>4.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View file

@ -1,11 +0,0 @@
import Foundation
import XCTest
import Result
final class NoErrorTests: XCTestCase {
func testEquatable() {
let foo = Result<Int, NoError>(1)
let bar = Result<Int, NoError>(1)
XCTAssertTrue(foo == bar)
}
}

View file

@ -1,256 +0,0 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
final class ResultTests: XCTestCase {
func testMapTransformsSuccesses() {
XCTAssertEqual(success.map { $0.count } ?? 0, 7)
}
func testMapRewrapsFailures() {
XCTAssertEqual(failure.map { $0.count } ?? 0, 0)
}
func testInitOptionalSuccess() {
XCTAssert(Result("success" as String?, failWith: error) == success)
}
func testInitOptionalFailure() {
XCTAssert(Result(nil, failWith: error) == failure)
}
func testFanout() {
let resultSuccess = success.fanout(success)
if let (x, y) = resultSuccess.value {
XCTAssertTrue(x == "success" && y == "success")
} else {
XCTFail()
}
let resultFailureBoth = failure.fanout(failure2)
XCTAssert(resultFailureBoth.error == error)
let resultFailureLeft = failure.fanout(success)
XCTAssert(resultFailureLeft.error == error)
let resultFailureRight = success.fanout(failure2)
XCTAssert(resultFailureRight.error == error2)
}
func testBimapTransformsSuccesses() {
XCTAssertEqual(success.bimap(
success: { $0.count },
failure: { $0 }
) ?? 0, 7)
}
func testBimapTransformsFailures() {
XCTAssert(failure.bimap(
success: { $0 },
failure: { _ in error2 }
) == failure2)
}
// MARK: Errors
func testErrorsIncludeTheSourceFile() {
let file = #file
XCTAssert(Result<(), NSError>.error().file == file)
}
func testErrorsIncludeTheSourceLine() {
let (line, error) = (#line, Result<(), NSError>.error())
XCTAssertEqual(error.line ?? -1, line)
}
func testErrorsIncludeTheCallingFunction() {
let function = #function
XCTAssert(Result<(), NSError>.error().function == function)
}
func testAnyErrorDelegatesLocalizedDescriptionToUnderlyingError() {
XCTAssertEqual(error.errorDescription, "localized description")
XCTAssertEqual(error.localizedDescription, "localized description")
XCTAssertEqual(error3.errorDescription, "localized description")
XCTAssertEqual(error3.localizedDescription, "localized description")
}
func testAnyErrorDelegatesLocalizedFailureReasonToUnderlyingError() {
XCTAssertEqual(error.failureReason, "failure reason")
}
func testAnyErrorDelegatesLocalizedRecoverySuggestionToUnderlyingError() {
XCTAssertEqual(error.recoverySuggestion, "recovery suggestion")
}
func testAnyErrorDelegatesLocalizedHelpAnchorToUnderlyingError() {
XCTAssertEqual(error.helpAnchor, "help anchor")
}
// MARK: Try - Catch
func testTryCatchProducesSuccesses() {
let result: Result<String, AnyError> = Result(try tryIsSuccess("success"))
XCTAssert(result == success)
}
func testTryCatchProducesFailures() {
let result: Result<String, AnyError> = Result(try tryIsSuccess(nil))
XCTAssert(result.error == error)
}
func testTryCatchWithFunctionProducesSuccesses() {
let function = { try tryIsSuccess("success") }
let result: Result<String, AnyError> = Result(attempt: function)
XCTAssert(result == success)
}
func testTryCatchWithFunctionCatchProducesFailures() {
let function = { try tryIsSuccess(nil) }
let result: Result<String, AnyError> = Result(attempt: function)
XCTAssert(result.error == error)
}
func testTryCatchWithFunctionThrowingNonAnyErrorCanProducesAnyErrorFailures() {
let nsError = NSError(domain: "", code: 0)
let function: () throws -> String = { throw nsError }
let result: Result<String, AnyError> = Result(attempt: function)
XCTAssert(result.error == AnyError(nsError))
}
func testMaterializeProducesSuccesses() {
let result1: Result<String, AnyError> = Result(try tryIsSuccess("success"))
XCTAssert(result1 == success)
let result2: Result<String, AnyError> = Result(attempt: { try tryIsSuccess("success") })
XCTAssert(result2 == success)
}
func testMaterializeProducesFailures() {
let result1: Result<String, AnyError> = Result(try tryIsSuccess(nil))
XCTAssert(result1.error == error)
let result2: Result<String, AnyError> = Result(attempt: { try tryIsSuccess(nil) })
XCTAssert(result2.error == error)
}
func testMaterializeInferrence() {
let result = Result(attempt: { try tryIsSuccess(nil) })
XCTAssert((type(of: result) as Any.Type) is Result<String, AnyError>.Type)
}
// MARK: Recover
func testRecoverProducesLeftForLeftSuccess() {
let left = Result<String, Error>.success("left")
XCTAssertEqual(left.recover("right"), "left")
}
func testRecoverProducesRightForLeftFailure() {
let left = Result<String, Error>.failure(Error.a)
XCTAssertEqual(left.recover("right"), "right")
}
// MARK: Recover With
func testRecoverWithProducesLeftForLeftSuccess() {
let left = Result<String, NSError>.success("left")
let right = Result<String, NSError>.success("right")
XCTAssertEqual(left.recover(with: right).value, "left")
}
func testRecoverWithProducesRightSuccessForLeftFailureAndRightSuccess() {
struct Error: Swift.Error {}
let left = Result<String, Error>.failure(Error())
let right = Result<String, Error>.success("right")
XCTAssertEqual(left.recover(with: right).value, "right")
}
func testRecoverWithProducesRightFailureForLeftFailureAndRightFailure() {
enum Error: Swift.Error { case left, right }
let left = Result<String, Error>.failure(.left)
let right = Result<String, Error>.failure(.right)
XCTAssertEqual(left.recover(with: right).error, .right)
}
func testTryMapProducesSuccess() {
let result = success.tryMap(tryIsSuccess)
XCTAssert(result == success)
}
func testTryMapProducesFailure() {
let result = Result<String, AnyError>.success("fail").tryMap(tryIsSuccess)
XCTAssert(result == failure)
}
}
// MARK: - Fixtures
enum Error: Swift.Error, LocalizedError {
case a, b
var errorDescription: String? {
return "localized description"
}
var failureReason: String? {
return "failure reason"
}
var helpAnchor: String? {
return "help anchor"
}
var recoverySuggestion: String? {
return "recovery suggestion"
}
}
let success = Result<String, AnyError>.success("success")
let error = AnyError(Error.a)
let error2 = AnyError(Error.b)
let error3 = AnyError(NSError(domain: "Result", code: 42, userInfo: [NSLocalizedDescriptionKey: "localized description"]))
let failure = Result<String, AnyError>.failure(error)
let failure2 = Result<String, AnyError>.failure(error2)
// MARK: - Helpers
extension AnyError: Equatable {
public static func ==(lhs: AnyError, rhs: AnyError) -> Bool {
return lhs.error._code == rhs.error._code
&& lhs.error._domain == rhs.error._domain
}
}
func tryIsSuccess(_ text: String?) throws -> String {
guard let text = text, text == "success" else {
throw error
}
return text
}
extension NSError {
var function: String? {
return userInfo[Result<(), NSError>.functionKey] as? String
}
var file: String? {
return userInfo[Result<(), NSError>.fileKey] as? String
}
var line: Int? {
return userInfo[Result<(), NSError>.lineKey] as? Int
}
}
import Foundation
import Result
import XCTest

View file

@ -1,57 +0,0 @@
import XCTest
extension AnyErrorTests {
static let __allTests = [
("testAnyError", testAnyError),
]
}
extension NoErrorTests {
static let __allTests = [
("testEquatable", testEquatable),
]
}
extension ResultTests {
static let __allTests = [
("testAnyErrorDelegatesLocalizedDescriptionToUnderlyingError", testAnyErrorDelegatesLocalizedDescriptionToUnderlyingError),
("testAnyErrorDelegatesLocalizedFailureReasonToUnderlyingError", testAnyErrorDelegatesLocalizedFailureReasonToUnderlyingError),
("testAnyErrorDelegatesLocalizedHelpAnchorToUnderlyingError", testAnyErrorDelegatesLocalizedHelpAnchorToUnderlyingError),
("testAnyErrorDelegatesLocalizedRecoverySuggestionToUnderlyingError", testAnyErrorDelegatesLocalizedRecoverySuggestionToUnderlyingError),
("testBimapTransformsFailures", testBimapTransformsFailures),
("testBimapTransformsSuccesses", testBimapTransformsSuccesses),
("testErrorsIncludeTheCallingFunction", testErrorsIncludeTheCallingFunction),
("testErrorsIncludeTheSourceFile", testErrorsIncludeTheSourceFile),
("testErrorsIncludeTheSourceLine", testErrorsIncludeTheSourceLine),
("testFanout", testFanout),
("testInitOptionalFailure", testInitOptionalFailure),
("testInitOptionalSuccess", testInitOptionalSuccess),
("testMapRewrapsFailures", testMapRewrapsFailures),
("testMapTransformsSuccesses", testMapTransformsSuccesses),
("testMaterializeInferrence", testMaterializeInferrence),
("testMaterializeProducesFailures", testMaterializeProducesFailures),
("testMaterializeProducesSuccesses", testMaterializeProducesSuccesses),
("testRecoverProducesLeftForLeftSuccess", testRecoverProducesLeftForLeftSuccess),
("testRecoverProducesRightForLeftFailure", testRecoverProducesRightForLeftFailure),
("testRecoverWithProducesLeftForLeftSuccess", testRecoverWithProducesLeftForLeftSuccess),
("testRecoverWithProducesRightFailureForLeftFailureAndRightFailure", testRecoverWithProducesRightFailureForLeftFailureAndRightFailure),
("testRecoverWithProducesRightSuccessForLeftFailureAndRightSuccess", testRecoverWithProducesRightSuccessForLeftFailureAndRightSuccess),
("testTryCatchProducesFailures", testTryCatchProducesFailures),
("testTryCatchProducesSuccesses", testTryCatchProducesSuccesses),
("testTryCatchWithFunctionCatchProducesFailures", testTryCatchWithFunctionCatchProducesFailures),
("testTryCatchWithFunctionProducesSuccesses", testTryCatchWithFunctionProducesSuccesses),
("testTryCatchWithFunctionThrowingNonAnyErrorCanProducesAnyErrorFailures", testTryCatchWithFunctionThrowingNonAnyErrorCanProducesAnyErrorFailures),
("testTryMapProducesFailure", testTryMapProducesFailure),
("testTryMapProducesSuccess", testTryMapProducesSuccess),
]
}
#if !os(macOS)
public func __allTests() -> [XCTestCaseEntry] {
return [
testCase(AnyErrorTests.__allTests),
testCase(NoErrorTests.__allTests),
testCase(ResultTests.__allTests),
]
}
#endif