Skip to content

Commit

Permalink
Improve documentation thoroughness
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobSyndeo committed Feb 7, 2024
1 parent 956ea8c commit 5321e43
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 11 deletions.
4 changes: 4 additions & 0 deletions Sources/Ether/Core+TypedRoute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extension Ether {
/// - parameters: A collection of key-value pairs to use as parameters. Defaults to empty.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: An instance of the provided ``Ether/EtherTypedRoute``'s ``Ether/EtherTypedRoute/DecodedType`` type, decoded from the response recevied from the server.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/EtherRoute/get(type:parameters:decoder:)``, a convenience version of this method.
public static func get<T>(typedRoute: T,
Expand All @@ -30,6 +31,7 @@ extension Ether {
/// - encoding: The encoding to use. Defaults to ``ParameterEncoding/gZip``.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: A ``Ether/Ether/Response`` struct containing the HTTP response, as well as the decoded struct (or raw data if no struct was requested).
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/EtherRoute/post(with:usingEncoding:responseFormat:decoder:)``, a convenience version of this method.
@discardableResult
Expand All @@ -51,6 +53,7 @@ extension Ether {
/// - formItems: The form items to include in the request. The key is the name of the form item, and the value is a `FormValue` that specifies the value of the form item.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: The response from the server, bundled in a ``Ether/Ether/Response``.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/EtherRoute/postMultipartForm(formItems:responseFormat:decoder:)``, a convenience version of this method.
@discardableResult
Expand All @@ -74,6 +77,7 @@ extension Ether {
/// - encoding: The encoding to use. Defaults to ``ParameterEncoding/urlQuery``.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: The response from the server, bundled in a ``Ether/Ether/Response``.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/EtherRoute/request(method:headers:parameters:body:responseFormat:usingEncoding:decoder:)``, a convenience version of this method.
@discardableResult
Expand Down
4 changes: 4 additions & 0 deletions Sources/Ether/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public struct Ether {
/// - parameters: A collection of key-value pairs to use as parameters. Defaults to empty.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: An instance of the `Decodable` type, decoded from the response recevied from the server.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/EtherRoute/get(type:parameters:decoder:)``, a convenience version of this method.
public static func get<T>(route: any Route,
Expand Down Expand Up @@ -61,6 +62,7 @@ public struct Ether {
/// - responseFormat: The `Decodable` type we expect to receive back. Ether will attempt to decode the HTTP response into this type. If no type is provided, the response struct will contain raw, undecoded data.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: A ``Response`` struct containing the HTTP response, as well as the decoded struct (or raw data if no struct was requested).
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/EtherRoute/post(with:usingEncoding:responseFormat:decoder:)``, a convenience version of this method.
@discardableResult
Expand All @@ -86,6 +88,7 @@ public struct Ether {
/// - responseFormat: The type of data to bundle in the response. Defaults to `DummyTypeUsedWhenNoDecodableIsRequested`.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: The response from the server, bundled in a ``Ether/Ether/Response``.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/EtherRoute/postMultipartForm(formItems:responseFormat:decoder:)``, a convenience version of this method.
@discardableResult
Expand Down Expand Up @@ -161,6 +164,7 @@ public struct Ether {
/// - encoding: The encoding to use. Defaults to ``ParameterEncoding/urlQuery``.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: The response from the server, bundled in a ``Ether/Ether/Response``.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/EtherRoute/request(method:headers:parameters:body:responseFormat:usingEncoding:decoder:)``, a convenience version of this method.
@discardableResult
Expand Down
27 changes: 26 additions & 1 deletion Sources/Ether/Error.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
import Foundation

extension Ether {
/// An error that can occur while using Ether.
/// This can help give insight into what went wrong.
/// As long as the issue wasn't server-side, network-related, or a bug in Ether, this should hopefully help you resolve the issue!
/// If not, or if you suspect a bug in Ether, please [open an issue on GitHub](https://github.com/JacobSyndeo/Ether/issues/new), and I'll do my best to help you out!
public enum Error: Swift.Error, LocalizedError {
/// The request failed.
case requestFailed
/// The response was not valid HTTP!
case responseNotHTTP
case badURL(_ attemptedToConvertFrom: String)
/// The string provided to Ether as an `Ether.Route` (for automatic conversion into a URL) is invalid.
/// - Parameters:
/// - attemptedToConvertFrom: The string that Ether attempted to convert into a URL.
case badURL(_ attemptedToConvertFrom: String?)
/// One of the provided query items is invalid.
/// - Parameters:
/// - queryItem: The query item that Ether found to be invalid.
case badQueryItem(_ queryItem: URLQueryItem)
/// The server responded with a bad response code.
/// - Parameters:
/// - responseCode: The response code that Ether found to be invalid.
case badResponseCode(_ responseCode: Int)
/// Encoding to JSON failed.
/// - Parameters:
/// - error: The error that occurred while encoding to JSON.
case jsonEncodingFailed(_ error: EncodingError?)
/// Decoding from JSON failed.
/// - Parameters:
/// - error: The error that occurred while decoding from JSON.
case jsonDecodingFailed(_ error: DecodingError?)
/// Some other, unknown issue occurred. [Please report this as an issue!](https://github.com/JacobSyndeo/Ether/issues/new)
case miscResponseIssue // For unknown/uncaught

/// A string describing the error.
public var errorDescription: String? {
switch self {
case .requestFailed:
Expand Down Expand Up @@ -48,6 +71,7 @@ extension Ether {
}
}

/// A string describing the reason for the error.
public var failureReason: String? {
switch self {
case .requestFailed:
Expand All @@ -69,6 +93,7 @@ extension Ether {
}
}

/// A string describing how to recover from the error.
public var recoverySuggestion: String? {
switch self {
case .requestFailed:
Expand Down
8 changes: 7 additions & 1 deletion Sources/Ether/Fetchable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public extension Ether.SingularFetchable {
/// - id: The identifier of the instance to fetch from the server.
/// - parameters: The parameters to use in the request. Defaults to empty.
/// - Returns: The instance requested.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
static func fetch(id: String? = nil, parameters: Ether.Parameters = [:]) async throws -> Self {
return try await Ether.get(route: singularRoute(id: id),
type: Self.self,
Expand All @@ -114,6 +115,7 @@ public extension Ether.SingularFetchable {
/// - parameters: The parameters to use in the request. Defaults to empty.
/// - container: The container type to decode from. You'll need to create this type based on the server's API response format.
/// - Returns: An instance of the provided container format, based on the server's response.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
static func fetchWithContainer<Container: Decodable>(id: String? = nil,
parameters: Ether.Parameters = [:],
container: Container.Type) async throws -> Container {
Expand All @@ -138,6 +140,7 @@ public extension Ether.SingularFetchable {
/// - container: The container type to decode from. You'll need to create this type based on the server's API response format.
/// - keyPath: The key path representing the location of this type within the container.
/// - Returns: An instance of the type with the provided identifier, based on the server's response.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
static func fetch<Container: Decodable>(id: String? = nil,
parameters: Ether.Parameters = [:],
container: Container.Type,
Expand All @@ -154,6 +157,7 @@ extension Ether.PluralFetchable {
/// - filters: An optional set of filters. See ``Ether/Ether/FetchableFilters`` for more information.
/// - parameters: The parameters to use in the request. Defaults to empty.
/// - Returns: An array containing all available instances of the type matching the provided filters (if any), based on the server's response.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
public static func fetchAll(filters: Ether.FetchableFilters? = nil,
parameters: Ether.Parameters = [:]) async throws -> [Self] {
return try await Ether.get(route: pluralRoute(filters: filters),
Expand All @@ -177,6 +181,7 @@ extension Ether.PluralFetchable {
/// - container: The container type to decode from. You'll need to create this type based on the server's API response format.
/// - keyPath: The key path representing the location of the array of instances of the type within the container.
/// - Returns: An instance of the provided container format, based on the server's response.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
public static func fetchAllWithContainer<Container: Decodable>(filters: Ether.FetchableFilters? = nil,
parameters: Ether.Parameters = [:],
container: Container.Type,
Expand All @@ -195,13 +200,14 @@ extension Ether.PluralFetchable {
///
/// If all you really care about is the type you asked for, then this function is for you!
///
/// Otherwise, in the case that you _do_ want that metadata, use ``Ether/EtherPluralFetchable/fetchAllWithContainer(filters:parameters:container:)``.
/// Otherwise, in the case that you _do_ want that metadata, use ``Ether/EtherPluralFetchable/fetchAllWithContainer(filters:parameters:container:keyPath:)``.
/// - Parameters:
/// - filters: An optional set of filters. See ``Ether/Ether/FetchableFilters`` for more information.
/// - parameters: The parameters to use in the request. Defaults to empty.
/// - container: The container type to decode from. You'll need to create this type based on the server's API response format.
/// - keyPath: The key path representing the location of this type within the container.
/// - Returns: An array containing all available instances of the type matching the provided filters (if any), based on the server's response.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
public static func fetchAll<Container: Decodable>(filters: Ether.FetchableFilters? = nil,
parameters: Ether.Parameters = [:],
container: Container.Type,
Expand Down
12 changes: 9 additions & 3 deletions Sources/Ether/Route.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Foundation
///
/// The fullURL variable on the enum type would then be a computed property that would generate the URLs `https://domain.com/home` and `https://domain.com/users/1`, respectively.
///
/// For further convenience, both ``String`` and ``URL`` are automatically conformed to this, so you can pass them directly into functions expecting `Route`s.
/// For further convenience, both ``Swift/String`` and ``Foundation/URL`` are automatically conformed to this, so you can pass them directly into functions expecting `Route`s.
///
/// Typealiased to ``Ether/Ether/Route`` for better namespacing.
///
Expand Down Expand Up @@ -36,9 +36,10 @@ extension Ether {

// Conform String to Route, so that we can use it.
extension String: Ether.Route {
/// Returns a URL if `self` represents a valid URL string that conforms to [RFC 2396](https://www.ietf.org/rfc/rfc2396.txt) or throws an `AFError`.
/// Returns a URL if `self` represents a valid URL string that conforms to [RFC 2396](https://www.ietf.org/rfc/rfc2396.txt) or throws an error.
///
/// - throws: An ``Ether/Ether/Error/badURL(_:)`` if `self` is not a valid URL string.
/// - Returns: A URL, if `self` is a valid URL string.
/// - Throws: An ``Ether/Ether/Error/badURL(_:)`` if `self` is not a valid URL string.
public var asURL: URL {
get throws {
guard let url = URL(string: self) else { throw Ether.Error.badURL(self) }
Expand All @@ -50,6 +51,7 @@ extension String: Ether.Route {
// Conform URL to Route, so that we can use it.
extension URL: Ether.Route {
/// Returns self.
/// Only "throws" because it's required by the protocol.
public var asURL: URL {
get throws {
return self
Expand All @@ -69,6 +71,7 @@ extension Ether.Route {
/// - parameters: A collection of key-value pairs to use as parameters. Defaults to empty.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: An instance of the `Decodable` type, decoded from the response recevied from the server.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/Ether/get(route:type:parameters:decoder:)``, the main version of this method.
public func get<T>(type: T.Type,
Expand All @@ -88,6 +91,7 @@ extension Ether.Route {
/// - responseFormat: The `Decodable` type we expect to receive back. Ether will attempt to decode the HTTP response into this type. If no type is provided, the response struct will contain raw, undecoded data.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: A ``Ether/Ether/Response`` struct containing the HTTP response, as well as the decoded struct (or raw data if no struct was requested).
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/Ether/post(route:with:usingEncoding:responseFormat:decoder:)``, the main version of this method.
@discardableResult
Expand All @@ -109,6 +113,7 @@ extension Ether.Route {
/// - responseFormat: The type of data to bundle in the response. Defaults to `DummyTypeUsedWhenNoDecodableIsRequested`.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: The response from the server, bundled in a ``Ether/Ether/Response``.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/Ether/postMultipartForm(route:formItems:responseFormat:decoder:)``, the main version of this method.
@discardableResult
Expand All @@ -132,6 +137,7 @@ extension Ether.Route {
/// - encoding: The encoding to use. Defaults to ``Ether/Ether/ParameterEncoding/urlQuery``.
/// - decoder: The `JSONDecoder` to use. You can create your own instance to customize its behavior before passing it in, if you'd like.
/// - Returns: The response from the server, bundled in a ``Ether/Ether/Response``.
/// - Throws: An ``Ether/Ether/Error``, or any error thrown by the `URLSession` data task, if the request fails.
///
/// Compare with ``Ether/Ether/request(route:method:headers:parameters:body:responseFormat:usingEncoding:decoder:)``, the main version of this method.
@discardableResult
Expand Down
Loading

0 comments on commit 5321e43

Please sign in to comment.