forked from vapor/vapor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Validations.swift
70 lines (60 loc) 路 2.37 KB
/
Validations.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
public struct Validations {
var storage: [Validation]
public init() {
self.storage = []
}
public mutating func add<T>(
_ key: ValidationKey,
as type: T.Type = T.self,
is validator: Validator<T> = .valid,
required: Bool = true
) {
let validation = Validation(key: key, required: required, validator: validator)
self.storage.append(validation)
}
public mutating func add(
_ key: ValidationKey,
result: ValidatorResult
) {
let validation = Validation(key: key, result: result)
self.storage.append(validation)
}
public mutating func add(
_ key: ValidationKey,
required: Bool = true,
_ nested: (inout Validations) -> ()
) {
var validations = Validations()
nested(&validations)
let validation = Validation(key: key, required: required, nested: validations)
self.storage.append(validation)
}
public func validate(request: Request) throws -> ValidationsResult {
guard let contentType = request.headers.contentType else {
throw Abort(.unprocessableEntity)
}
guard let body = request.body.data else {
throw Abort(.unprocessableEntity)
}
let contentDecoder = try ContentConfiguration.global.requireDecoder(for: contentType)
let decoder = try contentDecoder.decode(DecoderUnwrapper.self, from: body, headers: request.headers)
return try self.validate(decoder.decoder)
}
public func validate(query: URI) throws -> ValidationsResult {
let urlDecoder = try ContentConfiguration.global.requireURLDecoder()
let decoder = try urlDecoder.decode(DecoderUnwrapper.self, from: query)
return try self.validate(decoder.decoder)
}
public func validate(json: String) throws -> ValidationsResult {
let decoder = try JSONDecoder().decode(DecoderUnwrapper.self, from: Data(json.utf8))
return try self.validate(decoder.decoder)
}
public func validate(_ decoder: Decoder) throws -> ValidationsResult {
try self.validate(decoder.container(keyedBy: ValidationKey.self))
}
internal func validate(_ decoder: KeyedDecodingContainer<ValidationKey>) -> ValidationsResult {
.init(results: self.storage.map {
$0.run(decoder)
})
}
}