Move JSONAPIArbitrary and JSONAPIOpenAPI into their own packages.

This commit is contained in:
Mathew Polzin
2019-01-30 17:54:26 -08:00
parent ea663bb229
commit 7adbdb4505
32 changed files with 2 additions and 6021 deletions
+2 -23
View File
@@ -11,19 +11,10 @@ let package = Package(
targets: ["JSONAPI"]),
.library(
name: "JSONAPITesting",
targets: ["JSONAPITesting"]),
.library(
name: "JSONAPIArbitrary",
targets: ["JSONAPIArbitrary"]),
.library(
name: "JSONAPIOpenAPI",
targets: ["JSONAPIOpenAPI"])
targets: ["JSONAPITesting"])
],
dependencies: [
.package(url: "https://github.com/mattpolzin/Poly.git", from: "1.0.0"),
.package(url: "https://github.com/mattpolzin/Sampleable.git", from: "1.0.0"),
.package(url: "https://github.com/Flight-School/AnyCodable.git", from: "0.1.0"),
.package(url: "https://github.com/typelift/SwiftCheck.git", from: "0.11.0")
],
targets: [
.target(
@@ -32,24 +23,12 @@ let package = Package(
.target(
name: "JSONAPITesting",
dependencies: ["JSONAPI"]),
.target(
name: "JSONAPIArbitrary",
dependencies: ["JSONAPI", "SwiftCheck"]),
.target(
name: "JSONAPIOpenAPI",
dependencies: ["JSONAPI", "AnyCodable", "JSONAPIArbitrary", "Sampleable"]),
.testTarget(
name: "JSONAPITests",
dependencies: ["JSONAPI", "JSONAPITesting"]),
.testTarget(
name: "JSONAPITestingTests",
dependencies: ["JSONAPI", "JSONAPITesting"]),
.testTarget(
name: "JSONAPIArbitraryTests",
dependencies: ["JSONAPI", "SwiftCheck", "JSONAPIArbitrary"]),
.testTarget(
name: "JSONAPIOpenAPITests",
dependencies: ["JSONAPI", "JSONAPIOpenAPI"])
dependencies: ["JSONAPI", "JSONAPITesting"])
],
swiftLanguageVersions: [.v4_2]
)
@@ -1,24 +0,0 @@
//
// APIDescription+Arbitrary.swift
// JSONAPIArbitrary
//
// Created by Mathew Polzin on 1/21/19.
//
import SwiftCheck
import JSONAPI
extension APIDescription: Arbitrary where Meta: Arbitrary {
public static var arbitrary: Gen<APIDescription<Meta>> {
return Gen.compose { c in
APIDescription(version: c.generate(),
meta: c.generate())
}
}
}
extension NoAPIDescription: Arbitrary {
public static var arbitrary: Gen<NoAPIDescription> {
return Gen.pure(.none)
}
}
@@ -1,20 +0,0 @@
//
// Attribute+Arbitrary.swift
// JSONAPIArbitrary
//
// Created by Mathew Polzin on 1/15/19.
//
import SwiftCheck
import JSONAPI
extension Attribute: Arbitrary where RawValue: Arbitrary {
public static var arbitrary: Gen<Attribute<RawValue>> {
return RawValue.arbitrary.map { .init(value: $0) }
}
}
// Cannot conform TransformedAttribute to Arbitrary here
// because there is no way to guarantee that an arbitrary
// RawValue will successfully transform or that an
// arbitrary Value will successfully reverse-transform.
@@ -1,110 +0,0 @@
//
// Document+Arbitrary.swift
// JSONAPIArbitrary
//
// Created by Mathew Polzin on 1/21/19.
//
import SwiftCheck
import JSONAPI
extension Document.Body.Data: Arbitrary where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary {
public static var arbitrary: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body.Data> {
return Gen.compose { c in
Document.Body.Data(primary: c.generate(),
includes: c.generate(),
meta: c.generate(),
links: c.generate())
}
}
}
extension Document.Body: Arbitrary where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary, Error: Arbitrary {
public static var arbitrary: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body> {
return Gen.one(of: [
arbitraryData,
arbitraryErrors
])
}
}
extension Document.Body where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary {
/// Arbitrary Document.Body with data (guaranteed to not
/// be an error body).
public static var arbitraryData: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body> {
return Document.Body.Data.arbitrary.map(Document.Body.data)
}
}
extension Document.Body where MetaType: Arbitrary, LinksType: Arbitrary, Error: Arbitrary {
/// Arbitrary Document.Body with errors (guaranteed to not
/// be a data body).
public static var arbitraryErrors: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body> {
return Gen.compose { c in
Document.Body.errors(c.generate(),
meta: c.generate(),
links: c.generate())
}
}
}
extension Document.Body where Error: Arbitrary {
/// Arbitrary Document.Body with errors but no
/// metadata or links (also guaranteed to not
/// be a data body).
public static var arbitraryErrorsWithoutMetaOrLinks: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body> {
return Gen.compose { c in
Document.Body.errors(c.generate(),
meta: nil,
links: nil)
}
}
}
extension Document: Arbitrary where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary, Error: Arbitrary, APIDescription: Arbitrary {
public static var arbitrary: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>> {
return Gen.one(of: [
arbitraryData,
arbitraryErrors
])
}
}
extension Document where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary, APIDescription: Arbitrary {
/// Arbitrary Document with data (guaranteed to not
/// be an error body).
public static var arbitraryData: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>> {
return Gen.compose { c in
Document(apiDescription: c.generate(),
body: c.generate(),
includes: c.generate(),
meta: c.generate(),
links: c.generate())
}
}
}
extension Document where MetaType: Arbitrary, LinksType: Arbitrary, Error: Arbitrary, APIDescription: Arbitrary {
/// Arbitrary Document with errors (guaranteed to not
/// be a data body).
public static var arbitraryErrors: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>> {
return Gen.compose { c in
Document(apiDescription: c.generate(),
errors: c.generate(),
meta: c.generate(),
links: c.generate())
}
}
}
extension Document where Error: Arbitrary, APIDescription: Arbitrary {
/// Arbitrary Document with errors but no
/// metadata or links (also guaranteed to not
/// be a data body).
public static var arbitraryErrors: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>> {
return Gen.compose { c in
Document(apiDescription: c.generate(),
errors: c.generate())
}
}
}
@@ -1,50 +0,0 @@
//
// Entity+Arbitrary.swift
// JSONAPIArbitrary
//
// Created by Mathew Polzin on 1/14/19.
//
import SwiftCheck
import JSONAPI
extension NoMetadata: Arbitrary {
public static var arbitrary: Gen<NoMetadata> {
return Gen.pure(.none)
}
}
extension NoLinks: Arbitrary {
public static var arbitrary: Gen<NoLinks> {
return Gen.pure(.none)
}
}
extension NoAttributes: Arbitrary {
public static var arbitrary: Gen<NoAttributes> {
return Gen.pure(.none)
}
}
extension NoRelationships: Arbitrary {
public static var arbitrary: Gen<NoRelationships> {
return Gen.pure(.none)
}
}
// NOTE: Arbitrary conformance for MetaType, LinksType, Description.Attributes,
// and Description.Relationships must all be provided BY YOU for Entity to
// gain Arbitrary conformance (with the exception of NoMetadata, NoLinks,
// NoAttributes, and NoRelationships which all have Arbitrary conformance
// out of the box).
extension Entity: Arbitrary where MetaType: Arbitrary, LinksType: Arbitrary, Description.Attributes: Arbitrary, Description.Relationships: Arbitrary, EntityRawIdType: Arbitrary {
public static var arbitrary: Gen<Entity<Description, MetaType, LinksType, EntityRawIdType>> {
return Gen.compose { c in
Entity(id: c.generate(),
attributes: c.generate(),
relationships: c.generate(),
meta: c.generate(),
links: c.generate())
}
}
}
@@ -1,15 +0,0 @@
//
// Error+Arbitrary.swift
// JSONAPIArbitrary
//
// Created by Mathew Polzin on 1/21/19.
//
import SwiftCheck
import JSONAPI
extension UnknownJSONAPIError: Arbitrary {
public static var arbitrary: Gen<UnknownJSONAPIError> {
return Gen.pure(.unknownError)
}
}
@@ -1,21 +0,0 @@
//
// Id+Arbitrary.swift
// JSONAPIArbitrary
//
// Created by Mathew Polzin on 1/14/19.
//
import SwiftCheck
import JSONAPI
extension Unidentified: Arbitrary {
public static var arbitrary: Gen<Unidentified> {
return Gen.pure(.init())
}
}
extension Id: Arbitrary where RawType: Arbitrary {
public static var arbitrary: Gen<Id<RawType, IdentifiableType>> {
return RawType.arbitrary.map { Id(rawValue: $0) }
}
}
@@ -1,166 +0,0 @@
//
// Includes+Arbitrary.swift
// JSONAPIArbitrary
//
// Created by Mathew Polzin on 1/21/19.
//
import SwiftCheck
import JSONAPI
extension Includes: Arbitrary where I: Arbitrary {
public static var arbitrary: Gen<Includes<I>> {
return I
.arbitrary
.proliferate
.map(Includes.init(values:))
}
}
extension NoIncludes: Arbitrary {
public static var arbitrary: Gen<NoIncludes> {
return Gen.pure(NoIncludes())
}
}
extension Include1: Arbitrary where A: Arbitrary {
public static var arbitrary: Gen<Include1<A>> {
return Gen.one(of: [
A.arbitrary.map(Include1.init)
])
}
}
extension Include2: Arbitrary where A: Arbitrary, B: Arbitrary {
public static var arbitrary: Gen<Include2<A, B>> {
return Gen.one(of: [
A.arbitrary.map(Include2.init),
B.arbitrary.map(Include2.init)
])
}
}
extension Include3: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary {
public static var arbitrary: Gen<Include3<A, B, C>> {
return Gen.one(of: [
A.arbitrary.map(Include3.init),
B.arbitrary.map(Include3.init),
C.arbitrary.map(Include3.init)
])
}
}
extension Include4: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary {
public static var arbitrary: Gen<Include4<A, B, C, D>> {
return Gen.one(of: [
A.arbitrary.map(Include4.init),
B.arbitrary.map(Include4.init),
C.arbitrary.map(Include4.init),
D.arbitrary.map(Include4.init)
])
}
}
extension Include5: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary {
public static var arbitrary: Gen<Include5<A, B, C, D, E>> {
return Gen.one(of: [
A.arbitrary.map(Include5.init),
B.arbitrary.map(Include5.init),
C.arbitrary.map(Include5.init),
D.arbitrary.map(Include5.init),
E.arbitrary.map(Include5.init)
])
}
}
extension Include6: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary {
public static var arbitrary: Gen<Include6<A, B, C, D, E, F>> {
// Note broken up because compiler cannot typecheck entire array
// before it times out
let set1: [Gen<Include6<A, B, C, D, E, F>>] = [
A.arbitrary.map(Include6.init),
B.arbitrary.map(Include6.init),
C.arbitrary.map(Include6.init)
]
let set2: [Gen<Include6<A, B, C, D, E, F>>] = [
D.arbitrary.map(Include6.init),
E.arbitrary.map(Include6.init),
F.arbitrary.map(Include6.init)
]
return Gen.one(of: set1 + set2)
}
}
extension Include7: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary, G: Arbitrary {
public static var arbitrary: Gen<Include7<A, B, C, D, E, F, G>> {
// Note broken up because compiler cannot typecheck entire array
// before it times out
let set1: [Gen<Include7<A, B, C, D, E, F, G>>] = [
A.arbitrary.map(Include7.init),
B.arbitrary.map(Include7.init),
C.arbitrary.map(Include7.init)
]
let set2: [Gen<Include7<A, B, C, D, E, F, G>>] = [
D.arbitrary.map(Include7.init),
E.arbitrary.map(Include7.init),
F.arbitrary.map(Include7.init),
G.arbitrary.map(Include7.init)
]
return Gen.one(of: set1 + set2)
}
}
extension Include8: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary, G: Arbitrary, H: Arbitrary {
public static var arbitrary: Gen<Include8<A, B, C, D, E, F, G, H>> {
// Note broken up because compiler cannot typecheck entire array
// before it times out
let set1: [Gen<Include8<A, B, C, D, E, F, G, H>>] = [
A.arbitrary.map(Include8.init),
B.arbitrary.map(Include8.init),
C.arbitrary.map(Include8.init)
]
let set2: [Gen<Include8<A, B, C, D, E, F, G, H>>] = [
D.arbitrary.map(Include8.init),
E.arbitrary.map(Include8.init),
F.arbitrary.map(Include8.init)
]
let set3: [Gen<Include8<A, B, C, D, E, F, G, H>>] = [
G.arbitrary.map(Include8.init),
H.arbitrary.map(Include8.init)
]
return Gen.one(of: set1 + set2 + set3)
}
}
extension Include9: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary, G: Arbitrary, H: Arbitrary, I: Arbitrary {
public static var arbitrary: Gen<Include9<A, B, C, D, E, F, G, H, I>> {
// Note broken up because compiler cannot typecheck entire array
// before it times out
let set1: [Gen<Include9<A, B, C, D, E, F, G, H, I>>] = [
A.arbitrary.map(Include9.init),
B.arbitrary.map(Include9.init),
C.arbitrary.map(Include9.init)
]
let set2: [Gen<Include9<A, B, C, D, E, F, G, H, I>>] = [
D.arbitrary.map(Include9.init),
E.arbitrary.map(Include9.init),
F.arbitrary.map(Include9.init)
]
let set3: [Gen<Include9<A, B, C, D, E, F, G, H, I>>] = [
G.arbitrary.map(Include9.init),
H.arbitrary.map(Include9.init),
I.arbitrary.map(Include9.init)
]
return Gen.one(of: set1 + set2 + set3)
}
}
@@ -1,60 +0,0 @@
//
// Relationship+Arbitrary.swift
// JSONAPIArbitrary
//
// Created by Mathew Polzin on 1/15/19.
//
import SwiftCheck
import JSONAPI
extension ToOneRelationship: Arbitrary where Identifiable.Identifier: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary {
public static var arbitrary: Gen<ToOneRelationship<Identifiable, MetaType, LinksType>> {
return Gen.compose { c in
return .init(id: c.generate(),
meta: c.generate(),
links: c.generate())
}
}
}
extension ToOneRelationship where MetaType: Arbitrary, LinksType: Arbitrary {
/// Create a generator of arbitrary ToOneRelationships that will all
/// point to one of the given entities. This allows you to create
/// arbitrary relationships that make sense in a broader context where
/// the relationship must actually point to another entity.
public static func arbitrary<E: EntityType>(givenEntities: [E]) -> Gen<ToOneRelationship<Identifiable, MetaType, LinksType>> where E.Id == Identifiable.Identifier {
return Gen.compose { c in
let idGen = Gen.fromElements(of: givenEntities).map { $0.id }
return .init(id: c.generate(using: idGen),
meta: c.generate(),
links: c.generate())
}
}
}
extension ToManyRelationship: Arbitrary where Relatable.Identifier: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary {
public static var arbitrary: Gen<ToManyRelationship<Relatable, MetaType, LinksType>> {
return Gen.compose { c in
return .init(ids: c.generate(),
meta: c.generate(),
links: c.generate())
}
}
}
extension ToManyRelationship where MetaType: Arbitrary, LinksType: Arbitrary {
/// Create a generator of arbitrary ToManyRelationships that will all
/// point to some number of the given entities. This allows you to create
/// arbitrary relationships that make sense in a broader context where
/// the relationship must actually point to other existing entities.
public static func arbitrary<E: EntityType>(givenEntities: [E]) -> Gen<ToManyRelationship<Relatable, MetaType, LinksType>> where E.Id == Relatable.Identifier {
return Gen.compose { c in
let idsGen = Gen.fromElements(of: givenEntities).map { $0.id }.proliferate
return .init(ids: c.generate(using: idsGen),
meta: c.generate(),
links: c.generate())
}
}
}
@@ -1,27 +0,0 @@
//
// ResourceBody+Arbitrary.swift
// JSONAPIArbitrary
//
// Created by Mathew Polzin on 1/21/19.
//
import SwiftCheck
import JSONAPI
extension SingleResourceBody: Arbitrary where Entity: Arbitrary {
public static var arbitrary: Gen<SingleResourceBody<Entity>> {
return Entity.arbitrary.map(SingleResourceBody.init(entity:))
}
}
extension ManyResourceBody: Arbitrary where Entity: Arbitrary {
public static var arbitrary: Gen<ManyResourceBody<Entity>> {
return Entity.arbitrary.proliferate.map(ManyResourceBody.init(entities:))
}
}
extension NoResourceBody: Arbitrary {
public static var arbitrary: Gen<NoResourceBody> {
return Gen.pure(.none)
}
}
@@ -1,166 +0,0 @@
//
// JSONAPIAttribute+OpenAPI.swift
// JSONAPIOpenAPI
//
// Created by Mathew Polzin on 1/28/19.
//
import JSONAPI
import Foundation
import AnyCodable
private protocol _Optional {}
extension Optional: _Optional {}
private protocol Wrapper {
associatedtype Wrapped
}
extension Optional: Wrapper {}
// MARK: Attribute
extension Attribute: OpenAPINodeType where RawValue: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if try !RawValue.openAPINode().required {
return try RawValue.openAPINode().requiredNode().nullableNode()
}
return try RawValue.openAPINode()
}
}
extension Attribute: RawOpenAPINodeType where RawValue: RawRepresentable, RawValue.RawValue: OpenAPINodeType {
static public func rawOpenAPINode() throws -> JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if try !RawValue.RawValue.openAPINode().required {
return try RawValue.RawValue.openAPINode().requiredNode().nullableNode()
}
return try RawValue.RawValue.openAPINode()
}
}
extension Attribute: WrappedRawOpenAPIType where RawValue: RawOpenAPINodeType {
public static func wrappedOpenAPINode() throws -> JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if try !RawValue.rawOpenAPINode().required {
return try RawValue.rawOpenAPINode().requiredNode().nullableNode()
}
return try RawValue.rawOpenAPINode()
}
}
extension Attribute: GenericOpenAPINodeType where RawValue: GenericOpenAPINodeType {
public static func genericOpenAPINode(using encoder: JSONEncoder) throws -> JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if try !RawValue.genericOpenAPINode(using: encoder).required {
return try RawValue.genericOpenAPINode(using: encoder).requiredNode().nullableNode()
}
return try RawValue.genericOpenAPINode(using: encoder)
}
}
extension Attribute: DateOpenAPINodeType where RawValue: DateOpenAPINodeType {
public static func dateOpenAPINodeGuess(using encoder: JSONEncoder) -> JSONNode? {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if
!(RawValue.dateOpenAPINodeGuess(using: encoder)?.required ?? true) {
return RawValue.dateOpenAPINodeGuess(using: encoder)?.requiredNode().nullableNode()
}
return RawValue.dateOpenAPINodeGuess(using: encoder)
}
}
extension Attribute: AnyJSONCaseIterable where RawValue: CaseIterable, RawValue: Codable {
public static func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
return (try? allCases(from: Array(RawValue.allCases), using: encoder)) ?? []
}
}
extension Attribute: AnyWrappedJSONCaseIterable where RawValue: AnyJSONCaseIterable {
public static func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
return RawValue.allCases(using: encoder)
}
}
// MARK: - TransformedAttribute
extension TransformedAttribute: OpenAPINodeType where RawValue: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if try !RawValue.openAPINode().required {
return try RawValue.openAPINode().requiredNode().nullableNode()
}
return try RawValue.openAPINode()
}
}
extension TransformedAttribute: RawOpenAPINodeType where RawValue: RawRepresentable, RawValue.RawValue: OpenAPINodeType {
static public func rawOpenAPINode() throws -> JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if try !RawValue.RawValue.openAPINode().required {
return try RawValue.RawValue.openAPINode().requiredNode().nullableNode()
}
return try RawValue.RawValue.openAPINode()
}
}
extension TransformedAttribute: WrappedRawOpenAPIType where RawValue: RawOpenAPINodeType {
public static func wrappedOpenAPINode() throws -> JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if try !RawValue.rawOpenAPINode().required {
return try RawValue.rawOpenAPINode().requiredNode().nullableNode()
}
return try RawValue.rawOpenAPINode()
}
}
extension TransformedAttribute: GenericOpenAPINodeType where RawValue: GenericOpenAPINodeType {
public static func genericOpenAPINode(using encoder: JSONEncoder) throws -> JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if try !RawValue.genericOpenAPINode(using: encoder).required {
return try RawValue.genericOpenAPINode(using: encoder).requiredNode().nullableNode()
}
return try RawValue.genericOpenAPINode(using: encoder)
}
}
extension TransformedAttribute: DateOpenAPINodeType where RawValue: DateOpenAPINodeType {
public static func dateOpenAPINodeGuess(using encoder: JSONEncoder) -> JSONNode? {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if
!(RawValue.dateOpenAPINodeGuess(using: encoder)?.required ?? true) {
return RawValue.dateOpenAPINodeGuess(using: encoder)?.requiredNode().nullableNode()
}
return RawValue.dateOpenAPINodeGuess(using: encoder)
}
}
extension TransformedAttribute: AnyJSONCaseIterable where RawValue: CaseIterable, RawValue: Codable {
public static func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
return (try? allCases(from: Array(RawValue.allCases), using: encoder)) ?? []
}
}
extension TransformedAttribute: AnyWrappedJSONCaseIterable where RawValue: AnyJSONCaseIterable {
public static func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
return RawValue.allCases(using: encoder)
}
}
@@ -1,132 +0,0 @@
//
// JSONAPIInclude+OpenAPI.swift
// JSONAPIOpenAPI
//
// Created by Mathew Polzin on 1/22/19.
//
import JSONAPI
import Foundation
extension Includes: OpenAPIEncodedNodeType where I: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
let includeNode = try I.openAPINode(using: encoder)
return .array(.init(format: .generic,
required: true),
.init(items: includeNode,
uniqueItems: true))
}
}
extension Include0: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
throw OpenAPITypeError.invalidNode
}
}
extension Include1: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try A.openAPINode(using: encoder)
}
}
extension Include2: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try .one(of: [
A.openAPINode(using: encoder),
B.openAPINode(using: encoder)
])
}
}
extension Include3: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try .one(of: [
A.openAPINode(using: encoder),
B.openAPINode(using: encoder),
C.openAPINode(using: encoder)
])
}
}
extension Include4: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try .one(of: [
A.openAPINode(using: encoder),
B.openAPINode(using: encoder),
C.openAPINode(using: encoder),
D.openAPINode(using: encoder)
])
}
}
extension Include5: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try .one(of: [
A.openAPINode(using: encoder),
B.openAPINode(using: encoder),
C.openAPINode(using: encoder),
D.openAPINode(using: encoder),
E.openAPINode(using: encoder)
])
}
}
extension Include6: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType, F: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try .one(of: [
A.openAPINode(using: encoder),
B.openAPINode(using: encoder),
C.openAPINode(using: encoder),
D.openAPINode(using: encoder),
E.openAPINode(using: encoder),
F.openAPINode(using: encoder)
])
}
}
extension Include7: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType, F: OpenAPIEncodedNodeType, G: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try .one(of: [
A.openAPINode(using: encoder),
B.openAPINode(using: encoder),
C.openAPINode(using: encoder),
D.openAPINode(using: encoder),
E.openAPINode(using: encoder),
F.openAPINode(using: encoder),
G.openAPINode(using: encoder)
])
}
}
extension Include8: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType, F: OpenAPIEncodedNodeType, G: OpenAPIEncodedNodeType, H: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try .one(of: [
A.openAPINode(using: encoder),
B.openAPINode(using: encoder),
C.openAPINode(using: encoder),
D.openAPINode(using: encoder),
E.openAPINode(using: encoder),
F.openAPINode(using: encoder),
G.openAPINode(using: encoder),
H.openAPINode(using: encoder)
])
}
}
extension Include9: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType, F: OpenAPIEncodedNodeType, G: OpenAPIEncodedNodeType, H: OpenAPIEncodedNodeType, I: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try .one(of: [
A.openAPINode(using: encoder),
B.openAPINode(using: encoder),
C.openAPINode(using: encoder),
D.openAPINode(using: encoder),
E.openAPINode(using: encoder),
F.openAPINode(using: encoder),
G.openAPINode(using: encoder),
H.openAPINode(using: encoder),
I.openAPINode(using: encoder)
])
}
}
@@ -1,160 +0,0 @@
//
// JSONAPIOpenAPITypes.swift
// JSONAPIOpenAPI
//
// Created by Mathew Polzin on 1/13/19.
//
import JSONAPI
import Foundation
import AnyCodable
import Sampleable
private protocol _Optional {}
extension Optional: _Optional {}
private protocol Wrapper {
associatedtype Wrapped
}
extension Optional: Wrapper {}
extension RelationshipType {
static func relationshipNode(nullable: Bool, jsonType: String) -> JSONNode {
let propertiesDict: [String: JSONNode] = [
"id": .string(.init(format: .generic,
required: true),
.init()),
"type": .string(.init(format: .generic,
required: true,
allowedValues: [.init(jsonType)]),
.init())
]
return .object(.init(format: .generic,
required: true,
nullable: nullable),
.init(properties: propertiesDict))
}
}
extension ToOneRelationship: OpenAPINodeType {
// NOTE: const for json `type` not supported by OpenAPI 3.0
// Will use "enum" with one possible value for now.
// TODO: metadata & links
static public func openAPINode() throws -> JSONNode {
let nullable = Identifiable.self is _Optional.Type
return .object(.init(format: .generic,
required: true),
.init(properties: [
"data": ToOneRelationship.relationshipNode(nullable: nullable, jsonType: Identifiable.jsonType)
]))
}
}
extension ToManyRelationship: OpenAPINodeType {
// NOTE: const for json `type` not supported by OpenAPI 3.0
// Will use "enum" with one possible value for now.
// TODO: metadata & links
static public func openAPINode() throws -> JSONNode {
return .object(.init(format: .generic,
required: true),
.init(properties: [
"data": .array(.init(format: .generic,
required: true),
.init(items: ToManyRelationship.relationshipNode(nullable: false, jsonType: Relatable.jsonType)))
]))
}
}
extension Entity: OpenAPIEncodedNodeType where Description.Attributes: Sampleable, Description.Relationships: Sampleable {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
// NOTE: const for json `type` not supported by OpenAPI 3.0
// Will use "enum" with one possible value for now.
// TODO: metadata, links
let idNode: JSONNode? = Id.RawType.self != Unidentified.self
? JSONNode.string(.init(format: .generic,
required: true),
.init())
: nil
let idProperty = idNode.map { ("id", $0) }
let typeNode = JSONNode.string(.init(format: .generic,
required: true,
allowedValues: [.init(Entity.jsonType)]),
.init())
let typeProperty = ("type", typeNode)
let attributesNode: JSONNode? = Description.Attributes.self == NoAttributes.self
? nil
: try Description.Attributes.genericOpenAPINode(using: encoder)
let attributesProperty = attributesNode.map { ("attributes", $0) }
let relationshipsNode: JSONNode? = Description.Relationships.self == NoRelationships.self
? nil
: try Description.Relationships.genericOpenAPINode(using: encoder)
let relationshipsProperty = relationshipsNode.map { ("relationships", $0) }
let propertiesDict = Dictionary([
idProperty,
typeProperty,
attributesProperty,
relationshipsProperty
].compactMap { $0 }) { _, value in value }
return .object(.init(format: .generic,
required: true),
.init(properties: propertiesDict))
}
}
extension SingleResourceBody: OpenAPIEncodedNodeType where Entity: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return try Entity.openAPINode(using: encoder)
}
}
extension ManyResourceBody: OpenAPIEncodedNodeType where Entity: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
return .array(.init(format: .generic,
required: true),
.init(items: try Entity.openAPINode(using: encoder)))
}
}
extension Document: OpenAPIEncodedNodeType where PrimaryResourceBody: OpenAPIEncodedNodeType, IncludeType: OpenAPIEncodedNodeType {
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
// TODO: metadata, links, api description, errors
// TODO: represent data and errors as the two distinct possible outcomes
let primaryDataNode: JSONNode? = try PrimaryResourceBody.openAPINode(using: encoder)
let primaryDataProperty = primaryDataNode.map { ("data", $0) }
let includeNode: JSONNode?
do {
includeNode = try Includes<Include>.openAPINode(using: encoder)
} catch let err as OpenAPITypeError {
guard case .invalidNode = err else {
throw err
}
includeNode = nil
}
let includeProperty = includeNode.map { ("included", $0) }
let propertiesDict = Dictionary([
primaryDataProperty,
includeProperty
].compactMap { $0 }) { _, value in value }
return .object(.init(format: .generic,
required: true),
.init(properties: propertiesDict))
}
}
@@ -1,40 +0,0 @@
//
// Date+OpenAPI.swift
// JSONAPIOpenAPI
//
// Created by Mathew Polzin on 1/24/19.
//
import Foundation
extension Date: DateOpenAPINodeType {
public static func dateOpenAPINodeGuess(using encoder: JSONEncoder) -> JSONNode? {
switch encoder.dateEncodingStrategy {
case .deferredToDate, .custom:
// I don't know if we can say anything about this case without
// encoding the Date and looking at it, which is what `primitiveGuess()`
// does.
return nil
case .secondsSince1970,
.millisecondsSince1970:
return .number(.init(format: .double,
required: true),
.init())
case .iso8601:
return .string(.init(format: .dateTime,
required: true),
.init())
case .formatted(let formatter):
let hasTime = formatter.timeStyle != .none
let format: JSONTypeFormat.StringFormat = hasTime ? .dateTime : .date
return .string(.init(format: format,
required: true),
.init())
}
}
}
@@ -1,454 +0,0 @@
//
// OpenAPITypes+Codable.swift
// JSONAPIOpenAPI
//
// Created by Mathew Polzin on 1/14/19.
//
extension JSONNode.Context: Encodable {
private enum CodingKeys: String, CodingKey {
case type
case format
case allowedValues = "enum"
case nullable
case example
// case constantValue = "const"
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(format.jsonType, forKey: .type)
if format != Format.unspecified {
try container.encode(format, forKey: .format)
}
if allowedValues != nil {
try container.encode(allowedValues, forKey: .allowedValues)
}
// if constantValue != nil {
// try container.encode(constantValue, forKey: .constantValue)
// }
try container.encode(nullable, forKey: .nullable)
if example != nil {
try container.encode(example, forKey: .example)
}
}
}
extension JSONNode.NumericContext: Encodable {
private enum CodingKeys: String, CodingKey {
case multipleOf
case maximum
case exclusiveMaximum
case minimum
case exclusiveMinimum
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if multipleOf != nil {
try container.encode(multipleOf, forKey: .multipleOf)
}
if maximum != nil {
try container.encode(maximum, forKey: .maximum)
}
if exclusiveMaximum != nil {
try container.encode(exclusiveMaximum, forKey: .exclusiveMaximum)
}
if minimum != nil {
try container.encode(minimum, forKey: .minimum)
}
if exclusiveMinimum != nil {
try container.encode(exclusiveMinimum, forKey: .exclusiveMinimum)
}
}
}
extension JSONNode.StringContext: Encodable {
private enum CodingKeys: String, CodingKey {
case maxLength
case minLength
case pattern
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if maxLength != nil {
try container.encode(maxLength, forKey: .maxLength)
}
try container.encode(minLength, forKey: .minLength)
if pattern != nil {
try container.encode(pattern, forKey: .pattern)
}
}
}
extension JSONNode.ArrayContext: Encodable {
private enum CodingKeys: String, CodingKey {
case items
case maxItems
case minItems
case uniqueItems
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(items, forKey: .items)
if maxItems != nil {
try container.encode(maxItems, forKey: .maxItems)
}
try container.encode(minItems, forKey: .minItems)
try container.encode(uniqueItems, forKey: .uniqueItems)
}
}
extension JSONNode.ObjectContext : Encodable {
private enum CodingKeys: String, CodingKey {
case maxProperties
case minProperties
case properties
case additionalProperties
case required
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if maxProperties != nil {
try container.encode(maxProperties, forKey: .maxProperties)
}
try container.encode(properties, forKey: .properties)
if additionalProperties != nil {
try container.encode(additionalProperties, forKey: .additionalProperties)
}
try container.encode(requiredProperties, forKey: .required)
try container.encode(minProperties, forKey: .minProperties)
}
}
extension JSONNode: Encodable {
private enum SubschemaCodingKeys: String, CodingKey {
case allOf
case oneOf
case anyOf
case not
}
public func encode(to encoder: Encoder) throws {
switch self {
case .boolean(let context):
try context.encode(to: encoder)
case .object(let contextA as Encodable, let contextB as Encodable),
.array(let contextA as Encodable, let contextB as Encodable),
.number(let contextA as Encodable, let contextB as Encodable),
.integer(let contextA as Encodable, let contextB as Encodable),
.string(let contextA as Encodable, let contextB as Encodable):
try contextA.encode(to: encoder)
try contextB.encode(to: encoder)
case .all(of: let nodes):
var container = encoder.container(keyedBy: SubschemaCodingKeys.self)
try container.encode(nodes, forKey: .allOf)
case .one(of: let nodes):
var container = encoder.container(keyedBy: SubschemaCodingKeys.self)
try container.encode(nodes, forKey: .oneOf)
case .any(of: let nodes):
var container = encoder.container(keyedBy: SubschemaCodingKeys.self)
try container.encode(nodes, forKey: .anyOf)
case .not(let node):
var container = encoder.container(keyedBy: SubschemaCodingKeys.self)
try container.encode(node, forKey: .not)
case .reference(let reference):
var container = encoder.singleValueContainer()
try container.encode(reference)
}
}
}
extension JSONReference: Encodable {
private enum CodingKeys: String, CodingKey {
case ref = "$ref"
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
let referenceString: String = {
switch self {
case .file(let reference):
return reference
case .node(let reference):
return "#/\(Root.refName)/\(reference.refName)/\(reference.selector)"
}
}()
try container.encode(referenceString, forKey: .ref)
}
}
extension RefDict: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(dict)
}
}
extension OpenAPIResponse.Code: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
let string: String
switch self {
case .`default`:
string = "default"
case .status(code: let code):
string = String(code)
}
try container.encode(string)
}
}
extension OpenAPIRequestBody: Encodable {
private enum CodingKeys: String, CodingKey {
case description
case content
case required
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if description != nil {
try container.encode(description, forKey: .description)
}
// Hack to work around Dictionary encoding
// itself as an array in this case:
let stringKeyedDict = Dictionary(
content.map { ($0.key.rawValue, $0.value) },
uniquingKeysWith: { $1 }
)
try container.encode(stringKeyedDict, forKey: .content)
try container.encode(required, forKey: .required)
}
}
extension OpenAPIPathItem.PathProperties.Operation: Encodable {
private enum CodingKeys: String, CodingKey {
case tags
case summary
case description
case externalDocs
case operationId
case parameters
case requestBody
case responses
case callbacks
case deprecated
case security
case servers
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if tags != nil {
try container.encode(tags, forKey: .tags)
}
if summary != nil {
try container.encode(summary, forKey: .summary)
}
if description != nil {
try container.encode(description, forKey: .description)
}
try container.encode(operationId, forKey: .operationId)
try container.encode(parameters, forKey: .parameters)
if requestBody != nil {
try container.encode(requestBody, forKey: .requestBody)
}
// Hack to work around Dictionary encoding
// itself as an array in this case:
let stringKeyedDict = Dictionary(
responses.map { ($0.key.rawValue, $0.value) },
uniquingKeysWith: { $1 }
)
try container.encode(stringKeyedDict, forKey: .responses)
try container.encode(deprecated, forKey: .deprecated)
}
}
extension OpenAPIPathItem.PathProperties: Encodable {
private enum CodingKeys: String, CodingKey {
case summary
case description
case servers
case parameters
case get
case put
case post
case delete
case options
case head
case patch
case trace
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if summary != nil {
try container.encode(summary, forKey: .summary)
}
if description != nil {
try container.encode(description, forKey: .description)
}
try container.encode(parameters, forKey: .parameters)
if get != nil {
try container.encode(get, forKey: .get)
}
if put != nil {
try container.encode(put, forKey: .put)
}
if post != nil {
try container.encode(post, forKey: .post)
}
if delete != nil {
try container.encode(delete, forKey: .delete)
}
if options != nil {
try container.encode(options, forKey: .options)
}
if head != nil {
try container.encode(head, forKey: .head)
}
if patch != nil {
try container.encode(patch, forKey: .patch)
}
if trace != nil {
try container.encode(trace, forKey: .trace)
}
}
}
extension OpenAPIResponse: Encodable {
private enum CodingKeys: String, CodingKey {
case description
case headers
case content
case links
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(description, forKey: .description)
// Hack to work around Dictionary encoding
// itself as an array in this case:
let stringKeyedDict = Dictionary(
content.map { ($0.key.rawValue, $0.value) },
uniquingKeysWith: { $1 }
)
try container.encode(stringKeyedDict, forKey: .content)
}
}
extension OpenAPIPathItem: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .reference(let reference):
try container.encode(reference)
case .operations(let operations):
try container.encode(operations)
}
}
}
extension OpenAPISchema: Encodable {
private enum CodingKeys: String, CodingKey {
case openAPIVersion = "openapi"
case info
case servers
case paths
case components
case security
case tags
case externalDocs
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(openAPIVersion, forKey: .openAPIVersion)
try container.encode(info, forKey: .info)
// Hack to work around Dictionary encoding
// itself as an array in this case:
let stringKeyedDict = Dictionary(
paths.map { ($0.key.rawValue, $0.value) },
uniquingKeysWith: { $1 }
)
try container.encode(stringKeyedDict, forKey: .paths)
try container.encode(components, forKey: .components)
}
}
File diff suppressed because it is too large Load Diff
@@ -1,132 +0,0 @@
//
// PrimitiveTypes.swift
// JSONAPIOpenAPI
//
// Created by Mathew Polzin on 01/13/19.
//
import AnyCodable
import Foundation
/**
Notable omissions in this library's default offerings:
Base 64 encoded characters:
.string(.byte)
Any sequence of octets:
.string(.binary)
RFC3339 full-date:
.string(.date)
RFC3339 date-time:
.string(.dateTime)
A hint to UIs to obscure input:
.string(.password)
Any object:
.object(.generic)
**/
extension Optional: OpenAPINodeType where Wrapped: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
return try Wrapped.openAPINode().optionalNode()
}
}
extension Optional: RawOpenAPINodeType where Wrapped: RawRepresentable, Wrapped.RawValue: OpenAPINodeType {
static public func rawOpenAPINode() throws -> JSONNode {
return try Wrapped.RawValue.openAPINode().optionalNode()
}
}
extension Optional: WrappedRawOpenAPIType where Wrapped: RawOpenAPINodeType {
static public func wrappedOpenAPINode() throws -> JSONNode {
return try Wrapped.rawOpenAPINode().optionalNode()
}
}
extension Optional: DoubleWrappedRawOpenAPIType where Wrapped: WrappedRawOpenAPIType {
static public func wrappedOpenAPINode() throws -> JSONNode {
return try Wrapped.wrappedOpenAPINode().optionalNode()
}
}
extension Optional: AnyJSONCaseIterable where Wrapped: CaseIterable, Wrapped: Codable {
public static func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
return (try? allCases(from: Array(Wrapped.allCases), using: encoder)) ?? []
}
}
extension Optional: DateOpenAPINodeType where Wrapped: DateOpenAPINodeType {
static public func dateOpenAPINodeGuess(using encoder: JSONEncoder) -> JSONNode? {
return Wrapped.dateOpenAPINodeGuess(using: encoder)?.optionalNode()
}
}
extension String: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
return .string(.init(format: .generic,
required: true),
.init())
}
}
extension Bool: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
return .boolean(.init(format: .generic,
required: true))
}
}
extension Array: OpenAPINodeType where Element: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
return .array(.init(format: .generic,
required: true),
.init(items: try Element.openAPINode()))
}
}
extension Double: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
return .number(.init(format: .double,
required: true),
.init())
}
}
extension Float: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
return .number(.init(format: .float,
required: true),
.init())
}
}
extension Int: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
return .integer(.init(format: .generic,
required: true),
.init())
}
}
extension Int32: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
return .integer(.init(format: .int32,
required: true),
.init())
}
}
extension Int64: OpenAPINodeType {
static public func openAPINode() throws -> JSONNode {
return .integer(.init(format: .int64,
required: true),
.init())
}
}
@@ -1,13 +0,0 @@
//
// Optional+ZipWith.swift
// JSONAPIOpenAPI
//
// Created by Mathew Polzin on 1/19/19.
//
/// Zip two optionals together with the given operation performed on
/// the unwrapped contents. If either optional is nil, the zip
/// yields nil.
func zip<X, Y, Z>(_ left: X?, _ right: Y?, with fn: (X, Y) -> Z) -> Z? {
return left.flatMap { lft in right.map { rght in fn(lft, rght) }}
}
@@ -1,185 +0,0 @@
//
// Include+Sampleable.swift
// JSONAPIOpenAPI
//
// Created by Mathew Polzin on 1/23/19.
//
import JSONAPI
import Sampleable
extension Includes: Sampleable where I: Sampleable {
public static var sample: Includes<I> {
guard I.self != NoIncludes.self else {
return .none
}
return .init(values: I.samples)
}
}
extension NoIncludes: Sampleable {
public static var sample: NoIncludes {
return NoIncludes()
}
}
extension Include1: Sampleable where A: Sampleable {
public static var sample: Include1<A> {
return .init(A.sample)
}
public static var samples: [Include1<A>] {
return A.samples.map(Include1<A>.init)
}
}
extension Include2: Sampleable where A: Sampleable, B: Sampleable {
public static var sample: Include2<A, B> {
let randomChoice = Int.random(in: 0..<samples.count)
return samples[randomChoice]
}
public static var samples: [Include2<A, B>] {
return A.samples.map(Include2<A, B>.init)
+ B.samples.map(Include2<A, B>.init)
}
}
extension Include3: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable {
public static var sample: Include3<A, B, C> {
let randomChoice = Int.random(in: 0..<samples.count)
return samples[randomChoice]
}
public static var samples: [Include3<A, B, C>] {
return A.samples.map(Include3<A, B, C>.init)
+ B.samples.map(Include3<A, B, C>.init)
+ C.samples.map(Include3<A, B, C>.init)
}
}
extension Include4: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable {
public static var sample: Include4<A, B, C, D> {
let randomChoice = Int.random(in: 0..<samples.count)
return samples[randomChoice]
}
public static var samples: [Include4<A, B, C, D>] {
return A.samples.map(Include4<A, B, C, D>.init)
+ B.samples.map(Include4<A, B, C, D>.init)
+ C.samples.map(Include4<A, B, C, D>.init)
+ D.samples.map(Include4<A, B, C, D>.init)
}
}
extension Include5: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable {
public static var sample: Include5<A, B, C, D, E> {
let randomChoice = Int.random(in: 0..<samples.count)
return samples[randomChoice]
}
public static var samples: [Include5<A, B, C, D, E>] {
let set1: [Include5<A, B, C, D, E>] = A.samples.map(Include5<A, B, C, D, E>.init)
+ B.samples.map(Include5<A, B, C, D, E>.init)
+ C.samples.map(Include5<A, B, C, D, E>.init)
let set2: [Include5<A, B, C, D, E>] = D.samples.map(Include5<A, B, C, D, E>.init)
+ E.samples.map(Include5<A, B, C, D, E>.init)
return set1 + set2
}
}
extension Include6: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable, F: Sampleable {
public static var sample: Include6<A, B, C, D, E, F> {
let randomChoice = Int.random(in: 0..<samples.count)
return samples[randomChoice]
}
public static var samples: [Include6<A, B, C, D, E, F>] {
let set1: [Include6<A, B, C, D, E, F>] = A.samples.map(Include6<A, B, C, D, E, F>.init)
+ B.samples.map(Include6<A, B, C, D, E, F>.init)
+ C.samples.map(Include6<A, B, C, D, E, F>.init)
let set2: [Include6<A, B, C, D, E, F>] = D.samples.map(Include6<A, B, C, D, E, F>.init)
+ E.samples.map(Include6<A, B, C, D, E, F>.init)
+ F.samples.map(Include6<A, B, C, D, E, F>.init)
return set1 + set2
}
}
extension Include7: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable, F: Sampleable, G: Sampleable {
public static var sample: Include7<A, B, C, D, E, F, G> {
let randomChoice = Int.random(in: 0..<samples.count)
return samples[randomChoice]
}
public static var samples: [Include7<A, B, C, D, E, F, G>] {
let set1: [Include7<A, B, C, D, E, F, G>] = A.samples.map(Include7<A, B, C, D, E, F, G>.init)
+ B.samples.map(Include7<A, B, C, D, E, F, G>.init)
+ C.samples.map(Include7<A, B, C, D, E, F, G>.init)
let set2: [Include7<A, B, C, D, E, F, G>] = D.samples.map(Include7<A, B, C, D, E, F, G>.init)
+ E.samples.map(Include7<A, B, C, D, E, F, G>.init)
+ F.samples.map(Include7<A, B, C, D, E, F, G>.init)
let set3: [Include7<A, B, C, D, E, F, G>] = G.samples.map(Include7<A, B, C, D, E, F, G>.init)
return set1 + set2 + set3
}
}
extension Include8: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable, F: Sampleable, G: Sampleable, H: Sampleable {
public static var sample: Include8<A, B, C, D, E, F, G, H> {
let randomChoice = Int.random(in: 0..<samples.count)
return samples[randomChoice]
}
public static var samples: [Include8<A, B, C, D, E, F, G, H>] {
let set1: [Include8<A, B, C, D, E, F, G, H>] = A.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
+ B.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
+ C.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
let set2: [Include8<A, B, C, D, E, F, G, H>] = D.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
+ E.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
+ F.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
let set3: [Include8<A, B, C, D, E, F, G, H>] = G.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
+ H.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
return set1 + set2 + set3
}
}
extension Include9: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable, F: Sampleable, G: Sampleable, H: Sampleable, I: Sampleable {
public static var sample: Include9<A, B, C, D, E, F, G, H, I> {
let randomChoice = Int.random(in: 0..<samples.count)
return samples[randomChoice]
}
public static var samples: [Include9<A, B, C, D, E, F, G, H, I>] {
let set1: [Include9<A, B, C, D, E, F, G, H, I>] = A.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
+ B.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
+ C.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
let set2: [Include9<A, B, C, D, E, F, G, H, I>] = D.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
+ E.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
+ F.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
let set3: [Include9<A, B, C, D, E, F, G, H, I>] = G.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
+ H.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
+ I.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
return set1 + set2 + set3
}
}
@@ -1,69 +0,0 @@
//
// JSONAPI+Sampleable.swift
// JSONAPIOpenAPI
//
// Created by Mathew Polzin on 1/24/19.
//
import JSONAPI
import Sampleable
extension NoAttributes: Sampleable {
public static var sample: NoAttributes {
return .none
}
}
extension NoRelationships: Sampleable {
public static var sample: NoRelationships {
return .none
}
}
extension NoMetadata: Sampleable {
public static var sample: NoMetadata {
return .none
}
}
extension NoLinks: Sampleable {
public static var sample: NoLinks {
return .none
}
}
extension NoAPIDescription: Sampleable {
public static var sample: NoAPIDescription {
return .none
}
}
extension UnknownJSONAPIError: Sampleable {
public static var sample: UnknownJSONAPIError {
return .unknownError
}
}
extension Unidentified: Sampleable {
public static var sample: Unidentified {
return Unidentified()
}
}
extension Attribute: Sampleable where RawValue: Sampleable {
public static var sample: Attribute<RawValue> {
return .init(value: RawValue.sample)
}
}
extension SingleResourceBody: Sampleable where Entity: Sampleable {
public static var sample: SingleResourceBody<Entity> {
return .init(entity: Entity.sample)
}
}
extension ManyResourceBody: Sampleable where Entity: Sampleable {
public static var sample: ManyResourceBody<Entity> {
return .init(entities: Entity.samples)
}
}

Some files were not shown because too many files have changed in this diff Show More