Refactored the Amiibo Live client in the library target to reduce boilerplate.
This commit is contained in:
@@ -130,10 +130,8 @@ private extension AmiiboLiveClient {
|
||||
func fetchAmiibos(
|
||||
_ filter: AmiiboFilter
|
||||
) async throws(AmiiboServiceError) -> [Amiibo] {
|
||||
let response: Operations.getAmiibos.Output
|
||||
|
||||
do {
|
||||
response = try await client.getAmiibos(.init(query: .init(
|
||||
let response = try await perform {
|
||||
try await client.getAmiibos(.init(query: .init(
|
||||
id: filter.identifier,
|
||||
head: filter.head,
|
||||
tail: filter.tail,
|
||||
@@ -145,8 +143,6 @@ private extension AmiiboLiveClient {
|
||||
showgames: filter.showGames,
|
||||
showusage: filter.showUsage
|
||||
)))
|
||||
} catch {
|
||||
try handle(error: error)
|
||||
}
|
||||
|
||||
switch response {
|
||||
@@ -182,15 +178,11 @@ private extension AmiiboLiveClient {
|
||||
func fetchAmiiboSeries(
|
||||
_ filter: AmiiboSeriesFilter
|
||||
) async throws(AmiiboServiceError) -> [AmiiboSeries] {
|
||||
let response: Operations.getAmiiboSeries.Output
|
||||
|
||||
do {
|
||||
response = try await client.getAmiiboSeries(.init(query: .init(
|
||||
let response = try await perform {
|
||||
try await client.getAmiiboSeries(.init(query: .init(
|
||||
key: filter.key,
|
||||
name: filter.name
|
||||
)))
|
||||
} catch {
|
||||
try handle(error: error)
|
||||
}
|
||||
|
||||
switch response {
|
||||
@@ -199,11 +191,9 @@ private extension AmiiboLiveClient {
|
||||
case let .json(output):
|
||||
switch output.amiibo {
|
||||
case let .AmiiboSeries(payload):
|
||||
return [AmiiboSeries(payload.value1)]
|
||||
return makeModels(from: [payload.value1])
|
||||
case let .case2(list):
|
||||
return list
|
||||
.map { AmiiboSeries($0.value1) }
|
||||
.sorted { $0.key < $1.key }
|
||||
return makeModels(from: list.map(\.value1))
|
||||
}
|
||||
}
|
||||
case .badRequest:
|
||||
@@ -224,15 +214,11 @@ private extension AmiiboLiveClient {
|
||||
func fetchAmiiboTypes(
|
||||
_ filter: AmiiboTypeFilter
|
||||
) async throws(AmiiboServiceError) -> [AmiiboType] {
|
||||
let response: Operations.getAmiiboTypes.Output
|
||||
|
||||
do {
|
||||
response = try await client.getAmiiboTypes(.init(query: .init(
|
||||
let response = try await perform {
|
||||
try await client.getAmiiboTypes(.init(query: .init(
|
||||
key: filter.key,
|
||||
name: filter.name
|
||||
)))
|
||||
} catch {
|
||||
try handle(error: error)
|
||||
}
|
||||
|
||||
switch response {
|
||||
@@ -241,11 +227,9 @@ private extension AmiiboLiveClient {
|
||||
case let .json(output):
|
||||
switch output.amiibo {
|
||||
case let .AmiiboType(payload):
|
||||
return [AmiiboType(payload.value1)]
|
||||
return makeModels(from: [payload.value1])
|
||||
case let .case2(list):
|
||||
return list
|
||||
.map { AmiiboType($0.value1) }
|
||||
.sorted { $0.key < $1.key }
|
||||
return makeModels(from: list.map(\.value1))
|
||||
}
|
||||
}
|
||||
case .badRequest:
|
||||
@@ -266,15 +250,11 @@ private extension AmiiboLiveClient {
|
||||
func fetchGameCharacters(
|
||||
_ filter: GameCharacterFilter
|
||||
) async throws(AmiiboServiceError) -> [GameCharacter] {
|
||||
let response: Operations.getGameCharacters.Output
|
||||
|
||||
do {
|
||||
response = try await client.getGameCharacters(.init(query: .init(
|
||||
let response = try await perform {
|
||||
try await client.getGameCharacters(.init(query: .init(
|
||||
key: filter.key,
|
||||
name: filter.name
|
||||
)))
|
||||
} catch {
|
||||
try handle(error: error)
|
||||
}
|
||||
|
||||
switch response {
|
||||
@@ -283,11 +263,9 @@ private extension AmiiboLiveClient {
|
||||
case let .json(output):
|
||||
switch output.amiibo {
|
||||
case let .GameCharacter(payload):
|
||||
return [GameCharacter(payload.value1)]
|
||||
return makeModels(from: [payload.value1])
|
||||
case let .case2(list):
|
||||
return list
|
||||
.map { GameCharacter($0.value1) }
|
||||
.sorted { $0.key < $1.key }
|
||||
return makeModels(from: list.map(\.value1))
|
||||
}
|
||||
}
|
||||
case .badRequest:
|
||||
@@ -308,15 +286,11 @@ private extension AmiiboLiveClient {
|
||||
func fetchGameSeries(
|
||||
_ filter: GameSeriesFilter
|
||||
) async throws(AmiiboServiceError) -> [GameSeries] {
|
||||
let response: Operations.getGameSeries.Output
|
||||
|
||||
do {
|
||||
response = try await client.getGameSeries(.init(query: .init(
|
||||
let response = try await perform {
|
||||
try await client.getGameSeries(.init(query: .init(
|
||||
key: filter.key,
|
||||
name: filter.name
|
||||
)))
|
||||
} catch {
|
||||
try handle(error: error)
|
||||
}
|
||||
|
||||
switch response {
|
||||
@@ -325,11 +299,9 @@ private extension AmiiboLiveClient {
|
||||
case let .json(output):
|
||||
switch output.amiibo {
|
||||
case let .GameSeries(payload):
|
||||
return [GameSeries(payload.value1)]
|
||||
return makeModels(from: [payload.value1])
|
||||
case let .case2(list):
|
||||
return list
|
||||
.map { GameSeries($0.value1) }
|
||||
.sorted { $0.key < $1.key }
|
||||
return makeModels(from: list.map(\.value1))
|
||||
}
|
||||
}
|
||||
case .badRequest:
|
||||
@@ -347,12 +319,8 @@ private extension AmiiboLiveClient {
|
||||
/// - Returns: A fetched last updated date.
|
||||
/// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result.
|
||||
func fetchLastUpdated() async throws(AmiiboServiceError) -> Date {
|
||||
let response: Operations.getLastUpdated.Output
|
||||
|
||||
do {
|
||||
response = try await client.getLastUpdated()
|
||||
} catch {
|
||||
try handle(error: error)
|
||||
let response = try await perform {
|
||||
try await client.getLastUpdated()
|
||||
}
|
||||
|
||||
switch response {
|
||||
@@ -368,6 +336,29 @@ private extension AmiiboLiveClient {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an API call, mapping any error thrown by the underlying client to an ``AmiiboServiceError`` error.
|
||||
/// - Parameter operation: A closure that performs the API call.
|
||||
/// - Returns: The output of the performed API call.
|
||||
/// - Throws: An ``AmiiboServiceError`` error in case the API call failed.
|
||||
func perform<Output>(
|
||||
_ operation: () async throws -> Output
|
||||
) async throws(AmiiboServiceError) -> Output {
|
||||
do {
|
||||
return try await operation()
|
||||
} catch {
|
||||
try handle(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
/// Maps a list of key-name tuples into a sorted list of models.
|
||||
/// - Parameter tuples: A list of tuples to map into models.
|
||||
/// - Returns: A list of models sorted by their keys in ascending order.
|
||||
func makeModels<Model: KeyNameModel>(from tuples: [Components.Schemas.Tuple]) -> [Model] {
|
||||
tuples
|
||||
.map { Model($0) }
|
||||
.sorted { $0.key < $1.key }
|
||||
}
|
||||
|
||||
/// Maps a given error to an ``AmiiboServiceError`` error.
|
||||
/// - Parameter error: An error to map.
|
||||
/// - Throws: An ``AmiiboServiceError`` error that corresponds to the given error.
|
||||
|
||||
Reference in New Issue
Block a user