Compare commits
No commits in common. "main" and "docc" have entirely different histories.
|
@ -1,34 +0,0 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
container:
|
||||
- 'swift:5.5-focal'
|
||||
container: ${{ matrix.container }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Run tests
|
||||
run: swift test --sanitize=thread
|
||||
macos:
|
||||
runs-on: macos-11
|
||||
strategy:
|
||||
matrix:
|
||||
xcode:
|
||||
- '13.1'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Select Xcode ${{ matrix.xcode }}
|
||||
run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app
|
||||
- name: Run tests
|
||||
run: swift test --sanitize=thread
|
|
@ -1,27 +0,0 @@
|
|||
name: Documentation
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-docs:
|
||||
runs-on: macos-11
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Build docs
|
||||
run: xcodebuild docbuild -scheme "Validations" -destination 'platform=macOS,arch=x86_64' -derivedDataPath ../DerivedData
|
||||
- name: Publish docs
|
||||
run: |
|
||||
git fetch --no-tags --prune --no-recurse-submodules origin docc
|
||||
git switch docc
|
||||
rm -rf docs.doccarchive
|
||||
mv -f ../DerivedData/Build/Products/Debug/Validations.doccarchive docs.doccarchive
|
||||
rm -rf ../DerivedData
|
||||
git add docs.doccarchive
|
||||
git commit -m "Update documentation"
|
||||
git push
|
||||
git switch - || git checkout -
|
21
LICENSE
21
LICENSE
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 Siemen Sikkema
|
||||
|
||||
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.
|
|
@ -1,25 +0,0 @@
|
|||
// swift-tools-version:5.5
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Validations",
|
||||
products: [
|
||||
.library(
|
||||
name: "Validations",
|
||||
targets: ["Validations"]
|
||||
),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/siemensikkema/Decoded.git", from: "0.5.0")
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "Validations",
|
||||
dependencies: ["Decoded"]
|
||||
),
|
||||
.testTarget(
|
||||
name: "ValidationsTests",
|
||||
dependencies: ["Validations"]
|
||||
),
|
||||
]
|
||||
)
|
38
README.md
38
README.md
|
@ -1,38 +0,0 @@
|
|||
# Validations
|
||||
|
||||
[](https://github.com/siemensikkema/Validations/actions/workflows/ci.yml)
|
||||
[](https://swiftpackageindex.com/siemensikkema/Validations)
|
||||
[](https://swiftpackageindex.com/siemensikkema/Validations)
|
||||
|
||||
Type-safe and composable validations with versatile output.
|
||||
|
||||
# Installation
|
||||
|
||||
Add `Validations` to your `Package.swift` file.
|
||||
|
||||
```swift
|
||||
dependencies: [
|
||||
...
|
||||
.package(url: "https://github.com/siemensikkema/Validations.git", from: "0.2.0"),
|
||||
]
|
||||
...
|
||||
targets: [
|
||||
.target(
|
||||
name: "MyTarget",
|
||||
dependencies: [
|
||||
...
|
||||
"Validations",
|
||||
]
|
||||
)
|
||||
]
|
||||
```
|
||||
|
||||
Import `Decoded` and `Validations` to any file you want to use this library in.
|
||||
|
||||
```swift
|
||||
import Decoded
|
||||
import Validations
|
||||
```
|
||||
|
||||
# Documentation
|
||||
This library's documentation is created using [DocC](https://developer.apple.com/documentation/docc) and can be found [here](https://validations.siemensikkema.nl).
|
|
@ -1,15 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
public extension Decoded {
|
||||
func validated() throws -> Validated<T> {
|
||||
try validated(mergingFailures: nil)
|
||||
}
|
||||
|
||||
func validated<V>(by validators: V ...) throws -> Validated<T> where V: ValidatorExpressible, V.T == T {
|
||||
try validated(mergingFailures: Validator(validators)(self))
|
||||
}
|
||||
|
||||
func validated(@ValidatorBuilder<T> buildValidator: () -> Validator<T>) throws -> Validated<T> {
|
||||
try validated(by: buildValidator())
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
struct KeyedFailure {
|
||||
let codingPath: CodingPath
|
||||
let failure: ValidationFailure
|
||||
}
|
||||
|
||||
extension KeyedFailure: KeyedFailuresRepresentable {
|
||||
var keyedFailures: KeyedFailures? {
|
||||
.init(self)
|
||||
}
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
/// Multiple values keyed by `CodingPath`.
|
||||
public struct KeyedValues<T> {
|
||||
/// The dictionary underlying the `KeyedValues` instance.
|
||||
public let value: [CodingPath: [T]]
|
||||
|
||||
private init(_ value: [CodingPath: [T]]) {
|
||||
self.value = value
|
||||
}
|
||||
}
|
||||
|
||||
extension KeyedValues: Encodable where T: Encodable {
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
try container.encode(
|
||||
Dictionary(
|
||||
uniqueKeysWithValues: value
|
||||
.map { codingPath, values in
|
||||
(codingPath.dotPath, values)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an unsuccessful validation with one or more ``ValidationFailure`` values per `CodingPath`.
|
||||
///
|
||||
/// ``KeyedFailures`` provides APIs for making the validation failures presentable (see ``KeyedValues``):
|
||||
/// - `mapFailures(_:)`
|
||||
/// - `mapFailuresWithCodingPath(_:)`
|
||||
///
|
||||
/// As an example, suppose you want to return an error response with error codes for certain failures. You could then define a protocol and conform any ``ValidationFailure`` you want to be associated with an error code:
|
||||
///
|
||||
/// ```swift
|
||||
/// protocol CodedError {
|
||||
/// var errorCode: Int { get }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// A response to represent your error:
|
||||
///
|
||||
/// ```swift
|
||||
/// struct ErrorResponse: Encodable {
|
||||
/// let code: Int?
|
||||
/// let description
|
||||
/// init(failure: ValidationFailure) {
|
||||
/// self.code = (failure as? CodedError)?.errorCode
|
||||
/// self.description = String(describing: failure)
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// And finally, catch the error and map the failures:
|
||||
///
|
||||
/// ```swift
|
||||
/// do {
|
||||
/// let validated = try decoded.validated()
|
||||
/// } catch let failures as KeyedFailures {
|
||||
/// let keyedErrorResponses = failures.mapFailures(ErrorResponse.init)
|
||||
/// ...
|
||||
/// }
|
||||
/// ```
|
||||
public typealias KeyedFailures = KeyedValues<ValidationFailure>
|
||||
|
||||
extension KeyedFailures: Error {}
|
||||
|
||||
extension KeyedFailures {
|
||||
init(codingPath: CodingPath, failure: T) {
|
||||
self.init([codingPath: [failure]])
|
||||
}
|
||||
|
||||
mutating func merge(_ other: KeyedFailuresRepresentable?) {
|
||||
guard let other = other?.keyedFailures else { return }
|
||||
self = .init(value.merging(other.value, uniquingKeysWith: +))
|
||||
}
|
||||
|
||||
/// Transforms the validation failures into new types.
|
||||
///
|
||||
/// - Parameter transform: Closure that transforms each `ValidationFailure` into a new type.
|
||||
/// - Returns: A `KeyedValues` containing the same keys but with transformed values.
|
||||
public func mapFailures<U>(_ transform: (T) -> U) -> KeyedValues<U> {
|
||||
.init(value.mapValuesEach(transform))
|
||||
}
|
||||
|
||||
/// Transforms the validation failures into new types.
|
||||
///
|
||||
/// - Parameter transform: Closure that takes a `CodingPath` and `ValidationFailure` and transforms each failure into a new type.
|
||||
/// - Returns: A `KeyedValues` containing the same keys but with transformed values.
|
||||
public func mapFailuresWithCodingPath<U>(_ transform: (CodingPath, T) -> U) -> KeyedValues<U> {
|
||||
.init(value.mapValuesEachWithKey(transform))
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary where Value: Sequence {
|
||||
func mapValuesEach<T>(_ transform: (Value.Element) -> T) -> [Key: [T]] {
|
||||
mapValues { values in
|
||||
values.map(transform)
|
||||
}
|
||||
}
|
||||
|
||||
func mapValuesEachWithKey<T>(_ transform: (Key, Value.Element) -> T) -> [Key: [T]] {
|
||||
.init(
|
||||
uniqueKeysWithValues: map { key, values in
|
||||
(key, values.map { transform(key, $0) })
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional where Wrapped == KeyedFailures {
|
||||
mutating func merge(_ other: KeyedFailuresRepresentable?) {
|
||||
self = self.merging(other)
|
||||
}
|
||||
}
|
||||
|
||||
extension KeyedFailures {
|
||||
init(_ keyedFailure: KeyedFailure) {
|
||||
self.init(codingPath: keyedFailure.codingPath, failure: keyedFailure.failure)
|
||||
}
|
||||
}
|
||||
|
||||
extension KeyedFailures: KeyedFailuresRepresentable {
|
||||
var keyedFailures: KeyedFailures? {
|
||||
.init(self)
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
protocol KeyedFailuresRepresentable {
|
||||
var keyedFailures: KeyedFailures? { get }
|
||||
}
|
||||
|
||||
extension KeyedFailuresRepresentable {
|
||||
func merging(_ other: KeyedFailuresRepresentable?) -> KeyedFailures? {
|
||||
var copy = keyedFailures
|
||||
copy?.merge(other)
|
||||
return copy ?? other.keyedFailures
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: KeyedFailuresRepresentable where Wrapped: KeyedFailuresRepresentable {
|
||||
var keyedFailures: KeyedFailures? {
|
||||
self?.keyedFailures
|
||||
}
|
||||
}
|
||||
|
||||
extension Decoded: KeyedFailuresRepresentable {
|
||||
var keyedFailures: KeyedFailures? {
|
||||
switch result {
|
||||
case .success(let success):
|
||||
return Mirror(reflecting: success.value).keyedFailures
|
||||
case .failure(let failure):
|
||||
return .init(codingPath: codingPath, failure: failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Mirror {
|
||||
var keyedFailures: KeyedFailures? {
|
||||
children.reduce(into: nil) { keyedFailures, child in
|
||||
keyedFailures.merge(child.value as? KeyedFailuresRepresentable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional where Wrapped == KeyedFailuresRepresentable {
|
||||
var keyedFailures: KeyedFailures? {
|
||||
flatMap(\.keyedFailures)
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
/// The result of a successful decoding attempt together with its `CodingPath`.
|
||||
public struct KeyedSuccess<T> {
|
||||
public let codingPath: CodingPath
|
||||
public let success: DecodingSuccess<T>
|
||||
}
|
||||
|
||||
extension KeyedSuccess {
|
||||
var value: T {
|
||||
success.value
|
||||
}
|
||||
}
|
||||
|
||||
extension Decoded {
|
||||
var keyedSuccess: KeyedSuccess<T>? {
|
||||
result.success.map { KeyedSuccess(codingPath: codingPath, success: $0) }
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
struct PartialRangeAfter<Bound> where Bound: Comparable {
|
||||
let lowerBound: Bound
|
||||
|
||||
init(_ lowerBound: Bound) {
|
||||
self.lowerBound = lowerBound
|
||||
}
|
||||
}
|
||||
|
||||
extension PartialRangeAfter: RangeExpression {
|
||||
func relative<C>(to collection: C) -> Range<Bound> where C : Collection, Bound == C.Index {
|
||||
collection.index(after: lowerBound)..<collection.endIndex
|
||||
}
|
||||
|
||||
func contains(_ element: Bound) -> Bool {
|
||||
lowerBound < element
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
/// A proxy for a successfully decoded and validated value.
|
||||
///
|
||||
/// A `Validated` value can only be created by calling `validate` on a `Decoded` value free from decoding and validation errors.
|
||||
/// This proxy provides convenient access to the underlying value through the use of `@dynamicMemberLookup`.
|
||||
///
|
||||
/// ```swift
|
||||
/// struct Package: Decodable {
|
||||
/// let contents: Int
|
||||
/// }
|
||||
///
|
||||
/// let validatedPackage: Validated<Package> = ...
|
||||
///
|
||||
/// // direct access to `contents`! (when the type is known)
|
||||
/// let validatedContents: Int = validatedPackage.contents
|
||||
/// ```
|
||||
///
|
||||
/// Direct access also works for nested objects, sequences, and dictionaries.
|
||||
@dynamicMemberLookup
|
||||
public struct Validated<T> {
|
||||
let decoded: Decoded<T>
|
||||
|
||||
fileprivate init(_ decoded: Decoded<T>) throws {
|
||||
self.decoded = decoded
|
||||
}
|
||||
}
|
||||
|
||||
public extension Validated {
|
||||
/// Unwraps the validated value.
|
||||
var unwrapped: T {
|
||||
try! decoded.unwrapped
|
||||
}
|
||||
|
||||
subscript<U>(dynamicMember keyPath: KeyPath<T, U>) -> U {
|
||||
unwrapped[keyPath: keyPath]
|
||||
}
|
||||
|
||||
subscript<U>(dynamicMember keyPath: KeyPath<T, Decoded<U>>) -> Validated<U> {
|
||||
try! .init(unwrapped[keyPath: keyPath])
|
||||
}
|
||||
|
||||
subscript<U>(dynamicMember keyPath: KeyPath<T, Decoded<U>>) -> U {
|
||||
unwrapped[keyPath: keyPath].value!
|
||||
}
|
||||
|
||||
subscript<U>(dynamicMember keyPath: KeyPath<T, Decoded<U>?>) -> Validated<U>? {
|
||||
try! unwrapped[keyPath: keyPath].map(Validated<U>.init)
|
||||
}
|
||||
|
||||
subscript<U>(dynamicMember keyPath: KeyPath<T, Decoded<U>?>) -> U? {
|
||||
unwrapped[keyPath: keyPath]?.value!
|
||||
}
|
||||
}
|
||||
|
||||
public extension Validated where T: Sequence, T.Element: Unwrappable {
|
||||
/// Unwraps the elements of the sequence of `Decoded` values as an `Array` of pure values.
|
||||
var unwrapped: [T.Element.Unwrapped] {
|
||||
try! unwrapped.unwrapped
|
||||
}
|
||||
}
|
||||
|
||||
public extension Validated where T: Unwrappable {
|
||||
/// Unwraps the validated value as defined by its type.
|
||||
var unwrapped: T.Unwrapped {
|
||||
try! unwrapped.unwrapped
|
||||
}
|
||||
}
|
||||
|
||||
extension Decoded {
|
||||
func validated(mergingFailures additional: KeyedFailuresRepresentable?) throws -> Validated<T> {
|
||||
if let keyedFailures = keyedFailures.merging(additional) {
|
||||
throw keyedFailures
|
||||
}
|
||||
|
||||
return try .init(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension Validated: Decodable where T: Decodable {
|
||||
/// Provides a shorthand for decoding and validating a type with one statement.
|
||||
/// - Parameter decoder: The decoder to read data from.
|
||||
public init(from decoder: Decoder) throws {
|
||||
self = try Decoded<T>(from: decoder).validated()
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
/// Enables conforming types to represent a single validation failure.
|
||||
public protocol ValidationFailure {}
|
||||
|
||||
extension DecodingFailure: ValidationFailure {}
|
|
@ -1,159 +0,0 @@
|
|||
# Defining Validations
|
||||
|
||||
Define the validation rules that your data should adhere to.
|
||||
|
||||
We will use a fictional reset password feature as an example since it enables us to explore various interesting aspects of validation.
|
||||
|
||||
Consider the following input:
|
||||
|
||||
```swift
|
||||
let payload: Data = """
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"password": "insecure",
|
||||
"newPassword": "insecure2"
|
||||
"confirmation": "insecure2"
|
||||
}
|
||||
""".data(using: .utf8)!
|
||||
```
|
||||
|
||||
There are several preconditions that the payload needs to meet before we can accept the input and change the user's password, including:
|
||||
1. all fields are present and of the correct type
|
||||
2. `newPassword` contains a strong enough password
|
||||
3. `confirmation` equals the value of the `newPassword`
|
||||
4. `password` matches the current password of the user with the given email address
|
||||
|
||||
More generally these correspond to validating ...
|
||||
1. the structure
|
||||
2. a single field
|
||||
3. a relationship between fields
|
||||
4. against an external state
|
||||
|
||||
> Warning: This example is chosen to highlight `Validations`' features and not intended to be a best practice for building a password reset implementation.
|
||||
|
||||
## Representing the payload
|
||||
|
||||
Traditionally we'd represent a payload like the above as follows:
|
||||
|
||||
```swift
|
||||
struct ResetPasswordRequest: Decodable { // ❌
|
||||
let email: String
|
||||
let password: String
|
||||
let newPassword: String
|
||||
let confirmation: String
|
||||
}
|
||||
```
|
||||
|
||||
Defining the payload like this would cause decoding to fail on the first mismatch between the input and the type.
|
||||
|
||||
> One could define the fields as `Optional` which would prevent decoding to fail on missing or `null` values but that would not convey the intended structure. Moreover, it would still fail if a field would be present but of the wrong type, say an `Int` instead of a `String`.
|
||||
|
||||
By wrapping the fields with `Decoded` we can capture any and all mismatches while still expressing the proper structure.
|
||||
|
||||
```swift
|
||||
struct ResetPasswordRequest: Decodable {
|
||||
let email: Decoded<String>
|
||||
let password: Decoded<String>
|
||||
let newPassword: Decoded<String>
|
||||
let confirmation: Decoded<String>
|
||||
}
|
||||
```
|
||||
|
||||
Now we're ready to decode the input.
|
||||
|
||||
```swift
|
||||
let decoder = JSONDecoder()
|
||||
let request = try decoder.decode(Decoded<ResetPasswordRequest>.self,
|
||||
from: payload)
|
||||
```
|
||||
|
||||
> Important: Note again the presence of the `Decoded` wrapper – this time involving our custom type. This allows us to capture top-level decoding errors (eg. trying to decode a `String` instead of the expected object) but more importantly it provides access to the validation APIs.
|
||||
|
||||
> Despite wrapping our fields in `Decoded` the decoding operation can still throw. Errors that can still occur include those due to malformed input (eg. `JSON` with syntax errors) and the possible presence of any non-`Decoded` fields.
|
||||
|
||||
## Validating the payload
|
||||
|
||||
Let's go through the preconditions listed above and see how to express them in `Validations`.
|
||||
|
||||
### 1. Validating the structure
|
||||
|
||||
If we just want to validate that the _structure_ of our input is correct, validation involves a single operation:
|
||||
|
||||
```swift
|
||||
let validated = try request.validated() // Validated<ResetPasswordRequest>
|
||||
```
|
||||
|
||||
> See ``Validated`` on how to use the values in the (now validated) payload and ``KeyedFailures`` on how to handle any resulting validation failures.
|
||||
|
||||
### 2. Validating a single field
|
||||
|
||||
Additional validations can be expressed using a special syntax powered by result builders.
|
||||
|
||||
```swift
|
||||
let validated = try request.validated {
|
||||
\.newPassword.count >= 8
|
||||
}
|
||||
```
|
||||
|
||||
The new validation will fail if `newPassword` is present and of the correct type but its `count` is less than eight characters.
|
||||
|
||||
> See ``Validator`` for available validations.
|
||||
|
||||
### 3. Validating a relationship between fields
|
||||
|
||||
Besides validations involving fields and values it is also possible to validate a relationship _between_ fields.
|
||||
|
||||
```swift
|
||||
\.confirmation == \.newPassword
|
||||
```
|
||||
|
||||
### 4. Validating against external state
|
||||
|
||||
Suppose we have a credential verification function that can verify that a password is valid for a user with an email address.
|
||||
|
||||
```swift
|
||||
func verifyCredentials(email: String?,
|
||||
password: String?) async -> ValidationFailure? {
|
||||
// verify credentials
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
If both email and password have non-nil values, the function performs a database lookup for the user and verifies the password against the stored hashed password. If the password does not match or if no user with the email address could not be found, some ``ValidationFailure`` is returned.
|
||||
|
||||
As the function is marked as `async` it cannot be used directly inside the validation builder. We can deal with this by verifying the password first and using the result when building the validator.
|
||||
|
||||
```swift
|
||||
let credentialFailure = await verifyCredentials(email: payload.email.value,
|
||||
password: payload.password.value)
|
||||
|
||||
let validated = try payload.validated {
|
||||
\.newPassword.count > 8
|
||||
\.confirmation == \.newPassword
|
||||
|
||||
if let failure = credentialFailure {
|
||||
Validator(nestedAt: \.email, failure: failure)
|
||||
}
|
||||
}
|
||||
```
|
||||
> We're associating the failure with the _email_ field. The failure could indicate either an incorrect email address or an incorrect password and we don't want to give any hints to potential bad actors.
|
||||
|
||||
An alternative way to approach this would be to split the validation into two validators and combining them at the validation step.
|
||||
|
||||
```swift
|
||||
let payloadValidator = Validator<ResetPasswordPayload> {
|
||||
\.newPassword.count > 8
|
||||
\.confirmation == \.newPassword
|
||||
}
|
||||
|
||||
let credentialFailure = await verifyCredentials(email: payload.email.value,
|
||||
password: payload.password.value)
|
||||
|
||||
let credentialValidator = Validator<ResetPasswordPayload> {
|
||||
if let failure = credentialFailure {
|
||||
Validator(nestedAt: \.email, failure: failure)
|
||||
}
|
||||
}
|
||||
|
||||
let validated = try payload.validated(by: payloadValidator, credentialValidator)
|
||||
```
|
|
@ -1,41 +0,0 @@
|
|||
# ``Validations``
|
||||
|
||||
Type-safe and composable validations with versatile output.
|
||||
|
||||
## Overview
|
||||
|
||||
Validating that data follows certain rules is relevant in situations where end-users or other services submit data to your application.
|
||||
|
||||
The aim of this library is to enable you to express such validation rules in a type-safe and flexible manner while making it possible to collect all failures at once and have full flexibility over how any violations of the rules are presented.
|
||||
|
||||
This library builds on the `Decoded` library to take advantage of its ability to collect any and all error states during the decoding process as opposed to failing on the first error. This makes it possible to combine _structural_ decoding related errors with _semantic_ failures as defined by validation rules in a single pass.
|
||||
|
||||
``Validator`` values can be passed around and combined as needed before performing the actual validation. This enables you, among other things, to combine validations that require asynchronicity with those that don't.
|
||||
|
||||
Once validated successfully, the resulting ``Validated`` structure yields access to the now validated input almost as if you were interacting with a plain decoded value through the use of `dynamicMemberLookup`.
|
||||
|
||||
If the validation was not successful, an error of type ``KeyedFailures`` will be thrown which contains one or more ``ValidationFailure`` values per offending `CodingPath`. These can be transformed before presenting them to the sender in order to do things like localization.
|
||||
|
||||
|
||||
## Topics
|
||||
|
||||
### Validating input
|
||||
|
||||
- <doc:Defining-Validations>
|
||||
|
||||
### Using the validated output
|
||||
|
||||
- ``Validated``
|
||||
|
||||
### Customizing error output
|
||||
|
||||
- ``KeyedFailures``
|
||||
|
||||
### Built-in Validators
|
||||
|
||||
- ``InRange``
|
||||
- ``IsAbsent``
|
||||
- ``IsEqual``
|
||||
- ``IsNil``
|
||||
- ``IsNotEqual``
|
||||
- ``ValidEmail``
|
|
@ -1,214 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
/// Able to validate a `Decoded<T>` value.
|
||||
///
|
||||
/// As the basic building block for Validations, ``Validator`` values can be composed with others to form arbitrarily complex validators.
|
||||
public struct Validator<T> {
|
||||
typealias Validate = (Decoded<T>) -> KeyedFailuresRepresentable?
|
||||
|
||||
let validate: Validate
|
||||
|
||||
init(validate: @escaping Validate) {
|
||||
self.validate = validate
|
||||
}
|
||||
|
||||
/// A ``Validator`` that always succeeds.
|
||||
public static var empty: Self {
|
||||
.init { (_: Decoded<T>) in nil }
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Initializers
|
||||
|
||||
// MARK: ValidatorBuilder
|
||||
|
||||
public extension Validator {
|
||||
/// Creates a new ``Validator`` using a result builder closure.
|
||||
init(@ValidatorBuilder<T> buildValidator: @escaping () -> Self) {
|
||||
self = buildValidator()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Combining Validators
|
||||
|
||||
public extension Validator {
|
||||
/// Creates a new ``Validator`` from others with the combined validation output.
|
||||
init<V>(_ validators: [V]) where V: ValidatorExpressible, V.T == T {
|
||||
self.init { decoded in
|
||||
validators.reduce(into: nil) { (partialResult: inout KeyedFailures?, validator) in
|
||||
partialResult.merge(validator(decoded))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new ``Validator`` from others with the combined validation output.
|
||||
init<V>(_ validators: V ...) where V: ValidatorExpressible, V.T == T {
|
||||
self.init(validators)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Top-level Validators
|
||||
public extension Validator {
|
||||
/// Creates a new ``Validator`` for a successfully decoded value.
|
||||
init(validate: @escaping (KeyedSuccess<T>) -> ValidationFailure?) {
|
||||
self.init(pathToSuccess: \.keyedSuccess) { _, success in validate(success) }
|
||||
}
|
||||
|
||||
/// Creates a new ``Validator`` for a successfully decoded value.
|
||||
init(validate: @escaping (T) -> ValidationFailure?) {
|
||||
self.init { success in
|
||||
validate(success.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Single-field Validators
|
||||
public extension Validator {
|
||||
/// Creates a new ``Validator`` for a successfully decoded field.
|
||||
init<U>(
|
||||
_ keyPath: KeyPath<T, Decoded<U>>,
|
||||
validate: @escaping (KeyedSuccess<U>) -> ValidationFailure?
|
||||
) {
|
||||
self.init { decoded in
|
||||
decoded.flatMap(keyPath).keyedSuccess
|
||||
} validate: { _, success in
|
||||
validate(success)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new ``Validator`` for a successfully decoded field.
|
||||
init<U>(
|
||||
_ keyPath: KeyPath<T, Decoded<U>>,
|
||||
validate: @escaping (U) -> ValidationFailure?
|
||||
) {
|
||||
self.init(keyPath) { success in
|
||||
validate(success.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Two-field Validators
|
||||
public extension Validator {
|
||||
/// Creates a new ``Validator`` for two successfully decoded fields.
|
||||
init<U, V>(
|
||||
_ keyPath1: KeyPath<T, Decoded<U>>,
|
||||
_ keyPath2: KeyPath<T, Decoded<V>>,
|
||||
validate: @escaping (KeyedSuccess<U>, KeyedSuccess<V>) -> ValidationFailure?
|
||||
) {
|
||||
self.init { decoded in
|
||||
decoded.keyedSuccess.flatMap { $0.value[keyPath: keyPath1].keyedSuccess }
|
||||
} validate: { decoded1, success1 -> ValidationFailure? in
|
||||
decoded1
|
||||
.flatMap(keyPath2)
|
||||
.keyedSuccess
|
||||
.flatMap { success2 in
|
||||
validate(success1, success2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new ``Validator`` for two successfully decoded fields.
|
||||
init<U, V>(
|
||||
_ keyPath1: KeyPath<T, Decoded<U>>,
|
||||
_ keyPath2: KeyPath<T, Decoded<V>>,
|
||||
validate: @escaping (U, V) -> ValidationFailure?
|
||||
) {
|
||||
self.init(keyPath1, keyPath2) { success1, success2 in
|
||||
validate(success1.value, success2.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Value inspecting Validators
|
||||
public extension Validator {
|
||||
/// Creates a new ``Validator`` based on the value of a successfully decoded field.
|
||||
init<U>(
|
||||
withValueAt keyPath: KeyPath<T, Decoded<U>>,
|
||||
@ValidatorBuilder<T> buildValidator: @escaping (KeyedSuccess<U>) -> Self
|
||||
) {
|
||||
self.init { decoded in
|
||||
decoded
|
||||
.flatMap(keyPath)
|
||||
.keyedSuccess
|
||||
.flatMap(buildValidator)?(decoded)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new ``Validator`` based on the value of a successfully decoded field.
|
||||
init<U>(
|
||||
withValueAt keyPath: KeyPath<T, Decoded<U>>,
|
||||
@ValidatorBuilder<T> buildValidator: @escaping (U) -> Self
|
||||
) {
|
||||
self.init(withValueAt: keyPath, buildValidator: {
|
||||
buildValidator($0.value)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Nested Validators
|
||||
public extension Validator {
|
||||
/// Creates a new ``Validator`` nested at a field.
|
||||
init<U>(
|
||||
nestedAt keyPath: KeyPath<T, Decoded<U>>,
|
||||
validator: Validator<U>
|
||||
) {
|
||||
self.init { (decoded: Decoded<T>) in
|
||||
let nested = decoded.flatMap(keyPath)
|
||||
|
||||
guard nested.result.success != nil else { return nil }
|
||||
|
||||
return validator(nested)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new ``Validator`` nested at a field.
|
||||
init<U>(
|
||||
nestedAt keyPath: KeyPath<T, Decoded<U>>,
|
||||
@ValidatorBuilder<U> buildValidator: @escaping () -> Validator<U>
|
||||
) {
|
||||
self.init(nestedAt: keyPath, validator: buildValidator())
|
||||
}
|
||||
|
||||
/// Creates a new ``Validator`` nested at a field that always fails with the provided failure.
|
||||
init<U>(
|
||||
nestedAt keyPath: KeyPath<T, Decoded<U>>,
|
||||
failure: ValidationFailure
|
||||
) {
|
||||
self.init(keyPath) { (_: KeyedSuccess<U>) in failure }
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ValidatorExpressible
|
||||
|
||||
extension Validator: ValidatorExpressible {
|
||||
public var validator: Self { self }
|
||||
}
|
||||
|
||||
public extension ValidatorExpressible {
|
||||
/// Map any failure resulting from the validation to a new ``ValidationFailure``.
|
||||
///
|
||||
/// - Parameter transform: Function that transforms a ``ValidationFailure``.
|
||||
/// - Returns: A new ``Validator``.
|
||||
func mapFailures(_ transform: @escaping (ValidationFailure) -> ValidationFailure) -> Validator<T> {
|
||||
.init { decoded in
|
||||
validator(decoded)?.keyedFailures?.mapFailures(transform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private extension Validator {
|
||||
init<U>(
|
||||
pathToSuccess: @escaping (Decoded<T>) -> KeyedSuccess<U>?,
|
||||
validate: @escaping (Decoded<T>, KeyedSuccess<U>) -> ValidationFailure?
|
||||
) {
|
||||
self.init { decoded in
|
||||
pathToSuccess(decoded).flatMap { success in
|
||||
validate(decoded, success).map {
|
||||
KeyedFailure(codingPath: success.codingPath, failure: $0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
@resultBuilder
|
||||
public struct ValidatorBuilder<T> {
|
||||
public static func buildBlock<V>(_ validators: V...) -> Validator<T>
|
||||
where V: ValidatorExpressible, V.T == T
|
||||
{
|
||||
.init(validators)
|
||||
}
|
||||
|
||||
public static func buildOptional(_ validator: Validator<T>?) -> Validator<T>
|
||||
{
|
||||
.init { decoded in
|
||||
validator?(decoded)
|
||||
}
|
||||
}
|
||||
|
||||
public static func buildOptional<V>(_ validator: V?) -> Validator<T>
|
||||
where V: ValidatorExpressible, V.T == T
|
||||
{
|
||||
.init { decoded in
|
||||
validator?(decoded)
|
||||
}
|
||||
}
|
||||
|
||||
public static func buildEither<V>(first validator: V) -> Validator<T>
|
||||
where V: ValidatorExpressible, V.T == T
|
||||
{
|
||||
validator.validator
|
||||
}
|
||||
|
||||
public static func buildEither<V>(second validator: V) -> Validator<T>
|
||||
where V: ValidatorExpressible, V.T == T
|
||||
{
|
||||
validator.validator
|
||||
}
|
||||
|
||||
public static func buildExpression(_ validator: Validator<T>) -> Validator<T> {
|
||||
validator
|
||||
}
|
||||
|
||||
public static func buildExpression<V>(_ validator: V) -> Validator<T>
|
||||
where V: ValidatorExpressible, V.T == T
|
||||
{
|
||||
validator.validator
|
||||
}
|
||||
|
||||
public static func buildLimitedAvailability<V>(_ validator: V) -> Validator<T>
|
||||
where V: ValidatorExpressible, V.T == T
|
||||
{
|
||||
validator.validator
|
||||
}
|
||||
|
||||
public static func buildArray<V>(_ validators: [V]) -> Validator<T>
|
||||
where V: ValidatorExpressible, V.T == T
|
||||
{
|
||||
.init(validators)
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
/// Types that are able to provide a ``Validator``.
|
||||
///
|
||||
/// By conforming to this protocol you can define your own custom validators.
|
||||
public protocol ValidatorExpressible {
|
||||
associatedtype T
|
||||
/// The ``Validator`` that the conforming type exposes.
|
||||
var validator: Validator<T> { get }
|
||||
}
|
||||
|
||||
extension ValidatorExpressible {
|
||||
func callAsFunction(_ decoded: Decoded<T>) -> KeyedFailuresRepresentable? {
|
||||
validator.validate(decoded)
|
||||
}
|
||||
}
|
||||
|
||||
public extension ValidatorExpressible {
|
||||
/// Produces a new ``Validator`` by combining `self` with another validator using "and" logic.
|
||||
///
|
||||
/// The resulting validator fails if either of the validators fail. Failures from both validators are combined.
|
||||
/// - Parameter other: A ``Validator`` to combine with `self`.
|
||||
/// - Returns: A new ``Validator``.
|
||||
func and<V>(_ other: V) -> Validator<T> where V: ValidatorExpressible, V.T == T {
|
||||
.init(self.validator, other.validator)
|
||||
}
|
||||
|
||||
/// Produces a new ``Validator`` by combining `self` with another validator using "or" logic.
|
||||
///
|
||||
/// The resulting validator only fails if **both** validators fail. Failures from both validators are combined.
|
||||
/// - Parameter other: A ``Validator`` to combine with `self`.
|
||||
/// - Returns: A new ``Validator``.
|
||||
func or<V>(_ other: V) -> Validator<T> where V: ValidatorExpressible, V.T == T {
|
||||
.init { decoded -> KeyedFailuresRepresentable? in
|
||||
guard
|
||||
let lhs = validator(decoded),
|
||||
let rhs = other.validator(decoded)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
return lhs.merging(rhs)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
public struct InRange<T>: ValidatorExpressible {
|
||||
public struct Failure<R: RangeExpression>: ValidationFailure {
|
||||
public let value: R.Bound
|
||||
public let range: R
|
||||
|
||||
init?(_ value: R.Bound, _ range: R) {
|
||||
guard !range.contains(value) else {
|
||||
return nil
|
||||
}
|
||||
self.value = value
|
||||
self.range = range
|
||||
}
|
||||
}
|
||||
|
||||
public let validator: Validator<T>
|
||||
|
||||
public init<R: RangeExpression>(_ keyPath: KeyPath<T, Decoded<R.Bound>>, _ range: R) {
|
||||
self.validator = .init(keyPath) { Failure($0.value, range) }
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
public struct IsAbsent<T>: ValidatorExpressible {
|
||||
public enum Failure: ValidationFailure {
|
||||
case hasValue, isNil
|
||||
|
||||
init?<U>(_ success: DecodingSuccess<U>) {
|
||||
switch success {
|
||||
case .nil:
|
||||
self = .isNil
|
||||
case .value:
|
||||
self = .hasValue
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public let validator: Validator<T>
|
||||
|
||||
public init<U>(_ keyPath: KeyPath<T, Decoded<U>>) {
|
||||
self.validator = .init(keyPath) { Failure($0.success) }
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
public struct IsEqual<T>: ValidatorExpressible {
|
||||
public struct Failure<U: Equatable>: ValidationFailure {
|
||||
public let lhs, rhs: U
|
||||
public let codingPath: CodingPath?
|
||||
|
||||
init?(_ lhs: U, _ rhs: U, codingPath: CodingPath? = nil) {
|
||||
guard lhs != rhs else {
|
||||
return nil
|
||||
}
|
||||
self.codingPath = codingPath
|
||||
self.lhs = lhs
|
||||
self.rhs = rhs
|
||||
}
|
||||
}
|
||||
|
||||
public let validator: Validator<T>
|
||||
|
||||
public init<U: Equatable>(_ keyPath: KeyPath<T, Decoded<U>>, _ rhs: U) {
|
||||
self.validator = .init(keyPath) { Failure($0.value, rhs) }
|
||||
}
|
||||
|
||||
public init<U: Equatable>(_ keyPath1: KeyPath<T, Decoded<U>>, _ keyPath2: KeyPath<T, Decoded<U>>) {
|
||||
self.validator = .init(keyPath1, keyPath2) { Failure($0.value, $1.value, codingPath: $1.codingPath) }
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
public struct IsNil<T>: ValidatorExpressible {
|
||||
public enum Failure: ValidationFailure {
|
||||
case hasValue, isAbsent
|
||||
|
||||
init?<U>(_ success: DecodingSuccess<U>) {
|
||||
switch success {
|
||||
case .absent:
|
||||
self = .isAbsent
|
||||
case .value:
|
||||
self = .hasValue
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public let validator: Validator<T>
|
||||
|
||||
public init<U>(_ keyPath: KeyPath<T, Decoded<U>>) {
|
||||
self.validator = .init(keyPath) { Failure($0.success) }
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
public struct IsNotEqual<T>: ValidatorExpressible {
|
||||
public struct Failure<U: Equatable>: ValidationFailure {
|
||||
public let value: U
|
||||
public let codingPath: CodingPath?
|
||||
|
||||
init?(_ lhs: U, _ rhs: U, codingPath: CodingPath? = nil) {
|
||||
guard lhs == rhs else {
|
||||
return nil
|
||||
}
|
||||
self.codingPath = codingPath
|
||||
self.value = rhs
|
||||
}
|
||||
}
|
||||
|
||||
public let validator: Validator<T>
|
||||
|
||||
public init<U: Equatable>(_ keyPath: KeyPath<T, Decoded<U>>, _ rhs: U) {
|
||||
self.validator = .init(keyPath) { Failure($0.value, rhs) }
|
||||
}
|
||||
|
||||
public init<U: Equatable>(_ keyPath1: KeyPath<T, Decoded<U>>, _ keyPath2: KeyPath<T, Decoded<U>>) {
|
||||
self.validator = .init(keyPath1, keyPath2) { Failure($0.value, $1.value, codingPath: $1.codingPath) }
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
public struct ValidEmail<T>: ValidatorExpressible {
|
||||
public struct Failure: ValidationFailure {
|
||||
init?(email: String) {
|
||||
// FIXME: this is a proof of concept implementation
|
||||
guard !email.contains("@") else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public let validator: Validator<T>
|
||||
|
||||
public init(_ keyPath: KeyPath<T, Decoded<String>>) {
|
||||
self.validator = .init(keyPath) { Failure(email: $0.value) }
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
import Decoded
|
||||
|
||||
public func == <T, U: Equatable>(keyPath: KeyPath<T, Decoded<U>>, rhs: U) -> IsEqual<T> {
|
||||
.init(keyPath, rhs)
|
||||
}
|
||||
|
||||
public func != <T, U: Equatable>(keyPath: KeyPath<T, Decoded<U>>, rhs: U) -> IsNotEqual<T> {
|
||||
.init(keyPath, rhs)
|
||||
}
|
||||
|
||||
public func == <T, U: Equatable>(keyPath1: KeyPath<T, Decoded<U>>, keyPath2: KeyPath<T, Decoded<U>>) -> IsEqual<T> {
|
||||
.init(keyPath1, keyPath2)
|
||||
}
|
||||
|
||||
public func != <T, U: Equatable>(keyPath1: KeyPath<T, Decoded<U>>, keyPath2: KeyPath<T, Decoded<U>>) -> IsNotEqual<T> {
|
||||
.init(keyPath1, keyPath2)
|
||||
}
|
||||
|
||||
public func ~= <T, R: RangeExpression>(keyPath1: KeyPath<T, Decoded<R.Bound>>, range: R) -> InRange<T> {
|
||||
.init(keyPath1, range)
|
||||
}
|
||||
|
||||
public func < <T, U: Comparable & AdditiveArithmetic>(keyPath1: KeyPath<T, Decoded<U>>, upperBound: U) -> InRange<T> {
|
||||
keyPath1 ~= ..<upperBound
|
||||
}
|
||||
|
||||
public func > <T, U: Comparable & AdditiveArithmetic>(keyPath1: KeyPath<T, Decoded<U>>, lowerBound: U) -> InRange<T> {
|
||||
keyPath1 ~= PartialRangeAfter(lowerBound)
|
||||
}
|
||||
|
||||
public func <= <T, U: Comparable & AdditiveArithmetic>(keyPath1: KeyPath<T, Decoded<U>>, upperBound: U) -> InRange<T> {
|
||||
keyPath1 ~= ...upperBound
|
||||
}
|
||||
|
||||
public func >= <T, U: Comparable & AdditiveArithmetic>(keyPath1: KeyPath<T, Decoded<U>>, lowerBound: U) -> InRange<T> {
|
||||
keyPath1 ~= lowerBound...
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
import Decoded
|
||||
import XCTest
|
||||
import Validations
|
||||
|
||||
final class KeyedFailuresTests: ValidationsTestCase {
|
||||
func test_annotatingFailuresWithErrorCodes() throws {
|
||||
do {
|
||||
let decoded: Decoded<Post> = try decode("""
|
||||
{
|
||||
"title": "My title",
|
||||
"body": "invalid"
|
||||
}
|
||||
""")
|
||||
|
||||
// fail the validation on purpose
|
||||
_ = try decoded.validated {
|
||||
Validator(nestedAt: \.title, failure: Failure1())
|
||||
Validator(nestedAt: \.body, failure: Failure2())
|
||||
}
|
||||
} catch let failures as KeyedFailures {
|
||||
let errorOutput = failures.mapFailures(FailureWithCode.init)
|
||||
|
||||
// encode mapped failures and decode as a dictionary so we can compare with the expected outcome
|
||||
let data = try JSONEncoder().encode(errorOutput)
|
||||
let dict = try JSONDecoder().decode([String: [FailureWithCode]].self, from: data)
|
||||
|
||||
XCTAssertEqual(dict, [
|
||||
"title": [FailureWithCode(description: "failure1", code: 1)],
|
||||
"body": [FailureWithCode(description: "failure2", code: nil)]
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate protocol CodedError {
|
||||
var errorCode: Int { get }
|
||||
}
|
||||
|
||||
fileprivate struct FailureWithCode: Codable, Equatable {
|
||||
let description: String
|
||||
let code: Int?
|
||||
}
|
||||
|
||||
extension FailureWithCode {
|
||||
init(failure: ValidationFailure) {
|
||||
self.code = (failure as? CodedError)?.errorCode
|
||||
self.description = String(describing: failure)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate struct Failure1: ValidationFailure, CodedError, CustomStringConvertible {
|
||||
let description = "failure1"
|
||||
let errorCode = 1
|
||||
}
|
||||
|
||||
fileprivate struct Failure2: ValidationFailure, CustomStringConvertible {
|
||||
let description = "failure2"
|
||||
}
|
||||
|
||||
fileprivate struct Post: Decodable {
|
||||
let title: Decoded<String>
|
||||
let body: Decoded<String>
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
import Decoded
|
||||
import Validations
|
||||
import XCTest
|
||||
|
||||
final class ValidatedTests: ValidationsTestCase {
|
||||
func test_singleValue() throws {
|
||||
let decoded: Decoded<Int> = try decode("0")
|
||||
let validated = try decoded.validated()
|
||||
XCTAssertEqual(validated.unwrapped, 0)
|
||||
}
|
||||
|
||||
func test_directPropertyAccess() throws {
|
||||
struct Gadget: Decodable {
|
||||
var name: Decoded<String>
|
||||
}
|
||||
|
||||
let decoded: Decoded<Gadget> = try decode(#"{"name":"arduino"}"#)
|
||||
let validated = try decoded.validated()
|
||||
XCTAssertEqual(validated.name, "arduino")
|
||||
}
|
||||
|
||||
func test_directPropertyAccess_nested() throws {
|
||||
struct CarRequest: Decodable {
|
||||
struct Engine: Decodable {
|
||||
var cylinderVolume: Decoded<Double>
|
||||
}
|
||||
var engine: Decoded<Engine>
|
||||
}
|
||||
|
||||
let decoded: Decoded<CarRequest> = try decode(#"{"engine":{"cylinderVolume": 0.9}}"#)
|
||||
let validated = try decoded.validated()
|
||||
XCTAssertEqual(validated.engine.cylinderVolume, 0.9)
|
||||
}
|
||||
|
||||
func test_checkingFailedDecodingThrowsError() throws {
|
||||
let decoded: Decoded<String> = try decode("0")
|
||||
|
||||
XCTAssertThrowsError(try decoded.validated()) { error in
|
||||
guard let failures = error as? KeyedFailures else {
|
||||
XCTFail("expected error of type `KeyedFailures`")
|
||||
return
|
||||
}
|
||||
XCTAssertTrue(failures.value.values.first?.first is DecodingFailure)
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests a workaround for the edge case of a payload with `unwrapped` as a key which conflicts with ``Validated.unwrapped``.
|
||||
func test_nameConflictWithUnwrapped() throws {
|
||||
struct Package: Decodable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case _unwrapped = "unwrapped"
|
||||
}
|
||||
var _unwrapped: Decoded<String>
|
||||
}
|
||||
let decoded: Decoded<Package> = try decode(#"{"unwrapped":"NY"}"#)
|
||||
let validated = try decoded.validated()
|
||||
XCTAssertEqual(validated._unwrapped, "NY")
|
||||
XCTAssertEqual(validated._unwrapped.codingPath, ["unwrapped"])
|
||||
}
|
||||
|
||||
func test_directDecoding() throws {
|
||||
let decoded: Validated<Int> = try decode("1")
|
||||
XCTAssertEqual(decoded.unwrapped, 1)
|
||||
}
|
||||
|
||||
func test_array() throws {
|
||||
let validated: Validated<[Decoded<Int>]> = try decode("[1,2,3]")
|
||||
XCTAssertEqual(validated.count, 3)
|
||||
XCTAssertEqual(validated[0], 1)
|
||||
XCTAssertEqual(validated.first, 1)
|
||||
XCTAssertEqual(validated.first?.value, 1)
|
||||
|
||||
XCTAssertEqual(validated.unwrapped, [1,2,3])
|
||||
}
|
||||
|
||||
func test_dictionary() throws {
|
||||
let validated: Validated<[String: Decoded<Int>]> = try decode(#"{"a":1}"#)
|
||||
XCTAssertEqual(validated.count, 1)
|
||||
XCTAssertEqual(validated["a"], 1)
|
||||
|
||||
XCTAssertEqual(validated.unwrapped, ["a": 1])
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
|
||||
class ValidationsTestCase: XCTestCase {
|
||||
private let decoder = JSONDecoder()
|
||||
|
||||
func decode<T: Decodable>(_ string: String, as _: T.Type = T.self) throws -> T {
|
||||
try decoder.decode(T.self, from: string.data(using: .utf8)!)
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
import Decoded
|
||||
import Validations
|
||||
import XCTest
|
||||
|
||||
final class ValidationsTests: ValidationsTestCase {
|
||||
/// Demonstrates how to validate a password reset scenario.
|
||||
func test_passwordReset() throws {
|
||||
struct ResetPasswordPayload: Decodable {
|
||||
let email: Decoded<String>
|
||||
let password: Decoded<String>
|
||||
let newPassword: Decoded<String>
|
||||
let confirmation: Decoded<String>
|
||||
}
|
||||
|
||||
let data = """
|
||||
{
|
||||
"email": "a@b.com",
|
||||
"password": "secret1",
|
||||
"newPassword": "secret2",
|
||||
"confirmation": "secret2"
|
||||
}
|
||||
"""
|
||||
let payload: Decoded<ResetPasswordPayload> = try decode(data)
|
||||
|
||||
// in a real-world scenario, this would be an async call
|
||||
let credentialFailure = verifyCredentials(for: payload.email.value, password: payload.password.value)
|
||||
|
||||
do {
|
||||
let validated = try payload.validated {
|
||||
\.newPassword.count > 8
|
||||
\.confirmation == \.newPassword
|
||||
|
||||
if let failure = credentialFailure {
|
||||
Validator(nestedAt: \.email, failure: failure)
|
||||
}
|
||||
}
|
||||
XCTAssertEqual(validated.newPassword, "secret2")
|
||||
} catch let failures as KeyedFailures {
|
||||
let descriptions = failures.mapFailures(String.init(describing:))
|
||||
|
||||
XCTAssertEqual(descriptions.value, [
|
||||
["email"]: ["Invalid credentials."],
|
||||
["newPassword"]: ["Is not contained in the expected range."]
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate struct InvalidCredentials: CustomStringConvertible, ValidationFailure {
|
||||
let description = "Invalid credentials."
|
||||
}
|
||||
|
||||
fileprivate func verifyCredentials(for email: String?, password: String?) -> ValidationFailure? {
|
||||
guard let _ = email, let _ = password else {
|
||||
return nil
|
||||
}
|
||||
|
||||
// in a real implementation we'd look the credentials for the email and verify the password against the stored hash
|
||||
|
||||
return InvalidCredentials()
|
||||
}
|
||||
|
||||
extension InRange.Failure: CustomStringConvertible {
|
||||
public var description: String {
|
||||
"Is not contained in the expected range."
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
import Decoded
|
||||
import Validations
|
||||
import XCTest
|
||||
|
||||
final class ValidatorTests: ValidationsTestCase {
|
||||
func test_basic_validator_success() throws {
|
||||
let decoded: Decoded<Int> = try decode("0")
|
||||
let validator = Validator<Int> { (value: KeyedSuccess) in
|
||||
nil
|
||||
}
|
||||
XCTAssertNoThrow(try decoded.validated(by: validator))
|
||||
}
|
||||
|
||||
func test_presentable_decoded_errors() throws {
|
||||
struct NonOptionalName: Decodable {
|
||||
let name: Decoded<String>
|
||||
}
|
||||
|
||||
let decoded: Decoded<NonOptionalName> = try decode(#"{"name":null}"#)
|
||||
|
||||
do {
|
||||
_ = try decoded.validated()
|
||||
} catch let failures as KeyedFailures {
|
||||
let descriptions = failures.mapFailures(String.init(describing:))
|
||||
|
||||
#if os(Linux)
|
||||
XCTAssertEqual(descriptions.value, [["name"]: ["Type mismatch."]])
|
||||
#else
|
||||
XCTAssertEqual(descriptions.value, [["name"]: ["Value not found."]])
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
func test_validatorResultBuilder() throws {
|
||||
let decoder = JSONDecoder()
|
||||
let data = """
|
||||
{
|
||||
"name": "a@b.com",
|
||||
"email": "ab.com",
|
||||
"address": {
|
||||
"street": "a",
|
||||
"city": "b",
|
||||
"region": "c",
|
||||
"postcode": "1234"
|
||||
}
|
||||
}
|
||||
""".data(using: .utf8)!
|
||||
|
||||
struct TestFailure: CustomStringConvertible, ValidationFailure {
|
||||
var description: String {
|
||||
"test"
|
||||
}
|
||||
}
|
||||
|
||||
let decoded = try decoder.decode(Decoded<User>.self, from: data)
|
||||
let validator = Validator<User> {
|
||||
\.name == "asd"
|
||||
|
||||
\.address.street == \.name
|
||||
|
||||
ValidEmail(\.email)
|
||||
|
||||
Validator {
|
||||
\.name != \.email
|
||||
}.or(Validator {
|
||||
\.name == "ab@b.com"
|
||||
})
|
||||
|
||||
Validator(withValueAt: \.name) { name in
|
||||
\.email != name
|
||||
}
|
||||
|
||||
Validator(nestedAt: \.address) {
|
||||
\.street == "a"
|
||||
\.line2 == nil
|
||||
IsNil(\.line2)
|
||||
\.city == "b"
|
||||
\.region == "c"
|
||||
\.postcode == "1234"
|
||||
}.mapFailures { _ in TestFailure() }
|
||||
}
|
||||
|
||||
do {
|
||||
let validated = try decoded.validated(by: validator)
|
||||
let name: String = validated.name
|
||||
print(name)
|
||||
} catch let failures as KeyedFailures {
|
||||
let descriptions = failures.mapFailures(String.init(describing:))
|
||||
|
||||
XCTAssertEqual(descriptions.value, [
|
||||
["name"]: ["'a@b.com' does not equal 'asd'."],
|
||||
["address", "street"]: ["'a' does not equal 'a@b.com'."],
|
||||
["email"]: ["Is not a valid email address."],
|
||||
["address", "line2"]: ["test"]
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Address: Decodable {
|
||||
var street: Decoded<String>
|
||||
var line2: Decoded<String?>
|
||||
var city: Decoded<String>
|
||||
var region: Decoded<String>
|
||||
var postcode: Decoded<String>
|
||||
}
|
||||
|
||||
struct User: Decodable {
|
||||
var email: Decoded<String>
|
||||
var name: Decoded<String>
|
||||
var address: Decoded<Address>
|
||||
}
|
||||
|
||||
extension DecodingFailure: CustomStringConvertible {
|
||||
public var description: String {
|
||||
switch self.errorType {
|
||||
case .dataCorrupted:
|
||||
return "Data corrupted."
|
||||
case .keyNotFound:
|
||||
return "Key not found."
|
||||
case .typeMismatch:
|
||||
return "Type mismatch."
|
||||
case .valueNotFound:
|
||||
return "Value not found."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension IsEqual.Failure: CustomStringConvertible {
|
||||
public var description: String {
|
||||
"'\(lhs)' does not equal '\(rhs)'."
|
||||
}
|
||||
}
|
||||
|
||||
extension ValidEmail.Failure: CustomStringConvertible {
|
||||
public var description: String {
|
||||
"Is not a valid email address."
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"T"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"internalParam","text":"keyPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"internalParam","text":"rhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual","preciseIdentifier":"s:11Validations10IsNotEqualV","text":"IsNotEqual"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":"> "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"Equatable","preciseIdentifier":"s:SQ"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/!=(_:_:)-2kxzx"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/!=(_:_:)-2kxzx","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"T"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"IsNotEqual","preciseIdentifier":"s:11Validations10IsNotEqualV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"title":"!=(_:_:)","roleHeading":"Operator","role":"symbol","symbolKind":"op","externalID":"s:11Validations2neoiyAA10IsNotEqualVyxGs7KeyPathCyx7DecodedAHVyq_GG_q_tSQR_r0_lF","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations"]]},"references":{"doc://Validations/documentation/Validations/IsNotEqual":{"role":"symbol","title":"IsNotEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNotEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNotEqual"}],"url":"\/documentation\/validations\/isnotequal"},"doc://Validations/documentation/Validations/!=(_:_:)-2kxzx":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"T"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"IsNotEqual","preciseIdentifier":"s:11Validations10IsNotEqualV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/!=(_:_:)-2kxzx","kind":"symbol","type":"topic","url":"\/documentation\/validations\/!=(_:_:)-2kxzx"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"=="},{"kind":"text","text":" "},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"T"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"internalParam","text":"keyPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"internalParam","text":"rhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual","preciseIdentifier":"s:11Validations7IsEqualV","text":"IsEqual"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":"> "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"Equatable","preciseIdentifier":"s:SQ"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/==(_:_:)-9pd09"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/==(_:_:)-9pd09","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"=="},{"kind":"text","text":" "},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"T"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"IsEqual","preciseIdentifier":"s:11Validations7IsEqualV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"title":"==(_:_:)","roleHeading":"Operator","role":"symbol","symbolKind":"op","externalID":"s:11Validations2eeoiyAA7IsEqualVyxGs7KeyPathCyx7DecodedAHVyq_GG_q_tSQR_r0_lF","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations"]]},"references":{"doc://Validations/documentation/Validations/==(_:_:)-9pd09":{"role":"symbol","title":"==(_:_:)","fragments":[{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"=="},{"kind":"text","text":" "},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"T"},{"kind":"text","text":", "},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"IsEqual","preciseIdentifier":"s:11Validations7IsEqualV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/==(_:_:)-9pd09","kind":"symbol","type":"topic","url":"\/documentation\/validations\/==(_:_:)-9pd09"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsEqual":{"role":"symbol","title":"IsEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsEqual"}],"url":"\/documentation\/validations\/isequal"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"R"},{"kind":"text","text":"> "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"RangeExpression","preciseIdentifier":"s:SX"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/inrange\/failure"],"traits":[{"interfaceLanguage":"swift"}]}],"relationshipsSections":[{"identifiers":["doc:\/\/Validations\/documentation\/Validations\/ValidationFailure"],"kind":"relationships","title":"Conforms To","type":"conformsTo"}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"title":"InRange.Failure","roleHeading":"Structure","role":"symbol","symbolKind":"struct","externalID":"s:11Validations7InRangeV7FailureV","modules":[{"name":"Validations"}],"navigatorTitle":[{"kind":"identifier","text":"Failure"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/InRange"]]},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure\/range","doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure\/value"]}],"references":{"doc://Validations/documentation/Validations/ValidationFailure":{"role":"symbol","title":"ValidationFailure","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"ValidationFailure"}],"abstract":[{"type":"text","text":"Enables conforming types to represent a single validation failure."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/ValidationFailure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ValidationFailure"}],"url":"\/documentation\/validations\/validationfailure"},"doc://Validations/documentation/Validations/InRange/Failure/value":{"role":"symbol","title":"value","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"value"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Bound"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure\/value","kind":"symbol","type":"topic","url":"\/documentation\/validations\/inrange\/failure\/value"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/InRange/Failure/range":{"role":"symbol","title":"range","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"range"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"R"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure\/range","kind":"symbol","type":"topic","url":"\/documentation\/validations\/inrange\/failure\/range"},"doc://Validations/documentation/Validations/InRange/Failure":{"role":"symbol","title":"InRange.Failure","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/inrange\/failure"},"doc://Validations/documentation/Validations/InRange":{"role":"symbol","title":"InRange","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"InRange"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"InRange"}],"url":"\/documentation\/validations\/inrange"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"range"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"R"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/inrange\/failure\/range"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure\/range","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"range"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"R"}],"title":"range","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations7InRangeV7FailureV5rangeqd__vp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/InRange","doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure"]]},"references":{"doc://Validations/documentation/Validations/InRange/Failure/range":{"role":"symbol","title":"range","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"range"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"R"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure\/range","kind":"symbol","type":"topic","url":"\/documentation\/validations\/inrange\/failure\/range"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/InRange/Failure":{"role":"symbol","title":"InRange.Failure","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/inrange\/failure"},"doc://Validations/documentation/Validations/InRange":{"role":"symbol","title":"InRange","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"InRange"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"InRange"}],"url":"\/documentation\/validations\/inrange"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"value"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Bound"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/inrange\/failure\/value"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure\/value","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"value"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Bound"}],"title":"value","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations7InRangeV7FailureV5value5BoundQyd__vp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/InRange","doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure"]]},"references":{"doc://Validations/documentation/Validations/InRange/Failure/value":{"role":"symbol","title":"value","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"value"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Bound"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure\/value","kind":"symbol","type":"topic","url":"\/documentation\/validations\/inrange\/failure\/value"},"doc://Validations/documentation/Validations/InRange/Failure":{"role":"symbol","title":"InRange.Failure","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/inrange\/failure"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/InRange":{"role":"symbol","title":"InRange","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"InRange"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"InRange"}],"url":"\/documentation\/validations\/inrange"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"R"},{"kind":"text","text":">("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"keyPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Bound"},{"kind":"text","text":">>, "},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"range"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":") "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"RangeExpression","preciseIdentifier":"s:SX"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/inrange\/init(_:_:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/InRange\/init(_:_:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"R"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Bound"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":")"}],"title":"init(_:_:)","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:11Validations7InRangeVyACyxGs7KeyPathCyx7DecodedAGVy5BoundQyd__GG_qd__tcSXRd__lufc","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/InRange"]]},"references":{"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/InRange/init(_:_:)":{"role":"symbol","title":"init(_:_:)","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"R"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":"."},{"kind":"typeIdentifier","text":"Bound"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"R"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange\/init(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/validations\/inrange\/init(_:_:)"},"doc://Validations/documentation/Validations/InRange":{"role":"symbol","title":"InRange","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"InRange"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"InRange"}],"url":"\/documentation\/validations\/inrange"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator","preciseIdentifier":"s:11Validations9ValidatorV","text":"Validator"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/inrange\/validator"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/InRange\/validator","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"The "},{"type":"reference","isActive":true,"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator"},{"type":"text","text":" that the conforming type exposes."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Validator","preciseIdentifier":"s:11Validations9ValidatorV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"title":"validator","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations7InRangeV9validatorAA9ValidatorVyxGvp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/InRange"]]},"references":{"doc://Validations/documentation/Validations/InRange/validator":{"role":"symbol","title":"validator","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Validator","preciseIdentifier":"s:11Validations9ValidatorV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"The "},{"type":"reference","isActive":true,"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator"},{"type":"text","text":" that the conforming type exposes."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange\/validator","kind":"symbol","type":"topic","url":"\/documentation\/validations\/inrange\/validator"},"doc://Validations/documentation/Validations/Validator":{"role":"symbol","title":"Validator","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Validator"}],"abstract":[{"type":"text","text":"Able to validate a "},{"type":"codeVoice","code":"Decoded<T>"},{"type":"text","text":" value."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Validator"}],"url":"\/documentation\/validations\/validator"},"doc://Validations/documentation/Validations/InRange":{"role":"symbol","title":"InRange","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"InRange"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/InRange","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"InRange"}],"url":"\/documentation\/validations\/inrange"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"internalParam","text":"lhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"internalParam","text":"rhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isabsent\/failure\/!=(_:_:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/!=(_:_:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Inherited from "},{"type":"codeVoice","code":"Equatable.!=(_:_:)"},{"type":"text","text":"."}],"kind":"symbol","metadata":{"role":"symbol","title":"!=(_:_:)","roleHeading":"Operator","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"symbolKind":"op","externalID":"s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::s:11Validations8IsAbsentV7FailureO","extendedModule":"Swift","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsAbsent","doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure","doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/Equatable-Implementations"]]},"references":{"doc://Validations/documentation/Validations/IsAbsent":{"role":"symbol","title":"IsAbsent","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsAbsent"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsAbsent"}],"url":"\/documentation\/validations\/isabsent"},"doc://Validations/documentation/Validations/IsAbsent/Failure/Equatable-Implementations":{"role":"collectionGroup","title":"Equatable Implementations","abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/Equatable-Implementations","kind":"article","type":"topic","url":"\/documentation\/validations\/isabsent\/failure\/equatable-implementations"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsAbsent/Failure/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isabsent\/failure\/!=(_:_:)"},"doc://Validations/documentation/Validations/IsAbsent/Failure":{"role":"symbol","title":"IsAbsent.Failure","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isabsent\/failure"}}}
|
|
@ -0,0 +1 @@
|
|||
{"variants":[{"paths":["\/documentation\/validations\/isabsent\/failure\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/Equatable-Implementations","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"article","metadata":{"modules":[{"name":"Validations"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsAbsent","doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure"]]},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/!=(_:_:)"],"generated":true}],"references":{"doc://Validations/documentation/Validations/IsAbsent/Failure":{"role":"symbol","title":"IsAbsent.Failure","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isabsent\/failure"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsAbsent/Failure/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isabsent\/failure\/!=(_:_:)"},"doc://Validations/documentation/Validations/IsAbsent":{"role":"symbol","title":"IsAbsent","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsAbsent"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsAbsent"}],"url":"\/documentation\/validations\/isabsent"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"hasValue"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isabsent\/failure\/hasvalue"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/hasValue","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"hasValue"}],"title":"IsAbsent.Failure.hasValue","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:11Validations8IsAbsentV7FailureO8hasValueyAEyx_GAGmlF","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsAbsent","doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure"]]},"references":{"doc://Validations/documentation/Validations/IsAbsent":{"role":"symbol","title":"IsAbsent","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsAbsent"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsAbsent"}],"url":"\/documentation\/validations\/isabsent"},"doc://Validations/documentation/Validations/IsAbsent/Failure":{"role":"symbol","title":"IsAbsent.Failure","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isabsent\/failure"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsAbsent/Failure/hasValue":{"role":"symbol","title":"IsAbsent.Failure.hasValue","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"hasValue"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/hasValue","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isabsent\/failure\/hasvalue"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"isNil"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isabsent\/failure\/isnil"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/isNil","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"isNil"}],"title":"IsAbsent.Failure.isNil","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:11Validations8IsAbsentV7FailureO5isNilyAEyx_GAGmlF","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsAbsent","doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure"]]},"references":{"doc://Validations/documentation/Validations/IsAbsent/Failure":{"role":"symbol","title":"IsAbsent.Failure","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isabsent\/failure"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsAbsent":{"role":"symbol","title":"IsAbsent","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsAbsent"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsAbsent"}],"url":"\/documentation\/validations\/isabsent"},"doc://Validations/documentation/Validations/IsAbsent/Failure/isNil":{"role":"symbol","title":"IsAbsent.Failure.isNil","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"isNil"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/Failure\/isNil","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isabsent\/failure\/isnil"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"keyPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isabsent\/init(_:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/init(_:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"title":"init(_:)","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:11Validations8IsAbsentVyACyxGs7KeyPathCyx7DecodedAGVyqd__GGclufc","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsAbsent"]]},"references":{"doc://Validations/documentation/Validations/IsAbsent/init(_:)":{"role":"symbol","title":"init(_:)","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/init(_:)","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isabsent\/init(_:)"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsAbsent":{"role":"symbol","title":"IsAbsent","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsAbsent"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsAbsent"}],"url":"\/documentation\/validations\/isabsent"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator","preciseIdentifier":"s:11Validations9ValidatorV","text":"Validator"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isabsent\/validator"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/validator","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"The "},{"type":"reference","isActive":true,"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator"},{"type":"text","text":" that the conforming type exposes."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Validator","preciseIdentifier":"s:11Validations9ValidatorV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"title":"validator","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations8IsAbsentV9validatorAA9ValidatorVyxGvp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsAbsent"]]},"references":{"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsAbsent":{"role":"symbol","title":"IsAbsent","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsAbsent"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsAbsent"}],"url":"\/documentation\/validations\/isabsent"},"doc://Validations/documentation/Validations/Validator":{"role":"symbol","title":"Validator","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Validator"}],"abstract":[{"type":"text","text":"Able to validate a "},{"type":"codeVoice","code":"Decoded<T>"},{"type":"text","text":" value."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Validator"}],"url":"\/documentation\/validations\/validator"},"doc://Validations/documentation/Validations/IsAbsent/validator":{"role":"symbol","title":"validator","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Validator","preciseIdentifier":"s:11Validations9ValidatorV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"The "},{"type":"reference","isActive":true,"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator"},{"type":"text","text":" that the conforming type exposes."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsAbsent\/validator","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isabsent\/validator"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"codingPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CodingPath","preciseIdentifier":"s:7Decoded10CodingPathV"},{"kind":"text","text":"?"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isequal\/failure\/codingpath"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure\/codingPath","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"codingPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CodingPath","preciseIdentifier":"s:7Decoded10CodingPathV"},{"kind":"text","text":"?"}],"title":"codingPath","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations7IsEqualV7FailureV10codingPath7Decoded06CodingF0VSgvp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsEqual","doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure"]]},"references":{"doc://Validations/documentation/Validations/IsEqual/Failure":{"role":"symbol","title":"IsEqual.Failure","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isequal\/failure"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsEqual":{"role":"symbol","title":"IsEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsEqual"}],"url":"\/documentation\/validations\/isequal"},"doc://Validations/documentation/Validations/IsEqual/Failure/codingPath":{"role":"symbol","title":"codingPath","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"codingPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CodingPath","preciseIdentifier":"s:7Decoded10CodingPathV"},{"kind":"text","text":"?"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure\/codingPath","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isequal\/failure\/codingpath"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"lhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isequal\/failure\/lhs"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure\/lhs","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"lhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"title":"lhs","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations7IsEqualV7FailureV3lhsqd__vp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsEqual","doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure"]]},"references":{"doc://Validations/documentation/Validations/IsEqual/Failure/lhs":{"role":"symbol","title":"lhs","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"lhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure\/lhs","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isequal\/failure\/lhs"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsEqual/Failure":{"role":"symbol","title":"IsEqual.Failure","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isequal\/failure"},"doc://Validations/documentation/Validations/IsEqual":{"role":"symbol","title":"IsEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsEqual"}],"url":"\/documentation\/validations\/isequal"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"rhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isequal\/failure\/rhs"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure\/rhs","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"rhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"title":"rhs","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations7IsEqualV7FailureV3rhsqd__vp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsEqual","doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure"]]},"references":{"doc://Validations/documentation/Validations/IsEqual":{"role":"symbol","title":"IsEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsEqual"}],"url":"\/documentation\/validations\/isequal"},"doc://Validations/documentation/Validations/IsEqual/Failure":{"role":"symbol","title":"IsEqual.Failure","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isequal\/failure"},"doc://Validations/documentation/Validations/IsEqual/Failure/rhs":{"role":"symbol","title":"rhs","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"rhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/Failure\/rhs","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isequal\/failure\/rhs"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"keyPath1"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"keyPath2"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>) "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"Equatable","preciseIdentifier":"s:SQ"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isequal\/init(_:_:)-14ta4"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/init(_:_:)-14ta4","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"title":"init(_:_:)","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:11Validations7IsEqualVyACyxGs7KeyPathCyx7DecodedAGVyqd__GG_AJtcSQRd__lufc","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsEqual"]]},"references":{"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsEqual/init(_:_:)-14ta4":{"role":"symbol","title":"init(_:_:)","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/init(_:_:)-14ta4","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isequal\/init(_:_:)-14ta4"},"doc://Validations/documentation/Validations/IsEqual":{"role":"symbol","title":"IsEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsEqual"}],"url":"\/documentation\/validations\/isequal"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"keyPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"rhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":") "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"Equatable","preciseIdentifier":"s:SQ"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isequal\/init(_:_:)-7ubuc"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/init(_:_:)-7ubuc","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":")"}],"title":"init(_:_:)","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:11Validations7IsEqualVyACyxGs7KeyPathCyx7DecodedAGVyqd__GG_qd__tcSQRd__lufc","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsEqual"]]},"references":{"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsEqual/init(_:_:)-7ubuc":{"role":"symbol","title":"init(_:_:)","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/init(_:_:)-7ubuc","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isequal\/init(_:_:)-7ubuc"},"doc://Validations/documentation/Validations/IsEqual":{"role":"symbol","title":"IsEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsEqual"}],"url":"\/documentation\/validations\/isequal"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator","preciseIdentifier":"s:11Validations9ValidatorV","text":"Validator"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isequal\/validator"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/validator","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"The "},{"type":"reference","isActive":true,"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator"},{"type":"text","text":" that the conforming type exposes."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Validator","preciseIdentifier":"s:11Validations9ValidatorV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"title":"validator","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations7IsEqualV9validatorAA9ValidatorVyxGvp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsEqual"]]},"references":{"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsEqual":{"role":"symbol","title":"IsEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsEqual"}],"url":"\/documentation\/validations\/isequal"},"doc://Validations/documentation/Validations/IsEqual/validator":{"role":"symbol","title":"validator","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Validator","preciseIdentifier":"s:11Validations9ValidatorV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"The "},{"type":"reference","isActive":true,"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator"},{"type":"text","text":" that the conforming type exposes."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsEqual\/validator","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isequal\/validator"},"doc://Validations/documentation/Validations/Validator":{"role":"symbol","title":"Validator","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Validator"}],"abstract":[{"type":"text","text":"Able to validate a "},{"type":"codeVoice","code":"Decoded<T>"},{"type":"text","text":" value."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Validator"}],"url":"\/documentation\/validations\/validator"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnil\/failure"],"traits":[{"interfaceLanguage":"swift"}]}],"relationshipsSections":[{"identifiers":["doc:\/\/Validations\/SQ","doc:\/\/Validations\/SH","doc:\/\/Validations\/documentation\/Validations\/ValidationFailure"],"kind":"relationships","title":"Conforms To","type":"conformsTo"}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"title":"IsNil.Failure","roleHeading":"Enumeration","role":"symbol","symbolKind":"enum","externalID":"s:11Validations5IsNilV7FailureO","modules":[{"name":"Validations"}],"navigatorTitle":[{"kind":"identifier","text":"Failure"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNil"]]},"topicSections":[{"title":"Enumeration Cases","identifiers":["doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/hasValue","doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/isAbsent"]},{"title":"Default Implementations","identifiers":["doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/Equatable-Implementations"],"generated":true}],"references":{"doc://Validations/SQ":{"type":"unresolvable","title":"Swift.Equatable","identifier":"doc:\/\/Validations\/SQ"},"doc://Validations/documentation/Validations/IsNil/Failure/hasValue":{"role":"symbol","title":"IsNil.Failure.hasValue","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"hasValue"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/hasValue","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnil\/failure\/hasvalue"},"doc://Validations/documentation/Validations/IsNil/Failure/isAbsent":{"role":"symbol","title":"IsNil.Failure.isAbsent","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"isAbsent"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/isAbsent","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnil\/failure\/isabsent"},"doc://Validations/documentation/Validations/IsNil/Failure/Equatable-Implementations":{"role":"collectionGroup","title":"Equatable Implementations","abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/Equatable-Implementations","kind":"article","type":"topic","url":"\/documentation\/validations\/isnil\/failure\/equatable-implementations"},"doc://Validations/SH":{"type":"unresolvable","title":"Swift.Hashable","identifier":"doc:\/\/Validations\/SH"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/ValidationFailure":{"role":"symbol","title":"ValidationFailure","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"ValidationFailure"}],"abstract":[{"type":"text","text":"Enables conforming types to represent a single validation failure."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/ValidationFailure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ValidationFailure"}],"url":"\/documentation\/validations\/validationfailure"},"doc://Validations/documentation/Validations/IsNil":{"role":"symbol","title":"IsNil","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNil"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNil"}],"url":"\/documentation\/validations\/isnil"},"doc://Validations/documentation/Validations/IsNil/Failure":{"role":"symbol","title":"IsNil.Failure","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isnil\/failure"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"internalParam","text":"lhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"internalParam","text":"rhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnil\/failure\/!=(_:_:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/!=(_:_:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"Inherited from "},{"type":"codeVoice","code":"Equatable.!=(_:_:)"},{"type":"text","text":"."}],"kind":"symbol","metadata":{"role":"symbol","title":"!=(_:_:)","roleHeading":"Operator","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"symbolKind":"op","externalID":"s:SQsE2neoiySbx_xtFZ::SYNTHESIZED::s:11Validations5IsNilV7FailureO","extendedModule":"Swift","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNil","doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure","doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/Equatable-Implementations"]]},"references":{"doc://Validations/documentation/Validations/IsNil/Failure":{"role":"symbol","title":"IsNil.Failure","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isnil\/failure"},"doc://Validations/documentation/Validations/IsNil/Failure/Equatable-Implementations":{"role":"collectionGroup","title":"Equatable Implementations","abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/Equatable-Implementations","kind":"article","type":"topic","url":"\/documentation\/validations\/isnil\/failure\/equatable-implementations"},"doc://Validations/documentation/Validations/IsNil/Failure/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnil\/failure\/!=(_:_:)"},"doc://Validations/documentation/Validations/IsNil":{"role":"symbol","title":"IsNil","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNil"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNil"}],"url":"\/documentation\/validations\/isnil"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"}}}
|
|
@ -0,0 +1 @@
|
|||
{"variants":[{"paths":["\/documentation\/validations\/isnil\/failure\/equatable-implementations"],"traits":[{"interfaceLanguage":"swift"}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/Equatable-Implementations","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"article","metadata":{"modules":[{"name":"Validations"}],"role":"collectionGroup","title":"Equatable Implementations"},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNil","doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure"]]},"topicSections":[{"title":"Operators","identifiers":["doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/!=(_:_:)"],"generated":true}],"references":{"doc://Validations/documentation/Validations/IsNil":{"role":"symbol","title":"IsNil","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNil"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNil"}],"url":"\/documentation\/validations\/isnil"},"doc://Validations/documentation/Validations/IsNil/Failure/!=(_:_:)":{"role":"symbol","title":"!=(_:_:)","fragments":[{"kind":"keyword","text":"static"},{"kind":"text","text":" "},{"kind":"keyword","text":"func"},{"kind":"text","text":" "},{"kind":"identifier","text":"!="},{"kind":"text","text":" "},{"kind":"text","text":"("},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Self"},{"kind":"text","text":") -> "},{"kind":"typeIdentifier","text":"Bool","preciseIdentifier":"s:Sb"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/!=(_:_:)","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnil\/failure\/!=(_:_:)"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsNil/Failure":{"role":"symbol","title":"IsNil.Failure","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isnil\/failure"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"hasValue"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnil\/failure\/hasvalue"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/hasValue","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"hasValue"}],"title":"IsNil.Failure.hasValue","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:11Validations5IsNilV7FailureO8hasValueyAEyx_GAGmlF","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNil","doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure"]]},"references":{"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsNil":{"role":"symbol","title":"IsNil","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNil"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNil"}],"url":"\/documentation\/validations\/isnil"},"doc://Validations/documentation/Validations/IsNil/Failure":{"role":"symbol","title":"IsNil.Failure","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isnil\/failure"},"doc://Validations/documentation/Validations/IsNil/Failure/hasValue":{"role":"symbol","title":"IsNil.Failure.hasValue","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"hasValue"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/hasValue","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnil\/failure\/hasvalue"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"isAbsent"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnil\/failure\/isabsent"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/isAbsent","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"isAbsent"}],"title":"IsNil.Failure.isAbsent","roleHeading":"Case","role":"symbol","symbolKind":"case","externalID":"s:11Validations5IsNilV7FailureO8isAbsentyAEyx_GAGmlF","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNil","doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure"]]},"references":{"doc://Validations/documentation/Validations/IsNil":{"role":"symbol","title":"IsNil","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNil"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNil"}],"url":"\/documentation\/validations\/isnil"},"doc://Validations/documentation/Validations/IsNil/Failure":{"role":"symbol","title":"IsNil.Failure","fragments":[{"kind":"keyword","text":"enum"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isnil\/failure"},"doc://Validations/documentation/Validations/IsNil/Failure/isAbsent":{"role":"symbol","title":"IsNil.Failure.isAbsent","fragments":[{"kind":"keyword","text":"case"},{"kind":"text","text":" "},{"kind":"identifier","text":"isAbsent"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/Failure\/isAbsent","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnil\/failure\/isabsent"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"keyPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnil\/init(_:)"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/init(_:)","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"title":"init(_:)","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:11Validations5IsNilVyACyxGs7KeyPathCyx7DecodedAGVyqd__GGclufc","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNil"]]},"references":{"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsNil":{"role":"symbol","title":"IsNil","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNil"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNil"}],"url":"\/documentation\/validations\/isnil"},"doc://Validations/documentation/Validations/IsNil/init(_:)":{"role":"symbol","title":"init(_:)","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/init(_:)","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnil\/init(_:)"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator","preciseIdentifier":"s:11Validations9ValidatorV","text":"Validator"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnil\/validator"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/validator","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"The "},{"type":"reference","isActive":true,"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator"},{"type":"text","text":" that the conforming type exposes."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Validator","preciseIdentifier":"s:11Validations9ValidatorV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"title":"validator","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations5IsNilV9validatorAA9ValidatorVyxGvp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNil"]]},"references":{"doc://Validations/documentation/Validations/Validator":{"role":"symbol","title":"Validator","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Validator"}],"abstract":[{"type":"text","text":"Able to validate a "},{"type":"codeVoice","code":"Decoded<T>"},{"type":"text","text":" value."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Validator"}],"url":"\/documentation\/validations\/validator"},"doc://Validations/documentation/Validations/IsNil/validator":{"role":"symbol","title":"validator","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"validator"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"Validator","preciseIdentifier":"s:11Validations9ValidatorV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":">"}],"abstract":[{"type":"text","text":"The "},{"type":"reference","isActive":true,"identifier":"doc:\/\/Validations\/documentation\/Validations\/Validator"},{"type":"text","text":" that the conforming type exposes."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil\/validator","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnil\/validator"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsNil":{"role":"symbol","title":"IsNil","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNil"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNil","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNil"}],"url":"\/documentation\/validations\/isnil"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":"> "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"Equatable","preciseIdentifier":"s:SQ"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnotequal\/failure"],"traits":[{"interfaceLanguage":"swift"}]}],"relationshipsSections":[{"identifiers":["doc:\/\/Validations\/documentation\/Validations\/ValidationFailure"],"kind":"relationships","title":"Conforms To","type":"conformsTo"}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"title":"IsNotEqual.Failure","roleHeading":"Structure","role":"symbol","symbolKind":"struct","externalID":"s:11Validations10IsNotEqualV7FailureV","modules":[{"name":"Validations"}],"navigatorTitle":[{"kind":"identifier","text":"Failure"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNotEqual"]]},"topicSections":[{"title":"Instance Properties","identifiers":["doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure\/codingPath","doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure\/value"]}],"references":{"doc://Validations/documentation/Validations/IsNotEqual/Failure":{"role":"symbol","title":"IsNotEqual.Failure","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isnotequal\/failure"},"doc://Validations/documentation/Validations/ValidationFailure":{"role":"symbol","title":"ValidationFailure","fragments":[{"kind":"keyword","text":"protocol"},{"kind":"text","text":" "},{"kind":"identifier","text":"ValidationFailure"}],"abstract":[{"type":"text","text":"Enables conforming types to represent a single validation failure."}],"identifier":"doc:\/\/Validations\/documentation\/Validations\/ValidationFailure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"ValidationFailure"}],"url":"\/documentation\/validations\/validationfailure"},"doc://Validations/documentation/Validations/IsNotEqual/Failure/codingPath":{"role":"symbol","title":"codingPath","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"codingPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CodingPath","preciseIdentifier":"s:7Decoded10CodingPathV"},{"kind":"text","text":"?"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure\/codingPath","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnotequal\/failure\/codingpath"},"doc://Validations/documentation/Validations/IsNotEqual/Failure/value":{"role":"symbol","title":"value","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"value"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure\/value","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnotequal\/failure\/value"},"doc://Validations/documentation/Validations/IsNotEqual":{"role":"symbol","title":"IsNotEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNotEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNotEqual"}],"url":"\/documentation\/validations\/isnotequal"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"codingPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CodingPath","preciseIdentifier":"s:7Decoded10CodingPathV"},{"kind":"text","text":"?"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnotequal\/failure\/codingpath"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure\/codingPath","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"codingPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CodingPath","preciseIdentifier":"s:7Decoded10CodingPathV"},{"kind":"text","text":"?"}],"title":"codingPath","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations10IsNotEqualV7FailureV10codingPath7Decoded06CodingG0VSgvp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNotEqual","doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure"]]},"references":{"doc://Validations/documentation/Validations/IsNotEqual/Failure/codingPath":{"role":"symbol","title":"codingPath","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"codingPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"CodingPath","preciseIdentifier":"s:7Decoded10CodingPathV"},{"kind":"text","text":"?"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure\/codingPath","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnotequal\/failure\/codingpath"},"doc://Validations/documentation/Validations/IsNotEqual/Failure":{"role":"symbol","title":"IsNotEqual.Failure","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isnotequal\/failure"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsNotEqual":{"role":"symbol","title":"IsNotEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNotEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNotEqual"}],"url":"\/documentation\/validations\/isnotequal"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"value"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnotequal\/failure\/value"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure\/value","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"value"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"title":"value","roleHeading":"Instance Property","role":"symbol","symbolKind":"property","externalID":"s:11Validations10IsNotEqualV7FailureV5valueqd__vp","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNotEqual","doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure"]]},"references":{"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsNotEqual":{"role":"symbol","title":"IsNotEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNotEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNotEqual"}],"url":"\/documentation\/validations\/isnotequal"},"doc://Validations/documentation/Validations/IsNotEqual/Failure":{"role":"symbol","title":"IsNotEqual.Failure","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"Failure"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"Failure"}],"url":"\/documentation\/validations\/isnotequal\/failure"},"doc://Validations/documentation/Validations/IsNotEqual/Failure/value":{"role":"symbol","title":"value","fragments":[{"kind":"keyword","text":"let"},{"kind":"text","text":" "},{"kind":"identifier","text":"value"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/Failure\/value","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnotequal\/failure\/value"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"keyPath"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"rhs"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":") "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"Equatable","preciseIdentifier":"s:SQ"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnotequal\/init(_:_:)-3d7ej"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/init(_:_:)-3d7ej","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":")"}],"title":"init(_:_:)","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:11Validations10IsNotEqualVyACyxGs7KeyPathCyx7DecodedAGVyqd__GG_qd__tcSQRd__lufc","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNotEqual"]]},"references":{"doc://Validations/documentation/Validations/IsNotEqual":{"role":"symbol","title":"IsNotEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNotEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNotEqual"}],"url":"\/documentation\/validations\/isnotequal"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"},"doc://Validations/documentation/Validations/IsNotEqual/init(_:_:)-3d7ej":{"role":"symbol","title":"init(_:_:)","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":")"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/init(_:_:)-3d7ej","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnotequal\/init(_:_:)-3d7ej"}}}
|
|
@ -0,0 +1 @@
|
|||
{"primaryContentSections":[{"kind":"declarations","declarations":[{"tokens":[{"kind":"keyword","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"keyPath1"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"externalParam","text":"_"},{"kind":"text","text":" "},{"kind":"internalParam","text":"keyPath2"},{"kind":"text","text":": "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>) "},{"kind":"keyword","text":"where"},{"kind":"text","text":" "},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":" : "},{"kind":"typeIdentifier","text":"Equatable","preciseIdentifier":"s:SQ"}],"languages":["swift"],"platforms":["macOS"]}]}],"schemaVersion":{"major":0,"minor":1,"patch":0},"sections":[],"variants":[{"paths":["\/documentation\/validations\/isnotequal\/init(_:_:)-4ul29"],"traits":[{"interfaceLanguage":"swift"}]}],"identifier":{"url":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/init(_:_:)-4ul29","interfaceLanguage":"swift"},"abstract":[{"type":"text","text":"No overview available."}],"kind":"symbol","metadata":{"fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"title":"init(_:_:)","roleHeading":"Initializer","role":"symbol","symbolKind":"init","externalID":"s:11Validations10IsNotEqualVyACyxGs7KeyPathCyx7DecodedAGVyqd__GG_AJtcSQRd__lufc","modules":[{"name":"Validations"}]},"hierarchy":{"paths":[["doc:\/\/Validations\/documentation\/Validations","doc:\/\/Validations\/documentation\/Validations\/IsNotEqual"]]},"references":{"doc://Validations/documentation/Validations/IsNotEqual/init(_:_:)-4ul29":{"role":"symbol","title":"init(_:_:)","fragments":[{"kind":"identifier","text":"init"},{"kind":"text","text":"<"},{"kind":"genericParameter","text":"U"},{"kind":"text","text":">("},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>, "},{"kind":"typeIdentifier","text":"KeyPath","preciseIdentifier":"s:s7KeyPathC"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"T"},{"kind":"text","text":", "},{"kind":"typeIdentifier","text":"Decoded","preciseIdentifier":"s:7DecodedAAV"},{"kind":"text","text":"<"},{"kind":"typeIdentifier","text":"U"},{"kind":"text","text":">>)"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual\/init(_:_:)-4ul29","kind":"symbol","type":"topic","url":"\/documentation\/validations\/isnotequal\/init(_:_:)-4ul29"},"doc://Validations/documentation/Validations/IsNotEqual":{"role":"symbol","title":"IsNotEqual","fragments":[{"kind":"keyword","text":"struct"},{"kind":"text","text":" "},{"kind":"identifier","text":"IsNotEqual"}],"abstract":[],"identifier":"doc:\/\/Validations\/documentation\/Validations\/IsNotEqual","kind":"symbol","type":"topic","navigatorTitle":[{"kind":"identifier","text":"IsNotEqual"}],"url":"\/documentation\/validations\/isnotequal"},"doc://Validations/documentation/Validations":{"role":"collection","title":"Validations","abstract":[{"type":"text","text":"Type-safe and composable validations with versatile output."}],"identifier":"doc:\/\/Validations\/documentation\/Validations","kind":"symbol","type":"topic","url":"\/documentation\/validations"}}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue