75 lines
2.3 KiB
Swift
75 lines
2.3 KiB
Swift
//
|
|
// Pagination.swift
|
|
// Pachyderm
|
|
//
|
|
// Created by Shadowfacts on 9/9/18.
|
|
// Copyright © 2018 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public struct Pagination {
|
|
public let older: RequestRange?
|
|
public let newer: RequestRange?
|
|
}
|
|
|
|
extension Pagination {
|
|
init(string: String) {
|
|
let links = string.components(separatedBy: ",").compactMap(Item.init)
|
|
self.older = links.first(where: { $0.kind == .next })?.range
|
|
self.newer = links.first(where: { $0.kind == .prev })?.range
|
|
}
|
|
}
|
|
|
|
extension Pagination {
|
|
struct Item {
|
|
let kind: Kind
|
|
let id: String
|
|
let limit: Int?
|
|
|
|
var range: RequestRange {
|
|
switch kind {
|
|
case .next:
|
|
return .before(id: id, count: limit)
|
|
case .prev:
|
|
return .after(id: id, count: limit)
|
|
}
|
|
}
|
|
|
|
init?(string: String) {
|
|
let segments = string.components(separatedBy: .whitespaces).filter { !$0.isEmpty }.joined().components(separatedBy: ";")
|
|
|
|
let url = segments.first.flatMap { str in
|
|
String(str[str.index(after: str.startIndex)..<str.index(before: str.endIndex)])
|
|
}
|
|
let rel = segments.last?.replacingOccurrences(of: "\"", with: "").trimmingCharacters(in: .whitespaces).components(separatedBy: "=")
|
|
|
|
guard let validURL = url,
|
|
let key = rel?.first,
|
|
key == "rel",
|
|
let value = rel?.last,
|
|
let kind = Kind(rawValue: value),
|
|
let components = URLComponents(string: validURL),
|
|
let queryItems = components.queryItems else { return nil }
|
|
|
|
let min = queryItems.first { $0.name == "min_id" }?.value
|
|
let since = queryItems.first { $0.name == "since_id" }?.value
|
|
let max = queryItems.first { $0.name == "max_id" }?.value
|
|
|
|
guard let id = min ?? since ?? max else { return nil }
|
|
|
|
let limit = queryItems.first { $0.name == "limit" }.flatMap { $0.value }.flatMap { Int($0) }
|
|
|
|
self.kind = kind
|
|
self.id = id
|
|
self.limit = limit
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Pagination.Item {
|
|
enum Kind: String {
|
|
case next, prev
|
|
}
|
|
}
|