forked from realm/SwiftLint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathYamlParser.swift
76 lines (64 loc) · 2.2 KB
/
YamlParser.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
70
71
72
73
74
75
76
import Foundation
import Yams
// MARK: - YamlParsingError
internal enum YamlParserError: Error, Equatable {
case yamlParsing(String)
}
// MARK: - YamlParser
public struct YamlParser {
public static func parse(_ yaml: String,
env: [String: String] = ProcessInfo.processInfo.environment) throws -> [String: Any] {
do {
return try Yams.load(yaml: yaml, .default,
.swiftlintContructor(env: env)) as? [String: Any] ?? [:]
} catch {
throw YamlParserError.yamlParsing("\(error)")
}
}
public static func parseArray(_ yaml: String,
env: [String: String] = ProcessInfo.processInfo.environment) throws -> [[String: Any]] {
do {
return try Yams.load(yaml: yaml, .default,
.swiftlintContructor(env: env)) as? [[String: Any]] ?? []
} catch {
throw YamlParserError.yamlParsing("\(error)")
}
}
}
private extension Constructor {
static func swiftlintContructor(env: [String: String]) -> Constructor {
return Constructor(customScalarMap(env: env))
}
static func customScalarMap(env: [String: String]) -> ScalarMap {
var map = defaultScalarMap
map[.str] = String.constructExpandingEnvVars(env: env)
map[.bool] = Bool.constructUsingOnlyTrueAndFalse
return map
}
}
private extension String {
static func constructExpandingEnvVars(env: [String: String]) -> (_ scalar: Node.Scalar) -> String? {
return { (scalar: Node.Scalar) -> String? in
return scalar.string.expandingEnvVars(env: env)
}
}
func expandingEnvVars(env: [String: String]) -> String {
var result = self
for (key, value) in env {
result = result.replacingOccurrences(of: "${\(key)}", with: value)
}
return result
}
}
private extension Bool {
static func constructUsingOnlyTrueAndFalse(from scalar: Node.Scalar) -> Bool? {
switch scalar.string.lowercased() {
case "true":
return true
case "false":
return false
default:
return nil
}
}
}