Я пытаюсь написать меньше кода в следующем сценарии:
У меня есть этот Queryable
протокол и перечисление Parameter
:
protocol Queryable {
var urlQuery: URLQueryItem { get }
}
enum PaginationParameter: Queryable {
case page(Int)
case pageSize(Int)
var queryItem: URLQueryItem {
switch self {
case .page(let page):
return URLQueryItem(name: "page", value: page.description)
case .pageSize(let pageSize):
return URLQueryItem(name: "page_size", value: pageSize.description)
}
}
}
И перечисление, которое обеспечивает некоторые случаи по умолчаниюи некоторые конкретные случаи, определяемые универсальным типом:
enum Parameter<P: Queryable> {
case pagination(PaginationParameter)
case specific(P)
}
Пример использования
enum BookParameters: Queryable {
case search(String)
case id(Int)
var urlQuery: URLQueryItem {
switch self {
case .search(let string):
return URLQueryItem(name: "search", value: string)
case .id(let id):
return URLQueryItem(name: "id", value: id.description)
}
}
}
let parameters: [Parameter<BookParameters>] = [
.pagination(.pageSize(10)),
.specific(.id(123))
]
Теперь мне нужно получить элемент запроса url как в случае .pagination
, так и .specific
.
let queryItems = parameters.map({
switch $0 {
case .pagination(let param):
return param.queryItem
case .specific(let param):
return param.queryItem
}
})
Было бы неплохо иметь способ обработки вложенных случаев, так как они соответствуют одному и тому же протоколу.Это не работает, так как мне нужно перейти к вложенным случаям через родительские случаи:
Небольшое улучшение состояло бы в том, чтобы похоронить оператор switch в расширении для перечисления Parameters и позволить ему соответствовать Queryable
протокол также:
extension Parameters: Queryable {
let queryItem: URLQueryItem {
switch self {
case .pagination(let param):
return param.queryItem
case .specific(let param):
return param.queryItem
}
}
}
Это приводит к одному вкладышу, но я только перенес свою проблему в другое место.
let queryItems = parameters.map({ $0.queryItem })