// // 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]> { var request = Request<[TryDecode]>(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 } }