Html.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //
  2. // Html.swift
  3. // Swifter
  4. //
  5. // Copyright © 2014-2016 Damian Kołakowski. All rights reserved.
  6. //
  7. import Foundation
  8. private var htmlStackBuffer = [UInt64: [UInt8]]()
  9. public class HtmlResponse: Response {
  10. public init(_ status: Int = Status.ok.rawValue, _ closure: ((Void) -> Void)) {
  11. super.init(status)
  12. self.headers.append(("Content-Type", "text/html"))
  13. htmlStackBuffer.removeAll(keepingCapacity: true)
  14. closure()
  15. if let buffer = htmlStackBuffer[Process.tid] {
  16. self.body = Array<UInt8>(buffer)
  17. }
  18. }
  19. }
  20. public func html(_ status: Int = Status.ok.rawValue, _ closure: ((Void) -> Void)? = nil) -> HtmlResponse {
  21. return HtmlResponse(status) {
  22. htmlStackBuffer[Process.tid] = [UInt8]()
  23. htmlStackBuffer[Process.tid]?.reserveCapacity(1024)
  24. htmlStackBuffer[Process.tid]?.append(contentsOf: "<!DOCTYPE html>".utf8)
  25. "html" ~ {
  26. if let closureFound = closure {
  27. closureFound()
  28. }
  29. }
  30. }
  31. }
  32. infix operator ~
  33. public func ~ (_ left: String, _ closure: ((Void) -> Void)?) {
  34. htmlStackBuffer[Process.tid]?.append(UInt8.lessThan)
  35. var tagName = [UInt8]()
  36. var tagEnd = false
  37. for c in left.utf8 {
  38. switch c {
  39. case UInt8.openingParenthesis:
  40. tagEnd = true
  41. htmlStackBuffer[Process.tid]?.append(.space)
  42. case UInt8.closingParenthesis:
  43. htmlStackBuffer[Process.tid]?.append(.doubleQuotes)
  44. case UInt8.equal:
  45. htmlStackBuffer[Process.tid]?.append(.equal)
  46. htmlStackBuffer[Process.tid]?.append(.doubleQuotes)
  47. case UInt8.comma:
  48. htmlStackBuffer[Process.tid]?.append(.doubleQuotes)
  49. htmlStackBuffer[Process.tid]?.append(.space)
  50. default:
  51. htmlStackBuffer[Process.tid]?.append(c)
  52. }
  53. if !tagEnd {
  54. tagName.append(c)
  55. }
  56. }
  57. htmlStackBuffer[Process.tid]?.append(UInt8.greaterThan)
  58. if let closure = closure {
  59. closure()
  60. }
  61. htmlStackBuffer[Process.tid]?.append(UInt8.lessThan)
  62. htmlStackBuffer[Process.tid]?.append(UInt8.slash)
  63. htmlStackBuffer[Process.tid]?.append(contentsOf: tagName)
  64. htmlStackBuffer[Process.tid]?.append(UInt8.greaterThan)
  65. }
  66. public func ~ (_ left: String, _ right: String) {
  67. htmlStackBuffer[Process.tid]?.append(UInt8.lessThan)
  68. var tagName = [UInt8]()
  69. var tagEnd = false
  70. for c in left.utf8 {
  71. switch c {
  72. case UInt8.openingParenthesis:
  73. tagEnd = true
  74. htmlStackBuffer[Process.tid]?.append(.space)
  75. case UInt8.closingParenthesis:
  76. htmlStackBuffer[Process.tid]?.append(.doubleQuotes)
  77. case UInt8.equal:
  78. htmlStackBuffer[Process.tid]?.append(.equal)
  79. htmlStackBuffer[Process.tid]?.append(.doubleQuotes)
  80. case UInt8.comma:
  81. htmlStackBuffer[Process.tid]?.append(.doubleQuotes)
  82. htmlStackBuffer[Process.tid]?.append(.space)
  83. default:
  84. htmlStackBuffer[Process.tid]?.append(c)
  85. }
  86. if !tagEnd {
  87. tagName.append(c)
  88. }
  89. }
  90. htmlStackBuffer[Process.tid]?.append(UInt8.greaterThan)
  91. htmlStackBuffer[Process.tid]?.append(contentsOf: right.utf8)
  92. htmlStackBuffer[Process.tid]?.append(UInt8.lessThan)
  93. htmlStackBuffer[Process.tid]?.append(UInt8.slash)
  94. htmlStackBuffer[Process.tid]?.append(contentsOf: tagName)
  95. htmlStackBuffer[Process.tid]?.append(UInt8.greaterThan)
  96. }
  97. public func 🦄(port: Int, closure: @escaping (((Response) -> Void) -> Void)) {
  98. do {
  99. let server = try Server()
  100. while true {
  101. try server.serve { (request, responder) in
  102. closure(responder)
  103. }
  104. }
  105. } catch {
  106. print(error)
  107. }
  108. }
  109. public func 🚀(_ responder: ((Response) -> Void), _ text: String? = nil) {
  110. if let text = text {
  111. responder(Response([UInt8](text.utf8)))
  112. } else {
  113. responder(Response(404))
  114. }
  115. }