diff --git a/Sources/AmiiboService/Public/Clients/AmiiboLiveClient.swift b/Sources/AmiiboService/Public/Clients/AmiiboLiveClient.swift index 01ff620..6ee2cfe 100644 --- a/Sources/AmiiboService/Public/Clients/AmiiboLiveClient.swift +++ b/Sources/AmiiboService/Public/Clients/AmiiboLiveClient.swift @@ -51,44 +51,7 @@ extension AmiiboLiveClient: AmiiboClient { public func getAmiibos( by filter: AmiiboFilter ) async throws(AmiiboServiceError) -> [Amiibo] { - let response: Operations.getAmiibos.Output - - do { - response = try await client.getAmiibos( - .init(query: .init( - amiiboSeries: filter.series, - character: filter.gameCharacter, - gameseries: filter.gameSeries, - id: filter.identifier, - name: filter.name, - showgames: filter.showGames, - showusage: filter.showUsage, - _type: filter.type - )) - ) - } catch let error as ClientError { - if error.underlyingError is DecodingError { - throw AmiiboServiceError.decoding - } else { - throw AmiiboServiceError.unknown - } - } catch { - throw AmiiboServiceError.unknown - } - - switch response { - case let .ok(ok): - switch ok.body { - case let .json(output): - return map(output) - } - - case .badRequest: - throw AmiiboServiceError.badRequest - - case let .undocumented(statusCode, _): - throw AmiiboServiceError.undocumented(statusCode) - } + try await fetchAmiibos(filter) } /// Gets a list of amiibo series based on a given filter. @@ -98,38 +61,7 @@ extension AmiiboLiveClient: AmiiboClient { public func getAmiiboSeries( by filter: AmiiboSeriesFilter ) async throws(AmiiboServiceError) -> [AmiiboSeries] { - let response: Operations.getAmiiboSeries.Output - - do { - response = try await client.getAmiiboSeries( - .init(query: .init( - key: filter.key, - name: filter.name - )) - ) - } catch { - throw AmiiboServiceError.unknown - } - - switch response { - case let .ok(ok): - switch ok.body { - case let .json(output): - return map(output, as: AmiiboSeries.self) - } - - case .badRequest: - throw AmiiboServiceError.badRequest - - case .internalServerError: - throw AmiiboServiceError.notAvailable - - case .notFound: - throw AmiiboServiceError.notFound - - case let .undocumented(statusCode, _): - throw AmiiboServiceError.undocumented(statusCode) - } + try await fetchAmiiboSeries(filter) } /// Gets a list of amiibo types based on a given filter. @@ -139,38 +71,7 @@ extension AmiiboLiveClient: AmiiboClient { public func getAmiiboTypes( by filter: AmiiboTypeFilter ) async throws(AmiiboServiceError) -> [AmiiboType] { - let response: Operations.getAmiiboTypes.Output - - do { - response = try await client.getAmiiboTypes( - .init(query: .init( - key: filter.key, - name: filter.name - )) - ) - } catch { - throw AmiiboServiceError.unknown - } - - switch response { - case let .ok(ok): - switch ok.body { - case let .json(output): - return map(output, as: AmiiboType.self) - } - - case .badRequest: - throw AmiiboServiceError.badRequest - - case .internalServerError: - throw AmiiboServiceError.notAvailable - - case .notFound: - throw AmiiboServiceError.notFound - - case let .undocumented(statusCode, _): - throw AmiiboServiceError.undocumented(statusCode) - } + try await fetchAmiiboTypes(filter) } /// Gets a list of game characters based on a given filter. @@ -180,38 +81,7 @@ extension AmiiboLiveClient: AmiiboClient { public func getGameCharacters( by filter: GameCharacterFilter ) async throws(AmiiboServiceError) -> [GameCharacter] { - let response: Operations.getGameCharacters.Output - - do { - response = try await client.getGameCharacters( - .init(query: .init( - key: filter.key, - name: filter.name - )) - ) - } catch { - throw AmiiboServiceError.unknown - } - - switch response { - case let .ok(ok): - switch ok.body { - case let .json(output): - return map(output, as: GameCharacter.self) - } - - case .badRequest: - throw AmiiboServiceError.badRequest - - case .internalServerError: - throw AmiiboServiceError.notAvailable - - case .notFound: - throw AmiiboServiceError.notFound - - case let .undocumented(statusCode, _): - throw AmiiboServiceError.undocumented(statusCode) - } + try await fetchGameCharacters(filter) } /// Gets a list of game series based on a given filter. @@ -221,62 +91,14 @@ extension AmiiboLiveClient: AmiiboClient { public func getGameSeries( by filter: GameSeriesFilter ) async throws(AmiiboServiceError) -> [GameSeries] { - let response: Operations.getGameSeries.Output - - do { - response = try await client.getGameSeries( - .init(query: .init( - key: filter.key, - name: filter.name - )) - ) - } catch { - throw AmiiboServiceError.unknown - } - - switch response { - case let .ok(ok): - switch ok.body { - case let .json(output): - return map(output, as: GameSeries.self) - } - - case .badRequest: - throw AmiiboServiceError.badRequest - - case .internalServerError: - throw AmiiboServiceError.notAvailable - - case .notFound: - throw AmiiboServiceError.notFound - - case let .undocumented(statusCode, _): - throw AmiiboServiceError.undocumented(statusCode) - } + try await fetchGameSeries(filter) } /// Gets the date when the data was last updated. /// - Returns: A last updated date. /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. public func getLastUpdated() async throws(AmiiboServiceError) -> Date { - let response: Operations.getLastUpdated.Output - - do { - response = try await client.getLastUpdated() - } catch { - throw AmiiboServiceError.unknown - } - - switch response { - case let .ok(ok): - switch ok.body { - case let .json(output): - return output.lastUpdated - } - - case let .undocumented(statusCode, _): - throw AmiiboServiceError.undocumented(statusCode) - } + try await fetchLastUpdated() } #else /// Gets a list of amiibo items based on a given filter. @@ -285,6 +107,72 @@ extension AmiiboLiveClient: AmiiboClient { /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. public func getAmiibos( by filter: AmiiboFilter + ) async throws -> [Amiibo] { + try await fetchAmiibos(filter) + } + + /// Gets a list of amiibo series based on a given filter. + /// - Parameter filter: A filter to remove unwanted items from the result. + /// - Returns: A list of filtered amiibo series. + /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. + public func getAmiiboSeries( + by filter: AmiiboSeriesFilter + ) async throws -> [AmiiboSeries] { + try await fetchAmiiboSeries(filter) + } + + /// Gets a list of amiibo types based on a given filter. + /// - Parameter filter: A filter to remove unwanted items from the result. + /// - Returns: A list of filtered amiibo types. + /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. + public func getAmiiboTypes( + by filter: AmiiboTypeFilter + ) async throws -> [AmiiboType] { + try await fetchAmiiboTypes(filter) + } + + /// Gets a list of game characters based on a given filter. + /// - Parameter filter: A filter to remove unwanted items from the result. + /// - Returns: A list of filtered game characters. + /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. + public func getGameCharacters( + by filter: GameCharacterFilter + ) async throws -> [GameCharacter] { + try await fetchGameCharacters(filter) + } + + /// Gets a list of game series based on a given filter. + /// - Parameter filter: A filter to remove unwanted items from the result. + /// - Returns: A list of filtered game series. + /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. + public func getGameSeries( + by filter: GameSeriesFilter + ) async throws -> [GameSeries] { + try await fetchGameSeries(filter) + } + + /// Gets the date when the data was last updated. + /// - Returns: A last updated date. + /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. + public func getLastUpdated() async throws -> Date { + try await fetchLastUpdated() + } +#endif + +} + +// MARK: - Helpers + +private extension AmiiboLiveClient { + + // MARK: Functions + + /// Fetches a list of amiibo items based on a given filter. + /// - Parameter filter: A filter to remove unwanted items from the result. + /// - Returns: A list of fetched amiibo items filtered, if requested. + /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. + func fetchAmiibos( + _ filter: AmiiboFilter ) async throws -> [Amiibo] { let response: Operations.getAmiibos.Output @@ -301,6 +189,8 @@ extension AmiiboLiveClient: AmiiboClient { _type: filter.type )) ) + } catch is CancellationError { + throw AmiiboServiceError.cancelled } catch let error as ClientError { if error.underlyingError is DecodingError { throw AmiiboServiceError.decoding @@ -317,21 +207,19 @@ extension AmiiboLiveClient: AmiiboClient { case let .json(output): return map(output) } - case .badRequest: throw AmiiboServiceError.badRequest - case let .undocumented(statusCode, _): throw AmiiboServiceError.undocumented(statusCode) } } - - /// Gets a list of amiibo series based on a given filter. + + /// Fetches a list of amiibo series based on a given filter. /// - Parameter filter: A filter to remove unwanted items from the result. - /// - Returns: A list of filtered amiibo series. + /// - Returns: A list of fetched amiibo series filtered, if requested. /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. - public func getAmiiboSeries( - by filter: AmiiboSeriesFilter + func fetchAmiiboSeries( + _ filter: AmiiboSeriesFilter ) async throws -> [AmiiboSeries] { let response: Operations.getAmiiboSeries.Output @@ -342,6 +230,8 @@ extension AmiiboLiveClient: AmiiboClient { name: filter.name )) ) + } catch is CancellationError { + throw AmiiboServiceError.cancelled } catch { throw AmiiboServiceError.unknown } @@ -352,27 +242,23 @@ extension AmiiboLiveClient: AmiiboClient { case let .json(output): return map(output, as: AmiiboSeries.self) } - case .badRequest: throw AmiiboServiceError.badRequest - case .internalServerError: throw AmiiboServiceError.notAvailable - case .notFound: throw AmiiboServiceError.notFound - case let .undocumented(statusCode, _): throw AmiiboServiceError.undocumented(statusCode) } } - /// Gets a list of amiibo types based on a given filter. + /// Fetches a list of amiibo types based on a given filter. /// - Parameter filter: A filter to remove unwanted items from the result. - /// - Returns: A list of filtered amiibo types. + /// - Returns: A list of fetched amiibo types filtered, if requested. /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. - public func getAmiiboTypes( - by filter: AmiiboTypeFilter + func fetchAmiiboTypes( + _ filter: AmiiboTypeFilter ) async throws -> [AmiiboType] { let response: Operations.getAmiiboTypes.Output @@ -383,6 +269,8 @@ extension AmiiboLiveClient: AmiiboClient { name: filter.name )) ) + } catch is CancellationError { + throw AmiiboServiceError.cancelled } catch { throw AmiiboServiceError.unknown } @@ -393,27 +281,23 @@ extension AmiiboLiveClient: AmiiboClient { case let .json(output): return map(output, as: AmiiboType.self) } - case .badRequest: throw AmiiboServiceError.badRequest - case .internalServerError: throw AmiiboServiceError.notAvailable - case .notFound: throw AmiiboServiceError.notFound - case let .undocumented(statusCode, _): throw AmiiboServiceError.undocumented(statusCode) } } - /// Gets a list of game characters based on a given filter. + /// Fetches a list of game characters based on a given filter. /// - Parameter filter: A filter to remove unwanted items from the result. - /// - Returns: A list of filtered game characters. + /// - Returns: A list of fetched game characters filtered, if requested. /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. - public func getGameCharacters( - by filter: GameCharacterFilter + func fetchGameCharacters( + _ filter: GameCharacterFilter ) async throws -> [GameCharacter] { let response: Operations.getGameCharacters.Output @@ -424,6 +308,8 @@ extension AmiiboLiveClient: AmiiboClient { name: filter.name )) ) + } catch is CancellationError { + throw AmiiboServiceError.cancelled } catch { throw AmiiboServiceError.unknown } @@ -434,27 +320,23 @@ extension AmiiboLiveClient: AmiiboClient { case let .json(output): return map(output, as: GameCharacter.self) } - case .badRequest: throw AmiiboServiceError.badRequest - case .internalServerError: throw AmiiboServiceError.notAvailable - case .notFound: throw AmiiboServiceError.notFound - case let .undocumented(statusCode, _): throw AmiiboServiceError.undocumented(statusCode) } } - /// Gets a list of game series based on a given filter. + /// Fetches a list of game series based on a given filter. /// - Parameter filter: A filter to remove unwanted items from the result. - /// - Returns: A list of filtered game series. + /// - Returns: A list of fetched game series filtered, if requested. /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. - public func getGameSeries( - by filter: GameSeriesFilter + func fetchGameSeries( + _ filter: GameSeriesFilter ) async throws -> [GameSeries] { let response: Operations.getGameSeries.Output @@ -465,6 +347,8 @@ extension AmiiboLiveClient: AmiiboClient { name: filter.name )) ) + } catch is CancellationError { + throw AmiiboServiceError.cancelled } catch { throw AmiiboServiceError.unknown } @@ -475,29 +359,27 @@ extension AmiiboLiveClient: AmiiboClient { case let .json(output): return map(output, as: GameSeries.self) } - case .badRequest: throw AmiiboServiceError.badRequest - case .internalServerError: throw AmiiboServiceError.notAvailable - case .notFound: throw AmiiboServiceError.notFound - case let .undocumented(statusCode, _): throw AmiiboServiceError.undocumented(statusCode) } } - /// Gets the date when the data was last updated. - /// - Returns: A last updated date. + /// Fetches the date when the data was last updated. + /// - Returns: A fetched last updated date. /// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result. - public func getLastUpdated() async throws -> Date { + func fetchLastUpdated() async throws -> Date { let response: Operations.getLastUpdated.Output do { response = try await client.getLastUpdated() + } catch is CancellationError { + throw AmiiboServiceError.cancelled } catch { throw AmiiboServiceError.unknown } @@ -508,20 +390,10 @@ extension AmiiboLiveClient: AmiiboClient { case let .json(output): return output.lastUpdated } - case let .undocumented(statusCode, _): throw AmiiboServiceError.undocumented(statusCode) } } -#endif - -} - -// MARK: - Helpers - -private extension AmiiboLiveClient { - - // MARK: Functions /// Retrieves a list of amiibo items from a wrapper container. /// - Parameter wrapper: A wrapper container that either has an object or a list of items. diff --git a/Sources/AmiiboService/Public/Errors/AmiiboServiceError.swift b/Sources/AmiiboService/Public/Errors/AmiiboServiceError.swift index 5e26afc..353e30d 100644 --- a/Sources/AmiiboService/Public/Errors/AmiiboServiceError.swift +++ b/Sources/AmiiboService/Public/Errors/AmiiboServiceError.swift @@ -14,6 +14,8 @@ public enum AmiiboServiceError: Error { /// A bad request has been given to the client. case badRequest + /// A call to an endpoint has been cancelled by the user. + case cancelled /// A response cannot be decoded. case decoding /// An online service is not currently available.