Skip to content

Commit ade72e0

Browse files
authored
Merge pull request #1 from ajevans99/schema-builders
Add Schema Builders
2 parents d5565a6 + 39274eb commit ade72e0

36 files changed

+1239
-227
lines changed

Sources/JSONResultBuilders/JSONBuilder.swift

-58
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import JSONSchema
2+
3+
@resultBuilder
4+
public struct JSONSchemaBuilder {
5+
public static func buildBlock(_ expression: JSONSchemaRepresentable) -> JSONSchemaRepresentable {
6+
expression
7+
}
8+
9+
public static func buildBlock(_ components: JSONSchemaRepresentable...) -> [JSONSchemaRepresentable] {
10+
components
11+
}
12+
13+
public static func buildBlock(_ components: [JSONSchemaRepresentable]) -> [JSONSchemaRepresentable] {
14+
components
15+
}
16+
17+
// MARK: Advanced builers
18+
19+
public static func buildOptional(_ component: JSONSchemaRepresentable?) -> JSONSchemaRepresentable {
20+
component ?? JSONNull()
21+
}
22+
23+
public static func buildEither(first: JSONSchemaRepresentable) -> JSONSchemaRepresentable {
24+
first
25+
}
26+
27+
public static func buildEither(second: JSONSchemaRepresentable) -> JSONSchemaRepresentable {
28+
second
29+
}
30+
31+
public static func buildArray(_ components: [JSONSchemaRepresentable]) -> [JSONSchemaRepresentable] {
32+
components
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import JSONSchema
2+
3+
public extension JSONSchemaRepresentable {
4+
func title(_ value: String) -> Self {
5+
var copy = self
6+
copy.annotations.title = value
7+
return copy
8+
}
9+
10+
func description(_ value: String) -> Self {
11+
var copy = self
12+
copy.annotations.description = value
13+
return copy
14+
}
15+
16+
func `default`(@JSONValueBuilder _ value: () -> JSONValueRepresentable) -> Self {
17+
var copy = self
18+
copy.annotations.default = value().value
19+
return copy
20+
}
21+
22+
func examples(@JSONValueBuilder _ examples: () -> JSONValueRepresentable) -> Self {
23+
var copy = self
24+
copy.annotations.examples = examples().value
25+
return copy
26+
}
27+
28+
func readOnly(_ value: Bool) -> Self {
29+
var copy = self
30+
copy.annotations.readOnly = value
31+
return copy
32+
}
33+
34+
func writeOnly(_ value: Bool) -> Self {
35+
var copy = self
36+
copy.annotations.writeOnly = value
37+
return copy
38+
}
39+
40+
func deprecated(_ value: Bool) -> Self {
41+
var copy = self
42+
copy.annotations.deprecated = value
43+
return copy
44+
}
45+
46+
func comment(_ value: String) -> Self {
47+
var copy = self
48+
copy.annotations.comment = value
49+
return copy
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import JSONSchema
2+
3+
public protocol JSONSchemaRepresentable {
4+
var schema: Schema { get }
5+
6+
var annotations: AnnotationOptions { get set }
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
@resultBuilder
2+
public struct JSONValueBuilder {
3+
public static func buildExpression(_ expression: JSONValueRepresentable?) -> JSONValueRepresentable {
4+
expression ?? JSONNullValue()
5+
}
6+
7+
public static func buildBlock(_ expression: JSONValueRepresentable...) -> JSONValueRepresentable {
8+
if expression.count == 1 {
9+
expression[0]
10+
} else {
11+
JSONArrayValue(elements: expression)
12+
}
13+
}
14+
15+
// MARK: Type hints
16+
17+
public static func buildExpression(_ expression: String) -> JSONStringValue {
18+
JSONStringValue(string: expression)
19+
}
20+
21+
public static func buildExpression(_ expression: Int) -> JSONIntegerValue {
22+
JSONIntegerValue(integer: expression)
23+
}
24+
25+
public static func buildExpression(_ expression: Double) -> JSONNumberValue {
26+
JSONNumberValue(number: expression)
27+
}
28+
29+
public static func buildExpression(_ expression: Bool) -> JSONBooleanValue {
30+
JSONBooleanValue(boolean: expression)
31+
}
32+
33+
public static func buildExpression(_ expression: [JSONValueRepresentable]) -> JSONArrayValue {
34+
JSONArrayValue(elements: expression)
35+
}
36+
37+
public static func buildExpression(_ expression: [String: JSONValueRepresentable]) -> JSONObjectValue {
38+
JSONObjectValue(properties: expression)
39+
}
40+
41+
// MARK: Additional array type hints
42+
43+
public static func buildExpression(_ expression: [String]) -> JSONArrayValue {
44+
JSONArrayValue(elements: expression.map { JSONStringValue(string: $0) })
45+
}
46+
47+
public static func buildExpression(_ expression: [Int]) -> JSONArrayValue {
48+
JSONArrayValue(elements: expression.map { JSONIntegerValue(integer: $0) })
49+
}
50+
51+
public static func buildExpression(_ expression: [Double]) -> JSONArrayValue {
52+
JSONArrayValue(elements: expression.map { JSONNumberValue(number: $0) })
53+
}
54+
55+
public static func buildExpression(_ expression: [Bool]) -> JSONArrayValue {
56+
JSONArrayValue(elements: expression.map { JSONBooleanValue(boolean: $0) })
57+
}
58+
59+
public static func buildExpression(_ expression: [JSONValueRepresentable?]) -> JSONArrayValue {
60+
JSONArrayValue(elements: expression.map { $0 ?? JSONNullValue() })
61+
}
62+
63+
// MARK: Addition dictionary type hints
64+
65+
public static func buildExpression(_ expression: [String: Int]) -> JSONObjectValue {
66+
JSONObjectValue(properties: expression.mapValues { JSONIntegerValue(integer: $0) })
67+
}
68+
69+
public static func buildExpression(_ expression: [String: Double]) -> JSONObjectValue {
70+
JSONObjectValue(properties: expression.mapValues { JSONNumberValue(number: $0) })
71+
}
72+
73+
public static func buildExpression(_ expression: [String: Bool]) -> JSONObjectValue {
74+
JSONObjectValue(properties: expression.mapValues { JSONBooleanValue(boolean: $0) })
75+
}
76+
77+
public static func buildExpression(_ expression: [String: String]) -> JSONObjectValue {
78+
JSONObjectValue(properties: expression.mapValues { JSONStringValue(string: $0) })
79+
}
80+
81+
public static func buildExpression(_ expression: [String: JSONValueRepresentable?]) -> JSONObjectValue {
82+
JSONObjectValue(properties: expression.mapValues { $0 ?? JSONNullValue() })
83+
}
84+
85+
// MARK: Advanced builers
86+
87+
public static func buildArray(_ components: [JSONValueRepresentable]) -> JSONValueRepresentable {
88+
JSONArrayValue(elements: components)
89+
}
90+
91+
public static func buildOptional(_ component: JSONValueRepresentable?) -> JSONValueRepresentable {
92+
component ?? JSONNullValue()
93+
}
94+
95+
public static func buildEither(first: JSONValueRepresentable) -> JSONValueRepresentable {
96+
first
97+
}
98+
99+
public static func buildEither(second: JSONValueRepresentable) -> JSONValueRepresentable {
100+
second
101+
}
102+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import JSONSchema
22

3-
public protocol JSONRepresentable {
3+
public protocol JSONValueRepresentable {
44
var value: JSONValue { get }
55
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
public struct JSONProperty {
2+
let key: String
3+
let value: JSONSchemaRepresentable
4+
5+
public init(key: String, @JSONSchemaBuilder builder: () -> JSONSchemaRepresentable) {
6+
self.key = key
7+
self.value = builder()
8+
}
9+
10+
public init(key: String, value: JSONSchemaRepresentable) {
11+
self.key = key
12+
self.value = value
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
@resultBuilder
2+
public struct JSONPropertySchemaBuilder {
3+
public static func buildBlock(_ components: [JSONProperty]...) -> [JSONProperty] {
4+
components.flatMap { $0 }
5+
}
6+
7+
public static func buildBlock(_ components: JSONProperty...) -> [JSONProperty] {
8+
components
9+
}
10+
11+
public static func buildEither(first component: [JSONProperty]) -> [JSONProperty] {
12+
component
13+
}
14+
15+
public static func buildEither(second component: [JSONProperty]) -> [JSONProperty] {
16+
component
17+
}
18+
19+
public static func buildOptional(_ component: [JSONProperty]?) -> [JSONProperty] {
20+
component ?? []
21+
}
22+
23+
public static func buildArray(_ components: [[JSONProperty]]) -> [JSONProperty] {
24+
components.flatMap { $0 }
25+
}
26+
}
27+
28+
extension JSONObject {
29+
public init(@JSONPropertySchemaBuilder _ content: () -> [JSONProperty]) {
30+
annotations = .annotations()
31+
options = .options(
32+
properties: content()
33+
.reduce(into: [:]) { partialResult, property in
34+
partialResult[property.key] = property.value.schema
35+
}
36+
)
37+
}
38+
}
39+
40+
@resultBuilder
41+
public struct JSONPropertyBuilder {
42+
public static func buildBlock(_ components: [JSONPropertyValue]...) -> [JSONPropertyValue] {
43+
components.flatMap { $0 }
44+
}
45+
46+
public static func buildBlock(_ components: JSONPropertyValue...) -> [JSONPropertyValue] {
47+
components
48+
}
49+
50+
public static func buildEither(first component: [JSONPropertyValue]) -> [JSONPropertyValue] {
51+
component
52+
}
53+
54+
public static func buildEither(second component: [JSONPropertyValue]) -> [JSONPropertyValue] {
55+
component
56+
}
57+
58+
public static func buildOptional(_ component: [JSONPropertyValue]?) -> [JSONPropertyValue] {
59+
component ?? []
60+
}
61+
62+
public static func buildArray(_ components: [[JSONPropertyValue]]) -> [JSONPropertyValue] {
63+
components.flatMap { $0 }
64+
}
65+
}
66+
67+
extension JSONObjectValue {
68+
public init(@JSONPropertyBuilder _ content: () -> [JSONPropertyValue]) {
69+
self.properties = content()
70+
.reduce(into: [:]) { partialResult, property in
71+
partialResult[property.key] = property.value
72+
}
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
public struct JSONPropertyValue {
2+
let key: String
3+
let value: JSONValueRepresentable
4+
5+
public init(key: String, @JSONValueBuilder builder: () -> JSONValueRepresentable) {
6+
self.key = key
7+
self.value = builder()
8+
}
9+
10+
public init(key: String, value: JSONValueRepresentable) {
11+
self.key = key
12+
self.value = value
13+
}
14+
}

Sources/JSONResultBuilders/Property/PropertyBuilder.swift

-15
This file was deleted.

Sources/JSONResultBuilders/Property/PropertyElement.swift

-14
This file was deleted.

0 commit comments

Comments
 (0)