1
0

JSON.swift 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //
  2. // JSON.swift
  3. // Swifter
  4. //
  5. // Copyright © 2016 Damian Kołakowski. All rights reserved.
  6. //
  7. #if os(Linux)
  8. import Glibc
  9. #else
  10. import Foundation
  11. #endif
  12. extension Dictionary {
  13. public func asJson() -> String {
  14. var tokens = [String]()
  15. for (key, value) in self {
  16. if let stringKey = key as? String {
  17. tokens.append(escapeString(stringKey) + ":" + toJsonValue(value))
  18. }
  19. }
  20. return "{" + tokens.joined(separator: ",") + "}"
  21. }
  22. }
  23. extension Array {
  24. public func asJson() -> String {
  25. return "[" + self.map({ toJsonValue($0) }).joined(separator: ",") + "]"
  26. }
  27. }
  28. private func escapeString(_ string: String) -> String {
  29. return string.unicodeScalars.reduce("\"") { (c, s) -> String in
  30. switch s.value {
  31. case 0 : return c + "\\0"
  32. case 7 : return c + "\\a"
  33. case 8 : return c + "\\b"
  34. case 9 : return c + "\\t"
  35. case 10: return c + "\\n"
  36. case 11: return c + "\\v"
  37. case 12: return c + "\\f"
  38. case 13: return c + "\\r"
  39. case 34: return c + "\\\""
  40. case 39: return c + "\\'"
  41. case 47: return c + "\\/"
  42. case 92: return c + "\\\\"
  43. case let n where n > 127: return c + "\\u" + String(format:"%04X", n)
  44. default:
  45. return c + String(s)
  46. }
  47. } + "\""
  48. }
  49. private func toJsonValue(_ value: Any?) -> String {
  50. if let value = value {
  51. switch value {
  52. case let int as Int8: return String(int)
  53. case let int as UInt8: return String(int)
  54. case let int as Int16: return String(int)
  55. case let int as UInt16: return String(int)
  56. case let int as Int32: return String(int)
  57. case let int as UInt32: return String(int)
  58. case let int as Int64: return String(int)
  59. case let int as UInt64: return String(int)
  60. case let int as Int: return String(int)
  61. case let int as UInt: return String(int)
  62. case let int as Float: return String(int)
  63. case let int as Double: return String(int)
  64. case let bool as Bool: return bool ? "true" : "false"
  65. case let dict as Dictionary<String, Any>: return dict.asJson()
  66. case let dict as Dictionary<String, Any?>: return dict.asJson()
  67. case let array as Array<Any>: return array.asJson()
  68. case let array as Array<Any?>: return array.asJson()
  69. case let string as String: return escapeString(string)
  70. default:
  71. return "null"
  72. }
  73. }
  74. return "null"
  75. }