You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.0 KiB
96 lines
3.0 KiB
import Model
|
|
|
|
public struct CodableRulesWrapper: Codable {
|
|
public let rules: any Rules
|
|
|
|
public init(of rules: any Rules) {
|
|
self.rules = rules
|
|
}
|
|
|
|
public init(from decoder: any Decoder) throws {
|
|
let container = try decoder.container(keyedBy: EnumCommonCodingKeys.self)
|
|
|
|
self.rules = try (try container.decode(RulesTypes.self, forKey: .type)).decodeRules(from: decoder)
|
|
}
|
|
|
|
public func encode(to encoder: any Encoder) throws {
|
|
var container = encoder.container(keyedBy: EnumCommonCodingKeys.self)
|
|
let type = self.rules.type
|
|
try container.encode(type, forKey: .type)
|
|
try (self.rules as! Encodable).encode(to: encoder)
|
|
}
|
|
}
|
|
|
|
extension RulesTypes: CodingKey, Codable {
|
|
public init(from decoder: any Decoder) throws {
|
|
self = (try CodableEnum<Self>(from: decoder)).variant
|
|
}
|
|
|
|
public func encode(to encoder: any Encoder) throws {
|
|
try CodableEnum(of: self).encode(to: encoder)
|
|
}
|
|
|
|
public func decodeRules(from decoder: any Decoder) throws -> any Rules {
|
|
switch self {
|
|
case .FourInARow: try FourInARowRules(from: decoder)
|
|
case .TicTacToe: try TicTacToeRules(from: decoder)
|
|
}
|
|
}
|
|
}
|
|
|
|
private enum CommonRulesCodingKeys: CodingKey {
|
|
case minAligned
|
|
}
|
|
|
|
extension FourInARowRules: Codable {
|
|
public init(from decoder: any Decoder) throws {
|
|
guard let context = decoder.userInfo[.gameDecodingContext] as? CodableContext else {
|
|
throw DeError.CodableContext
|
|
}
|
|
|
|
let container = try decoder.container(keyedBy: CommonRulesCodingKeys.self)
|
|
|
|
guard let zelf = Self.init(
|
|
columns: context.board!.columns,
|
|
rows: context.board!.rows,
|
|
minAligned: try container.decode(Int.self, forKey: .minAligned),
|
|
players: context.players!
|
|
) else {
|
|
throw DeError.InitializationFailed
|
|
}
|
|
|
|
self = zelf
|
|
}
|
|
|
|
public func encode(to encoder: any Encoder) throws {
|
|
var container = encoder.container(keyedBy: CommonRulesCodingKeys.self)
|
|
try container.encode(self.minAligned, forKey: .minAligned)
|
|
}
|
|
}
|
|
|
|
extension TicTacToeRules: Codable {
|
|
public init(from decoder: any Decoder) throws {
|
|
guard let context = decoder.userInfo[.gameDecodingContext] as? CodableContext else {
|
|
throw DeError.CodableContext
|
|
}
|
|
|
|
let container = try decoder.container(keyedBy: CommonRulesCodingKeys.self)
|
|
|
|
guard let zelf = Self.init(
|
|
columns: context.board!.columns,
|
|
rows: context.board!.rows,
|
|
minAligned: try container.decode(Int.self, forKey: .minAligned),
|
|
players: context.players!
|
|
) else {
|
|
throw DeError.InitializationFailed
|
|
}
|
|
|
|
self = zelf
|
|
}
|
|
|
|
public func encode(to encoder: any Encoder) throws {
|
|
var container = encoder.container(keyedBy: CommonRulesCodingKeys.self)
|
|
try container.encode(self.minAligned, forKey: .minAligned)
|
|
}
|
|
}
|