DocC documentation support (#4)
This PR contains the work done to: * Documented all the `private`, `internal`, and `public` interfaces on the existing codebase; * Set the DocC documentation catalog in the project; * Written the main `Library` article for the DocC documentation catalog; * Added the documentation tasks in the `Makefile` file. Reviewed-on: #4 Co-authored-by: Javier Cicchelli <javier@rock-n-code.com> Co-committed-by: Javier Cicchelli <javier@rock-n-code.com>
This commit was merged in pull request #4.
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
# --- DOCUMENTATION ---
|
||||
|
||||
DOCC_CATALOG_PATH=./Catalogs/AmiiboService.docc
|
||||
DOCC_GITHUB_OUTPUT=./docs
|
||||
DOCC_GITHUB_BASE_PATH=amiibo-service
|
||||
DOCC_PREVIEW_URL=http://localhost:8080/documentation/amiiboservice
|
||||
DOCC_XCODE_OUTPUT=./${SPM_LIBRARY_TARGET}.doccarchive
|
||||
|
||||
# -- SWIFT PACKAGE MANAGER ---
|
||||
|
||||
SPM_LIBRARY_TARGET=AmiiboService
|
||||
+4
-1
@@ -31,4 +31,7 @@ Packages/
|
||||
# hence it is not needed unless you have added a package configuration file to your project
|
||||
.swiftpm
|
||||
.swiftpm/configuration/registries.json
|
||||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
|
||||
|
||||
# DocC documentation
|
||||
*.doccarchive
|
||||
@@ -0,0 +1,74 @@
|
||||
# ``AmiiboService``
|
||||
|
||||
A library that provides everything the developer needs to interacts with the **Amiibo API** online service.
|
||||
|
||||
## Overview
|
||||
|
||||
The `AmiiboService` library is a Swift Package Manager package dependency aims at allowing the developer to interact with the [Amiibo API](https://www.amiiboapi.com) online service seamlessly, by not only providing the *service* tye but also any possible *clients*, *models*, *filters* and *errors* type that might be needed.
|
||||
|
||||
## Design
|
||||
|
||||
Although it could have been possible to generate a one-to-one RESTful client based on the Open API specification document that describe the available endpoints, it was decided to design a ``AmiiboService`` service that removes the complexities of the service's backend API, and provides the developer with a simple interface, and a seamless experience.
|
||||
|
||||
## Instalation
|
||||
|
||||
To use the `AmiiboService` library with your package, then add it as a dependency in the `Package.swift` file:
|
||||
|
||||
```swift
|
||||
let package = Package(
|
||||
// name, platforms, products, etc.
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/rock-n-code/amiibo-service", from: "1.0.0"),
|
||||
// other dependencies
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "SomeTarget",
|
||||
dependencies: [
|
||||
.product(name: "AmiiboService", package: "amiibo-service"),
|
||||
]
|
||||
)
|
||||
// other targets
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
It is also possible to use the `AmiiboService` library with your app in Xcode, then add it as a dependency in your Xcode project:
|
||||
|
||||
> important: Swift 5.9 or higher is required in order to compile this library.
|
||||
|
||||
## Topics
|
||||
|
||||
### Service
|
||||
|
||||
- ``AmiiboService``
|
||||
|
||||
### Clients
|
||||
|
||||
- ``AmiiboClient``
|
||||
- ``AmiiboLiveClient``
|
||||
- ``AmiiboMockClient``
|
||||
|
||||
### Models
|
||||
|
||||
- ``Amiibo``
|
||||
- ``Amiibo/Game``
|
||||
- ``Amiibo/Platform``
|
||||
- ``Amiibo/Release``
|
||||
- ``Amiibo/Usage``
|
||||
- ``AmiiboSeries``
|
||||
- ``AmiiboType``
|
||||
- ``GameCharacter``
|
||||
- ``GameSeries``
|
||||
|
||||
### Filters
|
||||
|
||||
- ``AmiiboFilter``
|
||||
- ``AmiiboSeriesFilter``
|
||||
- ``AmiiboTypeFilter``
|
||||
- ``GameCharacterFilter``
|
||||
- ``GameSeriesFilter``
|
||||
|
||||
### Errors
|
||||
|
||||
- ``AmiiboServiceError``
|
||||
@@ -17,14 +17,6 @@ environment ?= .env
|
||||
include $(environment)
|
||||
export $(shell sed 's/=.*//' $(environment))
|
||||
|
||||
# IDE
|
||||
|
||||
open-in-xcode: ## Opens this package with Xcode
|
||||
@open -a Xcode Package.swift
|
||||
|
||||
open-in-vscode: ## Opens this package with Visual Studio Code
|
||||
@code .
|
||||
|
||||
# SWIFT PACKAGE MANAGER
|
||||
|
||||
package-build: ## Builds the project locally
|
||||
@@ -41,6 +33,45 @@ package-reset: ## Resets the complete SPM cache/build folder from the package
|
||||
|
||||
package-update: ## Updates the SPM package dependencies
|
||||
@swift package update
|
||||
|
||||
# DOCUMENTATION
|
||||
|
||||
doc-generate: doc-generate-xcode doc-generate-github ## Generates the library documentation for both Github and Xcode
|
||||
|
||||
doc-generate-github: ## Generates the library documentation for Github
|
||||
@swift package \
|
||||
--allow-writing-to-directory $(DOCC_GITHUB_OUTPUT) \
|
||||
generate-documentation \
|
||||
$(DOCC_CATALOG_PATH) \
|
||||
--target $(SPM_LIBRARY_TARGET) \
|
||||
--disable-indexing \
|
||||
--transform-for-static-hosting \
|
||||
--hosting-base-path $(DOCC_GITHUB_BASE_PATH) \
|
||||
--output-path $(DOCC_GITHUB_OUTPUT)
|
||||
|
||||
doc-generate-xcode: ## Generates the library documentation for Xcode
|
||||
@swift package \
|
||||
--allow-writing-to-directory $(DOCC_XCODE_OUTPUT) \
|
||||
generate-documentation \
|
||||
$(DOCC_CATALOG_PATH) \
|
||||
--target $(SPM_LIBRARY_TARGET) \
|
||||
--output-path $(DOCC_XCODE_OUTPUT)
|
||||
|
||||
doc-preview: ## Previews the library documentation in Safari
|
||||
@open -a safari $(DOCC_PREVIEW_URL)
|
||||
@swift package \
|
||||
--disable-sandbox \
|
||||
preview-documentation \
|
||||
$(DOCC_CATALOG_PATH) \
|
||||
--target $(SPM_LIBRARY_TARGET)
|
||||
|
||||
# IDE
|
||||
|
||||
open-in-xcode: ## Opens this package with Xcode
|
||||
@open -a Xcode Package.swift
|
||||
|
||||
open-in-vscode: ## Opens this package with Visual Studio Code
|
||||
@code .
|
||||
|
||||
# HELP
|
||||
|
||||
|
||||
+8
-27
@@ -26,44 +26,25 @@ let package = Package(
|
||||
products: [
|
||||
.library(
|
||||
name: AmiiboService.package,
|
||||
targets: [
|
||||
AmiiboService.target
|
||||
]
|
||||
targets: [AmiiboService.target]
|
||||
)
|
||||
],
|
||||
dependencies: [
|
||||
.package(
|
||||
url: "https://github.com/apple/swift-openapi-generator.git",
|
||||
from: "1.3.0"
|
||||
),
|
||||
.package(
|
||||
url: "https://github.com/apple/swift-openapi-runtime",
|
||||
from: "1.5.0"
|
||||
),
|
||||
.package(
|
||||
url: "https://github.com/apple/swift-openapi-urlsession",
|
||||
from: "1.0.2"
|
||||
)
|
||||
.package(url: "https://github.com/apple/swift-openapi-generator.git", from: "1.3.0"),
|
||||
.package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.5.0"),
|
||||
.package(url: "https://github.com/apple/swift-openapi-urlsession", from: "1.0.2"),
|
||||
.package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.1.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: AmiiboService.target,
|
||||
dependencies: [
|
||||
.product(
|
||||
name: "OpenAPIRuntime",
|
||||
package: "swift-openapi-runtime"
|
||||
),
|
||||
.product(
|
||||
name: "OpenAPIURLSession",
|
||||
package: "swift-openapi-urlsession"
|
||||
)
|
||||
.product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"),
|
||||
.product(name: "OpenAPIURLSession", package: "swift-openapi-urlsession")
|
||||
],
|
||||
path: "Sources",
|
||||
plugins: [
|
||||
.plugin(
|
||||
name: "OpenAPIGenerator",
|
||||
package: "swift-openapi-generator"
|
||||
),
|
||||
.plugin(name: "OpenAPIGenerator", package: "swift-openapi-generator"),
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
|
||||
@@ -14,7 +14,13 @@ import Foundation
|
||||
|
||||
extension DateFormatter {
|
||||
|
||||
static var isoDateTime: DateFormatter {
|
||||
// MARK: Properties
|
||||
|
||||
/// An ISO timestamp formatter.
|
||||
///
|
||||
/// This formatter implements the `yyyy-MM-dd'T'HH:mm:ss.SSSSSS` custom date format.
|
||||
/// Within the context of this library, this formatter is solely used to decode a date formatted as a timestamp that is returned by the ``AmiiboService/getLastUpdated()`` function.
|
||||
static var isoTimestamp: DateFormatter {
|
||||
let formatter = DateFormatter()
|
||||
|
||||
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS"
|
||||
|
||||
@@ -12,15 +12,44 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol APIClient {
|
||||
/// A protocol that defines API clients containing all available endpoints to interact with.
|
||||
protocol APIClient {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
func getAmiibos(by filter: AmiiboFilter) async throws -> [Amiibo]
|
||||
func getAmiiboSeries(by filter: AmiiboSeriesFilter) async throws -> [AmiiboSeries]
|
||||
func getAmiiboTypes(by filter: AmiiboTypeFilter) async throws -> [AmiiboType]
|
||||
func getGameCharacters(by filter: GameCharacterFilter) async throws -> [GameCharacter]
|
||||
func getGameSeries(by filter: GameSeriesFilter) async throws -> [GameSeries]
|
||||
func getLastUpdated() async throws -> Date
|
||||
/// Gets 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 filtered amiibo items.
|
||||
/// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result.
|
||||
func getAmiibos(by filter: AmiiboFilter) async throws(AmiiboServiceError) -> [Amiibo]
|
||||
|
||||
/// 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.
|
||||
func getAmiiboSeries(by filter: AmiiboSeriesFilter) async throws(AmiiboServiceError) -> [AmiiboSeries]
|
||||
|
||||
/// 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.
|
||||
func getAmiiboTypes(by filter: AmiiboTypeFilter) async throws(AmiiboServiceError) -> [AmiiboType]
|
||||
|
||||
/// 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.
|
||||
func getGameCharacters(by filter: GameCharacterFilter) async throws(AmiiboServiceError) -> [GameCharacter]
|
||||
|
||||
/// 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.
|
||||
func getGameSeries(by filter: GameSeriesFilter) async throws(AmiiboServiceError) -> [GameSeries]
|
||||
|
||||
/// 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.
|
||||
func getLastUpdated() async throws(AmiiboServiceError) -> Date
|
||||
|
||||
}
|
||||
|
||||
@@ -10,17 +10,28 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A protocol that defines filters that might contain `key` and/or `name` values.
|
||||
protocol KeyNameFilter {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A key to use for filtering, if any.
|
||||
var key: String? { get }
|
||||
|
||||
/// A name to use for filtering, if any.
|
||||
var name: String? { get }
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this filter without key or name values.
|
||||
init()
|
||||
|
||||
/// Initializes this filter with a key value.
|
||||
/// - Parameter key: A key to use for filtering.
|
||||
init(key: String)
|
||||
|
||||
/// Initializes this filter with a name value.
|
||||
/// - Parameter name: A name to use for filtering.
|
||||
init(name: String)
|
||||
|
||||
}
|
||||
|
||||
@@ -10,15 +10,21 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A protocol that defines decodable models containing the `key` and `name` properties.
|
||||
protocol KeyNameModel: Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A key.
|
||||
var key: String { get }
|
||||
|
||||
/// A name.
|
||||
var name: String { get }
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this model from a given payload.
|
||||
/// - Parameter payload: A payload that contains the values for the model.
|
||||
init(_ payload: Components.Schemas.Tuple)
|
||||
|
||||
}
|
||||
|
||||
+12
-3
@@ -13,10 +13,19 @@
|
||||
import Foundation
|
||||
import OpenAPIRuntime
|
||||
|
||||
struct ISODateTranscoder: DateTranscoder {
|
||||
|
||||
/// A type that allows the decoding and encoding of ISO timestamp dates, defined by the `yyyy-MM-dd'T'HH:mm:ss.SSSSSS` custom date format.
|
||||
struct ISOTimestampTranscoder {
|
||||
|
||||
// MARK: Properties
|
||||
private let dateFormatter: DateFormatter = .isoDateTime
|
||||
|
||||
/// A formatter to use to decode and encode ISO timestamps dates.
|
||||
private let dateFormatter: DateFormatter = .isoTimestamp
|
||||
|
||||
}
|
||||
|
||||
// MARK: - DateTranscoder
|
||||
|
||||
extension ISOTimestampTranscoder: DateTranscoder {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
@@ -14,55 +14,61 @@ import Foundation
|
||||
import OpenAPIRuntime
|
||||
import OpenAPIURLSession
|
||||
|
||||
/// A type that implements a live client to the online service.
|
||||
public struct AmiiboLiveClient {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A client generated by the `OpenAPIRuntime` library.
|
||||
private let client: Client
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
public init() throws {
|
||||
/// Initializes this client.
|
||||
public init() {
|
||||
self.client = .init(
|
||||
serverURL: try Servers.Server1.url(),
|
||||
configuration: .init(dateTranscoder: ISODateTranscoder()),
|
||||
// The force unwrapping implemented below assumes that the server definition from the OpenAPI specification is correct.
|
||||
serverURL: try! Servers.Server1.url(),
|
||||
configuration: .init(dateTranscoder: ISOTimestampTranscoder()),
|
||||
transport: URLSessionTransport()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - APIProtocol
|
||||
// MARK: - APIClient
|
||||
|
||||
extension AmiiboLiveClient: APIClient {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
public func getAmiibos(by filter: AmiiboFilter) async throws -> [Amiibo] {
|
||||
let response = try await {
|
||||
do {
|
||||
return 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 {
|
||||
guard let _ = error.underlyingError as? DecodingError else {
|
||||
throw AmiiboServiceError.unknown
|
||||
}
|
||||
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
|
||||
} catch {
|
||||
} else {
|
||||
throw AmiiboServiceError.unknown
|
||||
}
|
||||
}()
|
||||
} catch {
|
||||
throw AmiiboServiceError.unknown
|
||||
}
|
||||
|
||||
switch response {
|
||||
case let .ok(ok):
|
||||
@@ -79,13 +85,21 @@ extension AmiiboLiveClient: APIClient {
|
||||
}
|
||||
}
|
||||
|
||||
public func getAmiiboSeries(by filter: AmiiboSeriesFilter) async throws -> [AmiiboSeries] {
|
||||
let response = try await client.getAmiiboSeries(
|
||||
.init(query: .init(
|
||||
key: filter.key,
|
||||
name: filter.name
|
||||
))
|
||||
)
|
||||
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):
|
||||
@@ -108,13 +122,21 @@ extension AmiiboLiveClient: APIClient {
|
||||
}
|
||||
}
|
||||
|
||||
public func getAmiiboTypes(by filter: AmiiboTypeFilter) async throws -> [AmiiboType] {
|
||||
let response = try await client.getAmiiboTypes(
|
||||
.init(query: .init(
|
||||
key: filter.key,
|
||||
name: filter.name
|
||||
))
|
||||
)
|
||||
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):
|
||||
@@ -137,13 +159,21 @@ extension AmiiboLiveClient: APIClient {
|
||||
}
|
||||
}
|
||||
|
||||
public func getGameCharacters(by filter: GameCharacterFilter) async throws -> [GameCharacter] {
|
||||
let response = try await client.getGameCharacters(
|
||||
.init(query: .init(
|
||||
key: filter.key,
|
||||
name: filter.name
|
||||
))
|
||||
)
|
||||
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):
|
||||
@@ -166,13 +196,21 @@ extension AmiiboLiveClient: APIClient {
|
||||
}
|
||||
}
|
||||
|
||||
public func getGameSeries(by filter: GameSeriesFilter) async throws -> [GameSeries] {
|
||||
let response = try await client.getGameSeries(
|
||||
.init(query: .init(
|
||||
key: filter.key,
|
||||
name: filter.name
|
||||
))
|
||||
)
|
||||
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):
|
||||
@@ -195,8 +233,14 @@ extension AmiiboLiveClient: APIClient {
|
||||
}
|
||||
}
|
||||
|
||||
public func getLastUpdated() async throws -> Date {
|
||||
let response = try await client.getLastUpdated()
|
||||
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):
|
||||
@@ -218,7 +262,12 @@ private extension AmiiboLiveClient {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
func map(_ wrapper: Components.Schemas.AmiiboWrapper) -> [Amiibo] {
|
||||
/// 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.
|
||||
/// - Returns: A list of amiibo items, sorted by identifiers.
|
||||
func map(
|
||||
_ wrapper: Components.Schemas.AmiiboWrapper
|
||||
) -> [Amiibo] {
|
||||
switch wrapper.amiibo {
|
||||
case let .Amiibo(object):
|
||||
return [.init(object)]
|
||||
@@ -230,6 +279,11 @@ private extension AmiiboLiveClient {
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves a list of items that conforms to the `KeyNameModel` protocol from a wrapper container.
|
||||
/// - Parameters:
|
||||
/// - wrapper: A wrapper container that either has an object or a list of items.
|
||||
/// - as: a model type that conforms to the `KeyNameModel` protocol.
|
||||
/// - Returns: A list of items that conforms to the `KeyNameModel` protocol, sorted by keys.
|
||||
func map<Model: KeyNameModel>(
|
||||
_ wrapper: Components.Schemas.TupleWrapper,
|
||||
as: Model.Type
|
||||
|
||||
@@ -12,20 +12,43 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A type that implements a mock client, for testing purposes.
|
||||
public struct AmiiboMockClient {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A list of amiibo items to return, if any.
|
||||
private let amiibos: [Amiibo]?
|
||||
|
||||
/// A list of amiibo series to return, if any.
|
||||
private let amiiboSeries: [AmiiboSeries]?
|
||||
|
||||
/// A list of amiibo types to return, if any.
|
||||
private let amiiboTypes: [AmiiboType]?
|
||||
|
||||
/// An error to throw, if any.
|
||||
private let error: AmiiboServiceError?
|
||||
|
||||
/// A list of game characters to return, if any.
|
||||
private let gameCharacters: [GameCharacter]?
|
||||
|
||||
/// A list of game series to return, if any.
|
||||
private let gameSeries: [GameSeries]?
|
||||
|
||||
/// A last updated date to return, if any.
|
||||
private let lastUpdated: Date?
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this client.
|
||||
/// - Parameters:
|
||||
/// - amiibos: A list of amiibo items to return, if any.
|
||||
/// - amiiboSeries: A list of amiibo series to return, if any.
|
||||
/// - amiiboTypes: A list of amiibo types to return, if any.
|
||||
/// - gameCharacters: A list of game characters to return, if any.
|
||||
/// - gameSeries: A list of game series to return, if any.
|
||||
/// - lastUpdated: A last updated date to return, if any.
|
||||
/// - error: An error to throw, if any.
|
||||
public init(
|
||||
amiibos: [Amiibo]? = nil,
|
||||
amiiboSeries: [AmiiboSeries]? = nil,
|
||||
@@ -52,7 +75,7 @@ extension AmiiboMockClient: APIClient {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
public func getAmiibos(by filter: AmiiboFilter) async throws -> [Amiibo] {
|
||||
public func getAmiibos(by filter: AmiiboFilter) async throws(AmiiboServiceError) -> [Amiibo] {
|
||||
try throwErrorIfExists()
|
||||
|
||||
guard let amiibos else {
|
||||
@@ -62,7 +85,7 @@ extension AmiiboMockClient: APIClient {
|
||||
return amiibos
|
||||
}
|
||||
|
||||
public func getAmiiboSeries(by filter: AmiiboSeriesFilter) async throws -> [AmiiboSeries] {
|
||||
public func getAmiiboSeries(by filter: AmiiboSeriesFilter) async throws(AmiiboServiceError) -> [AmiiboSeries] {
|
||||
try throwErrorIfExists()
|
||||
|
||||
guard let amiiboSeries else {
|
||||
@@ -72,7 +95,7 @@ extension AmiiboMockClient: APIClient {
|
||||
return amiiboSeries
|
||||
}
|
||||
|
||||
public func getAmiiboTypes(by filter: AmiiboTypeFilter) async throws -> [AmiiboType] {
|
||||
public func getAmiiboTypes(by filter: AmiiboTypeFilter) async throws(AmiiboServiceError) -> [AmiiboType] {
|
||||
try throwErrorIfExists()
|
||||
|
||||
guard let amiiboTypes else {
|
||||
@@ -82,7 +105,7 @@ extension AmiiboMockClient: APIClient {
|
||||
return amiiboTypes
|
||||
}
|
||||
|
||||
public func getGameCharacters(by filter: GameCharacterFilter) async throws -> [GameCharacter] {
|
||||
public func getGameCharacters(by filter: GameCharacterFilter) async throws(AmiiboServiceError) -> [GameCharacter] {
|
||||
try throwErrorIfExists()
|
||||
|
||||
guard let gameCharacters else {
|
||||
@@ -92,7 +115,7 @@ extension AmiiboMockClient: APIClient {
|
||||
return gameCharacters
|
||||
}
|
||||
|
||||
public func getGameSeries(by filter: GameSeriesFilter) async throws -> [GameSeries] {
|
||||
public func getGameSeries(by filter: GameSeriesFilter) async throws(AmiiboServiceError) -> [GameSeries] {
|
||||
try throwErrorIfExists()
|
||||
|
||||
guard let gameSeries else {
|
||||
@@ -102,7 +125,7 @@ extension AmiiboMockClient: APIClient {
|
||||
return gameSeries
|
||||
}
|
||||
|
||||
public func getLastUpdated() async throws -> Date {
|
||||
public func getLastUpdated() async throws(AmiiboServiceError) -> Date {
|
||||
try throwErrorIfExists()
|
||||
|
||||
guard let lastUpdated else {
|
||||
@@ -121,7 +144,9 @@ private extension AmiiboMockClient {
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
func throwErrorIfExists() throws {
|
||||
/// Throws an error if it has been provided,
|
||||
/// - Throws: An ``AmiiboServiceError`` error in case an error has been provided.
|
||||
func throwErrorIfExists() throws(AmiiboServiceError) {
|
||||
if let error {
|
||||
throw error
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//===----------------------------------------------------------------------===
|
||||
//
|
||||
// This source file is part of the AmiiboService open source project
|
||||
//
|
||||
// Copyright (c) 2024-2025 Röck+Cöde VoF. and the AmiiboAPI project authors
|
||||
// Licensed under the EUPL 1.2 or later.
|
||||
//
|
||||
// See LICENSE for license information
|
||||
// See CONTRIBUTORS for the list of AmiiboAPI project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A concrete representation of the types of client that a ``AmiiboService`` service can utilize.
|
||||
///
|
||||
/// > important: This enumeration has been defined as a way to avoid exposing the `APIClient` protocol outside the boundaries of this library.
|
||||
public enum AmiiboClient {
|
||||
/// A live Amiibo client to interact with the online service.
|
||||
case live(AmiiboLiveClient = .init())
|
||||
///A mock Amiibo client, for testing purposes.
|
||||
case mock(AmiiboMockClient)
|
||||
}
|
||||
@@ -10,12 +10,19 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A representation of all the possible errors that the ``AmiiboService`` service could throw.
|
||||
public enum AmiiboServiceError: Error {
|
||||
/// A bad request has been given to the client.
|
||||
case badRequest
|
||||
/// A response cannot be decoded.
|
||||
case decoding
|
||||
/// An online service is not currently available.
|
||||
case notAvailable
|
||||
/// A response cannot be found.
|
||||
case notFound
|
||||
/// An undocumented/unsupported status code error.
|
||||
case undocumented(_ statusCode: Int)
|
||||
/// An unknown error.
|
||||
case unknown
|
||||
}
|
||||
|
||||
|
||||
@@ -10,21 +10,47 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A type that contains values to fine-tune a response when requesting amiibo items.
|
||||
public struct AmiiboFilter {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A game character to return, if any.
|
||||
public let gameCharacter: String?
|
||||
|
||||
/// A game series to return, if any.
|
||||
public let gameSeries: String?
|
||||
|
||||
/// An amiibo identifier to return, if any.
|
||||
public let identifier: String?
|
||||
|
||||
/// An amiibo name to return, if any.
|
||||
public let name: String?
|
||||
|
||||
/// An amiibo series to return, if any.
|
||||
public let series: String?
|
||||
|
||||
/// A flag indicating whether to include games in the response, if any.
|
||||
public let showGames: Bool?
|
||||
|
||||
/// A flag indicating whether to include amiibo usages in games in the response, if any.
|
||||
public let showUsage: Bool?
|
||||
|
||||
/// An amiibo type to return, if any.
|
||||
public let type: String?
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this filter.
|
||||
/// - Parameters:
|
||||
/// - identifier: An amiibo identifier to return, if any.
|
||||
/// - name: An amiibo name to return, if any.
|
||||
/// - type: An amiibo type to return, if any.
|
||||
/// - series: An amiibo series to return, if any.
|
||||
/// - gameCharacter: A game character to return, if any.
|
||||
/// - gameSeries: A game series to return, if any.
|
||||
/// - showGames: A flag indicating whether to include games in the response, if any.
|
||||
/// - showUsage: A flag indicating whether to include amiibo usages in games in the response, if any.
|
||||
public init(
|
||||
identifier: String? = nil,
|
||||
name: String? = nil,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A type that contains values to fine-tune a response when requesting amiibo series.
|
||||
public struct AmiiboSeriesFilter: KeyNameFilter {
|
||||
|
||||
// MARK: Properties
|
||||
@@ -17,7 +18,7 @@ public struct AmiiboSeriesFilter: KeyNameFilter {
|
||||
public let key: String?
|
||||
public let name: String?
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
public init() {
|
||||
self.key = nil
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A type that contains values to fine-tune a response when requesting amiibo types.
|
||||
public struct AmiiboTypeFilter: KeyNameFilter {
|
||||
|
||||
// MARK: Properties
|
||||
@@ -17,7 +18,7 @@ public struct AmiiboTypeFilter: KeyNameFilter {
|
||||
public let key: String?
|
||||
public let name: String?
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
public init() {
|
||||
self.key = nil
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A type that contains values to fine-tune a response when requesting game characters.
|
||||
public struct GameCharacterFilter: KeyNameFilter {
|
||||
|
||||
// MARK: Properties
|
||||
@@ -17,7 +18,7 @@ public struct GameCharacterFilter: KeyNameFilter {
|
||||
public let key: String?
|
||||
public let name: String?
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
public init() {
|
||||
self.key = nil
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A type that contains values to fine-tune a response when requesting game series.
|
||||
public struct GameSeriesFilter: KeyNameFilter {
|
||||
|
||||
// MARK: Properties
|
||||
@@ -17,7 +18,7 @@ public struct GameSeriesFilter: KeyNameFilter {
|
||||
public let key: String?
|
||||
public let name: String?
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
public init() {
|
||||
self.key = nil
|
||||
|
||||
@@ -12,23 +12,45 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A model that represents an amiibo item.
|
||||
public struct Amiibo: Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A game character.
|
||||
public let gameCharacter: String
|
||||
|
||||
/// A game series.
|
||||
public let gameSeries: String
|
||||
|
||||
/// The first 8 hexadecimal characters of an identifier.
|
||||
public let head: String
|
||||
|
||||
/// An image link.
|
||||
public let image: String
|
||||
|
||||
/// An amiibo name.
|
||||
public let name: String
|
||||
|
||||
/// A game platform type, if any.
|
||||
public let platform: Platform?
|
||||
|
||||
/// A release date.
|
||||
public let release: Release
|
||||
|
||||
/// An amiibo series.
|
||||
public let series: String
|
||||
|
||||
/// The last 8 hexadecimal characters of an identifier.
|
||||
public let tail: String
|
||||
|
||||
/// An amiibo type.
|
||||
public let type: String
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this model from a given payload.
|
||||
/// - Parameter payload: A payload that contains the values for the model.
|
||||
init(_ payload: Components.Schemas.Amiibo) {
|
||||
self.gameCharacter = payload.character
|
||||
self.gameSeries = payload.gameSeries
|
||||
@@ -48,10 +70,12 @@ public struct Amiibo: Sendable {
|
||||
|
||||
// MARK: Computed
|
||||
|
||||
/// An identifier.
|
||||
public var identifier: String {
|
||||
head + tail
|
||||
}
|
||||
|
||||
/// A URL related to an image link, if any.
|
||||
public var imageURL: URL? {
|
||||
.init(string: image)
|
||||
}
|
||||
|
||||
@@ -11,16 +11,24 @@
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
extension Amiibo {
|
||||
/// A model that represents a game related to an amiibo item.
|
||||
public struct Game: Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A list of identifiers.
|
||||
public let identifiers: [String]
|
||||
|
||||
/// A name.
|
||||
public let name: String
|
||||
|
||||
/// A list of amiibo usages, if any.
|
||||
public let usages: [Usage]?
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this model from a given payload.
|
||||
/// - Parameter payload: A payload that contains the values for the model.
|
||||
init(_ payload: Components.Schemas.AmiiboGame) {
|
||||
self.identifiers = payload.gameID
|
||||
self.name = payload.gameName
|
||||
|
||||
@@ -11,16 +11,30 @@
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
extension Amiibo {
|
||||
/// A model that represents a collection of `WiiU`, `3DS`, and `Switch` games related to an amiibo item.
|
||||
public struct Platform: Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A list of `Switch` games related to an amiibo item.
|
||||
public let `switch`: [Game]
|
||||
|
||||
/// A list of `3DS` games related to an amiibo item.
|
||||
public let threeDS: [Game]
|
||||
|
||||
/// A list of `WiiU` games related to an amiibo item.
|
||||
public let wiiU: [Game]
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
/// Initializes this model.
|
||||
///
|
||||
/// > important: In case no data is provided, then an instance of this model is not created.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - `switch`: A list of `Switch` games related to an amiibo item, if any.
|
||||
/// - threeDS: A list of `3DS` games related to an amiibo item, if any.
|
||||
/// - wiiU: A list of `WiiU` games related to an amiibo item, if any.
|
||||
init?(
|
||||
_ `switch`: [Components.Schemas.AmiiboGame]?,
|
||||
_ threeDS: [Components.Schemas.AmiiboGame]?,
|
||||
|
||||
@@ -13,17 +13,27 @@
|
||||
import Foundation
|
||||
|
||||
extension Amiibo {
|
||||
/// A model that represents a collection of release dates related to an amiibo item.
|
||||
public struct Release: Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A release date for North America, if any.
|
||||
public let america: Date?
|
||||
|
||||
/// A release date for Australia, if any.
|
||||
public let australia: Date?
|
||||
|
||||
/// A release date for Europe, if any.
|
||||
public let europe: Date?
|
||||
|
||||
/// A release date for Japan, if any.
|
||||
public let japan: Date?
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this model from a given payload.
|
||||
/// - Parameter payload: A payload that contains the values for the model.
|
||||
init(_ payload: Components.Schemas.AmiiboRelease) {
|
||||
self.america = payload.na
|
||||
self.australia = payload.au
|
||||
|
||||
@@ -11,15 +11,21 @@
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
extension Amiibo {
|
||||
/// A model that represents the usage of an amiibo item within a certain game.
|
||||
public struct Usage: Sendable {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// An explanation of how to use an amiibo item.
|
||||
public let explanation: String
|
||||
|
||||
/// A flag that indicates whether an amiibo item can save game data in it.
|
||||
public let isWriteable: Bool
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this model from a given payload.
|
||||
/// - Parameter payload: A payload that contains the values for the model.
|
||||
init(_ payload: Components.Schemas.AmiiboUsage) {
|
||||
self.explanation = payload.Usage
|
||||
self.isWriteable = payload.write
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A model that represents an amiibo series.
|
||||
public struct AmiiboSeries: KeyNameModel {
|
||||
|
||||
// MARK: Properties
|
||||
@@ -17,7 +18,7 @@ public struct AmiiboSeries: KeyNameModel {
|
||||
public let key: String
|
||||
public let name: String
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
init(_ payload: Components.Schemas.Tuple) {
|
||||
self.key = payload.key
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A model that represents an amiibo type.
|
||||
public struct AmiiboType: KeyNameModel {
|
||||
|
||||
// MARK: Properties
|
||||
@@ -17,7 +18,7 @@ public struct AmiiboType: KeyNameModel {
|
||||
public let key: String
|
||||
public let name: String
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
init(_ payload: Components.Schemas.Tuple) {
|
||||
self.key = payload.key
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A model that represents a game character.
|
||||
public struct GameCharacter: KeyNameModel {
|
||||
|
||||
// MARK: Properties
|
||||
@@ -17,7 +18,7 @@ public struct GameCharacter: KeyNameModel {
|
||||
public let key: String
|
||||
public let name: String
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
init(_ payload: Components.Schemas.Tuple) {
|
||||
self.key = payload.key
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===
|
||||
|
||||
/// A model that represents a game series.
|
||||
public struct GameSeries: KeyNameModel {
|
||||
|
||||
// MARK: Properties
|
||||
@@ -17,7 +18,7 @@ public struct GameSeries: KeyNameModel {
|
||||
public let key: String
|
||||
public let name: String
|
||||
|
||||
// MARK: Initialisers
|
||||
// MARK: Initializers
|
||||
|
||||
init(_ payload: Components.Schemas.Tuple) {
|
||||
self.key = payload.key
|
||||
|
||||
@@ -12,51 +12,81 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A type that implements the service that uses a client to make calls.
|
||||
public struct AmiiboService {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// A client to interact with the endpoints.
|
||||
private let client: any APIClient
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
public init(_ client: any APIClient) {
|
||||
self.client = client
|
||||
// MARK: Initializers
|
||||
|
||||
/// Initializes this service with a specific client type.
|
||||
/// - Parameter client: A representation of a client to use to interact with the endpoints.
|
||||
public init(_ client: AmiiboClient) {
|
||||
self.client = switch client {
|
||||
case let .mock(mockClient): mockClient
|
||||
case let .live(liveClient): liveClient
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Functions
|
||||
|
||||
|
||||
/// Gets 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 filtered amiibo items.
|
||||
/// - Throws: An ``AmiiboServiceError`` error in case some issue is encountered while generating the result.
|
||||
public func getAmiibos(
|
||||
_ filter: AmiiboFilter = .init()
|
||||
) async throws -> [Amiibo] {
|
||||
) async throws(AmiiboServiceError) -> [Amiibo] {
|
||||
try await client.getAmiibos(by: 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(
|
||||
_ filter: AmiiboSeriesFilter = .init()
|
||||
) async throws -> [AmiiboSeries] {
|
||||
) async throws(AmiiboServiceError) -> [AmiiboSeries] {
|
||||
try await client.getAmiiboSeries(by: 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(
|
||||
_ filter: AmiiboTypeFilter = .init()
|
||||
) async throws -> [AmiiboType] {
|
||||
) async throws(AmiiboServiceError) -> [AmiiboType] {
|
||||
try await client.getAmiiboTypes(by: 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(
|
||||
_ filter: GameCharacterFilter = .init()
|
||||
) async throws -> [GameCharacter] {
|
||||
) async throws(AmiiboServiceError) -> [GameCharacter] {
|
||||
try await client.getGameCharacters(by: 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(
|
||||
_ filter: GameSeriesFilter = .init()
|
||||
) async throws -> [GameSeries] {
|
||||
) async throws(AmiiboServiceError) -> [GameSeries] {
|
||||
try await client.getGameSeries(by: filter)
|
||||
}
|
||||
|
||||
public func getLastUpdated() async throws -> Date {
|
||||
|
||||
/// 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 {
|
||||
try await client.getLastUpdated()
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -23,10 +23,8 @@ struct AmiiboServiceLiveTests {
|
||||
|
||||
// MARK: Initialisers
|
||||
|
||||
init() throws {
|
||||
let client = try AmiiboLiveClient()
|
||||
|
||||
self.service = .init(client)
|
||||
init() {
|
||||
self.service = .init(.live())
|
||||
}
|
||||
|
||||
// MARK: Functions tests
|
||||
Reference in New Issue
Block a user