JSON.swift 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import Foundation
  2. protocol JSON: Codable {
  3. var rawJSON: String { get }
  4. init?(from: String)
  5. }
  6. extension JSON {
  7. var rawJSON: RawJSON {
  8. let encoder = JSONEncoder()
  9. encoder.outputFormatting = .prettyPrinted
  10. encoder.dateEncodingStrategy = .iso8601
  11. return String(data: try! encoder.encode(self), encoding: .utf8)!
  12. }
  13. init?(from: String) {
  14. let decoder = JSONDecoder()
  15. decoder.dateDecodingStrategy = .iso8601
  16. guard let data = from.data(using: .utf8),
  17. let object = try? decoder.decode(Self.self, from: data)
  18. else {
  19. return nil
  20. }
  21. self = object
  22. }
  23. }
  24. extension String: JSON {
  25. var rawJSON: String { self }
  26. init?(from: String) { self = from }
  27. }
  28. extension Double: JSON {}
  29. extension Int: JSON {}
  30. extension Bool: JSON {}
  31. extension Decimal: JSON {}
  32. extension Date: JSON {
  33. var rawJSON: String {
  34. let formatter = ISO8601DateFormatter()
  35. return formatter.string(from: self)
  36. }
  37. init?(from: String) {
  38. let dateFormatter = ISO8601DateFormatter()
  39. dateFormatter.formatOptions.insert(.withFractionalSeconds)
  40. let string = from.replacingOccurrences(of: "\"", with: "")
  41. if let date = dateFormatter.date(from: string) {
  42. self = date
  43. } else {
  44. return nil
  45. }
  46. }
  47. }
  48. typealias RawJSON = String
  49. extension Array: JSON where Element: JSON {}
  50. extension Dictionary: JSON where Key: JSON, Value: JSON {}