93 lines
2.9 KiB
Swift
93 lines
2.9 KiB
Swift
//
|
|
// Timeline.swift
|
|
// Pachyderm
|
|
//
|
|
// Created by Shadowfacts on 9/9/18.
|
|
// Copyright © 2018 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public enum Timeline: Equatable, Hashable, Sendable {
|
|
case home
|
|
case `public`(local: Bool)
|
|
case tag(hashtag: String)
|
|
case list(id: String)
|
|
case direct
|
|
}
|
|
|
|
extension Timeline {
|
|
var endpoint: Endpoint {
|
|
switch self {
|
|
case .home:
|
|
return "/api/v1/timelines/home"
|
|
case .public:
|
|
return "/api/v1/timelines/public"
|
|
case let .tag(hashtag):
|
|
return "/api/v1/timelines/tag/\(hashtag)"
|
|
case let .list(id):
|
|
return "/api/v1/timelines/list/\(id)"
|
|
case .direct:
|
|
return "/api/v1/timelines/direct"
|
|
}
|
|
}
|
|
|
|
func request(range: RequestRange) -> Request<[TryDecode<Status>]> {
|
|
var request = Request<[TryDecode<Status>]>(method: .get, path: endpoint)
|
|
if case .public(true) = self {
|
|
request.queryParameters.append("local" => true)
|
|
}
|
|
request.range = range
|
|
// 206 can happen when the timeline is being regenerated and therefore is incomplete
|
|
request.additionalAcceptableHTTPCodes = [206]
|
|
return request
|
|
}
|
|
}
|
|
|
|
extension Timeline: Codable {
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
let type = try container.decode(String.self, forKey: .type)
|
|
switch type {
|
|
case "home":
|
|
self = .home
|
|
case "public":
|
|
self = .public(local: try container.decode(Bool.self, forKey: .local))
|
|
case "tag":
|
|
self = .tag(hashtag: try container.decode(String.self, forKey: .hashtag))
|
|
case "list":
|
|
self = .list(id: try container.decode(String.self, forKey: .listID))
|
|
case "direct":
|
|
self = .direct
|
|
default:
|
|
throw DecodingError.dataCorruptedError(forKey: CodingKeys.type, in: container, debugDescription: "Timeline type must be one of 'home', 'local', 'tag', 'list', or 'direct'")
|
|
}
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
switch self {
|
|
case .home:
|
|
try container.encode("home", forKey: .type)
|
|
case let .public(local):
|
|
try container.encode("public", forKey: .type)
|
|
try container.encode(local, forKey: .local)
|
|
case let .tag(hashtag):
|
|
try container.encode("tag", forKey: .type)
|
|
try container.encode(hashtag, forKey: .hashtag)
|
|
case let .list(id):
|
|
try container.encode("list", forKey: .type)
|
|
try container.encode(id, forKey: .listID)
|
|
case .direct:
|
|
try container.encode("direct", forKey: .type)
|
|
}
|
|
}
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case type
|
|
case local
|
|
case hashtag
|
|
case listID
|
|
}
|
|
}
|