Files

54 lines
1.6 KiB
Swift

import Foundation
/// Wire records are independent of domain values. Both file adapters convert
/// through the validated RuleMatch constructors before publishing any rules.
struct StoredProxyRule: Codable {
let action: String
let match: StoredRuleMatch
init(_ rule: ProxyRule) {
action = rule.action.rawValue
match = StoredRuleMatch(rule.match)
}
func domain() throws -> ProxyRule {
guard let action = RuleAction(rawValue: action) else {
throw RuleStorageDecodingError.invalidAction(action)
}
return ProxyRule(action: action, match: try match.domain())
}
}
struct StoredRuleMatch: Codable {
let kind: String
let value: String
init(_ match: RuleMatch) {
switch match.pattern {
case .domainExact(let raw): (kind, value) = ("domainExact", raw)
case .domainSuffix(let raw): (kind, value) = ("domainSuffix", raw)
case .ipv4CIDR(let raw): (kind, value) = ("ipv4CIDR", raw)
case .ipv6CIDR(let raw): (kind, value) = ("ipv6CIDR", raw)
}
}
func domain() throws -> RuleMatch {
switch kind {
case "domainExact": return try RuleMatch(domainExact: value)
case "domainSuffix":
if value == "local" { return .localSuffix }
if value == "localhost" { return .localhostSuffix }
return try RuleMatch(nationalDomainSuffix: value)
case "ipv4CIDR": return try RuleMatch(ipv4CIDR: value)
case "ipv6CIDR": return try RuleMatch(ipv6CIDR: value)
default: throw RuleStorageDecodingError.invalidMatchKind(kind)
}
}
}
enum RuleStorageDecodingError: Error {
case invalidAction(String)
case invalidMatchKind(String)
case invalidSource(String)
}