Tusker/Packages/Pachyderm/Sources/Pachyderm/Model/Timeline.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
}
}