Skip to content

Commit

Permalink
Merge pull request #7 from justeattakeaway/decoding-improvements
Browse files Browse the repository at this point in the history
Improve Decodable implementation
  • Loading branch information
albertodebortoli authored Aug 30, 2024
2 parents bbd95d8 + b7d03eb commit 351fae7
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 57 deletions.
51 changes: 51 additions & 0 deletions Sources/Core/Spec+Context.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Spec+Context.swift

import Foundation

extension Spec.Product {
func makeContext() -> [String: Any] {
[
"name": name,
"productType": productType.rawValue,
"targets": targets
]
}
}

extension Spec.RemoteDependency {
func makeContext() -> [String: Any] {
var retVal = [
"name": name,
"url": url
]
if let ref {
switch ref {
case .branch(let value):
retVal["branch"] = value
case .revision(let value):
retVal["revision"] = value
case .version(let value):
retVal["version"] = value
}
}
return retVal.compactMapValues { $0 }
}
}

extension Spec {
func makeContext() -> [String: Any] {
let values: [String: Any?] = [
"package_name": name,
"platforms": platforms,
"local_dependencies": localDependencies,
"remote_dependencies": remoteDependencies.map { $0.makeContext() },
"products": products.map { $0.makeContext() },
"targets": targets,
"local_binary_targets": localBinaryTargets,
"remote_binary_targets": remoteBinaryTargets,
"swift_tools_version": swiftToolsVersion,
"swift_versions": swiftLanguageVersions
]
return values.compactMapValues { $0 }
}
}
4 changes: 1 addition & 3 deletions Sources/Core/SpecGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ final class SpecGenerator {
return Spec.RemoteDependency(
name: dependency.name,
url: remoteDependency.url ?? dependency.url,
version: remoteDependency.version ?? dependency.version,
revision: remoteDependency.revision ?? dependency.revision,
branch: remoteDependency.branch ?? dependency.branch
ref: remoteDependency.ref ?? dependency.ref
)
}

Expand Down
26 changes: 15 additions & 11 deletions Sources/Models/Dependencies.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,23 @@ struct Dependencies: Decodable {
struct Dependency: Decodable {
let name: String
let url: String
let version: String?
let revision: String?
let branch: String?
let ref: Ref

init(name: String, url: String, version: String?, revision: String?, branch: String?) {
guard version != nil || revision != nil || branch != nil else {
fatalError("You need to provide at least one of the following: version, revision or branch")
}

enum CodingKeys: String, CodingKey {
case name
case url
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
self.url = try container.decode(String.self, forKey: .url)
self.ref = try Ref(from: decoder)
}

init(name: String, url: String, ref: Ref) {
self.name = name
self.url = url
self.version = version
self.revision = revision
self.branch = branch
self.ref = ref
}
}
29 changes: 29 additions & 0 deletions Sources/Models/Ref.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Ref.swift

import Foundation

enum Ref: Decodable {
case version(String)
case revision(String)
case branch(String)

enum CodingKeys: String, CodingKey {
case version
case revision
case branch
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

if let version = try container.decodeIfPresent(String.self, forKey: .version) {
self = .version(version)
} else if let revision = try container.decodeIfPresent(String.self, forKey: .revision) {
self = .revision(revision)
} else if let branch = try container.decodeIfPresent(String.self, forKey: .branch) {
self = .branch(branch)
} else {
throw DecodingError.dataCorruptedError(forKey: CodingKeys.version, in: container, debugDescription: "Expected one of version, revision, or branch to be present.")
}
}
}
48 changes: 5 additions & 43 deletions Sources/Models/Spec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,14 @@ struct Spec: Decodable {

struct Product: Decodable {
let name: String
let productType: String
let productType: ProductType
let targets: [String]

enum CodingKeys: CodingKey {
case name
case productType
case targets
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
self.productType = try container.decode(ProductType.self, forKey: .productType).rawValue
self.targets = try container.decode([String].self, forKey: .targets)
}
}

enum ProductType: String, Decodable {
Expand All @@ -39,37 +32,24 @@ struct Spec: Decodable {
struct RemoteDependency: Decodable {
let name: String
let url: String?
let version: String?
let revision: String?
let branch: String?
let ref: Ref?

enum CodingKeys: CodingKey {
case name
case url
case version
case revision
case branch
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
self.url = try container.decodeIfPresent(String.self, forKey: .url)
self.version = try container.decodeIfPresent(String.self, forKey: .version)
self.revision = try container.decodeIfPresent(String.self, forKey: .revision)
self.branch = try container.decodeIfPresent(String.self, forKey: .branch)
self.ref = try? Ref(from: decoder)
}

init(name: String, url: String, version: String?, revision: String?, branch: String?) {
guard version != nil || revision != nil || branch != nil else {
fatalError("You need to provide at least one of the following: version, revision or branch")
}

init(name: String, url: String, ref: Ref) {
self.name = name
self.url = url
self.version = version
self.revision = revision
self.branch = branch
self.ref = ref
}
}

Expand Down Expand Up @@ -181,21 +161,3 @@ struct Spec: Decodable {
self.swiftLanguageVersions = swiftLanguageVersions
}
}

extension Spec {
func makeContext() -> [String: Any] {
let values: [String: Any?] = [
"package_name": name,
"platforms": platforms,
"local_dependencies": localDependencies,
"remote_dependencies": remoteDependencies,
"products": products,
"targets": targets,
"local_binary_targets": localBinaryTargets,
"remote_binary_targets": remoteBinaryTargets,
"swift_tools_version": swiftToolsVersion,
"swift_versions": swiftLanguageVersions
]
return values.compactMapValues { $0 }
}
}

0 comments on commit 351fae7

Please sign in to comment.