Refactored the Amiibo Live client in the library target to reduce boilerplate.

This commit is contained in:
2026-07-26 01:42:47 +02:00
parent b9935d22b3
commit 43f47b0648
@@ -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.