import Foundation nonisolated class DanbooruPostParser { private struct FailableDecodable: Decodable { let value: Value? init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() value = try? container.decode(Value.self) } } private let data: Data init(data: Data) { self.data = data } func parse() -> [BooruPost] { let decoder = JSONDecoder() decoder.dateDecodingStrategy = .custom { decoder in Self.parseDate( try (try decoder.singleValueContainer()).decode(String.self) ) ?? Date() } do { let decodedPosts = try decoder.decode([FailableDecodable].self, from: data) let validPosts = decodedPosts.compactMap(\.value) let droppedRecordCount = decodedPosts.count - validPosts.count if droppedRecordCount > 0 { debugPrint( "DanbooruPostParser.parse: dropped \(droppedRecordCount) malformed records while decoding page." ) } return validPosts.compactMap { post in post.toBooruPost() } } catch { debugPrint("DanbooruPostParser.parse: failed to decode response: \(error)") return [] } } nonisolated(unsafe) private static let isoFormatter: ISO8601DateFormatter = { let formatter = ISO8601DateFormatter() formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] return formatter }() private static let alternativeFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "EEE MMM dd HH:mm:ss Z yyyy" formatter.locale = Locale(identifier: "en_US_POSIX") return formatter }() private static func parseDate(_ input: String) -> Date? { if let date = isoFormatter.date(from: input) { return date } if let date = alternativeFormatter.date(from: input) { return date } if let timestamp = Double(input) { return Date(timeIntervalSince1970: timestamp) } return nil } }