// // Hashtag.swift // Pachyderm // // Created by Shadowfacts on 9/9/18. // Copyright © 2018 Shadowfacts. All rights reserved. // import Foundation import WebURL import WebURLFoundationExtras public struct Hashtag: Codable, Sendable { public let name: String public let url: WebURL /// Only present when returned from the trending hashtags endpoint public let history: [History]? /// Only present on Mastodon >= 4 and when logged in public let following: Bool? public init(name: String, url: URL) { self.name = name self.url = WebURL(url)! self.history = nil self.following = nil } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.name = try container.decode(String.self, forKey: .name) // pixelfed (possibly others) don't fully escape special characters in the hashtag url self.url = try container.decode(WebURL.self, forKey: .url) self.history = try container.decodeIfPresent([History].self, forKey: .history) self.following = try container.decodeIfPresent(Bool.self, forKey: .following) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(name, forKey: .name) try container.encode(url, forKey: .url) try container.encodeIfPresent(history, forKey: .history) try container.encodeIfPresent(following, forKey: .following) } public static func follow(name: String) -> Request { return Request(method: .post, path: "/api/v1/tags/\(name)/follow") } public static func unfollow(name: String) -> Request { return Request(method: .post, path: "/api/v1/tags/\(name)/unfollow") } private enum CodingKeys: String, CodingKey { case name case url case history case following } } extension Hashtag: Equatable, Hashable { public static func ==(lhs: Hashtag, rhs: Hashtag) -> Bool { return lhs.name == rhs.name } public func hash(into hasher: inout Hasher) { hasher.combine(name) } }