我正在使用Vapor,但這是一個純粹的Swift問題。蒸氣具有枚舉「狀態」定義爲:(我刪除在這裏枚舉某些情況下這個代碼已經是相當長)更改枚舉的功能
public enum Status {
case `continue`
case switchingProtocols
case processing
case ok
case created
case accepted
case nonAuthoritativeInformation
case noContent
case resetContent
case partialContent
case multipleChoices
case movedPermanently
case found
case seeOther
case notModified
case useProxy
case switchProxy
case temporaryRedirect
case permanentRedirect
case badRequest
case unauthorized
case paymentRequired
case forbidden
case notFound
case methodNotAllowed
case notAcceptable
//removed a bunch of other 'cases' for the sake of brevity
case other(statusCode: Int, reasonPhrase: String)
}
extension Status {
public init?(officialCode: Int) {
switch officialCode {
case Status.`continue`.statusCode: self = .`continue`
case Status.switchingProtocols.statusCode: self = .switchingProtocols
case Status.processing.statusCode: self = .processing
case Status.ok.statusCode: self = .ok
case Status.created.statusCode: self = .created
case Status.accepted.statusCode: self = .accepted
case Status.nonAuthoritativeInformation.statusCode: self = .nonAuthoritativeInformation
case Status.noContent.statusCode: self = .noContent
case Status.resetContent.statusCode: self = .resetContent
case Status.partialContent.statusCode: self = .partialContent
case Status.multipleChoices.statusCode: self = .multipleChoices
case Status.movedPermanently.statusCode: self = .movedPermanently
case Status.found.statusCode: self = .found
case Status.seeOther.statusCode: self = .seeOther
case Status.notModified.statusCode: self = .notModified
case Status.useProxy.statusCode: self = .useProxy
case Status.switchProxy.statusCode: self = .switchProxy
case Status.temporaryRedirect.statusCode: self = .temporaryRedirect
case Status.permanentRedirect.statusCode: self = .permanentRedirect
case Status.badRequest.statusCode: self = .badRequest
case Status.unauthorized.statusCode: self = .unauthorized
case Status.paymentRequired.statusCode: self = .paymentRequired
case Status.forbidden.statusCode: self = .forbidden
case Status.notFound.statusCode: self = .notFound
case Status.methodNotAllowed.statusCode: self = .methodNotAllowed
case Status.notAcceptable.statusCode: self = .notAcceptable
default: return nil
}
}
public init(statusCode: Int, reasonPhrase: String? = nil) {
if let official = Status(officialCode: statusCode) {
self = official
} else {
self = .other(statusCode: statusCode, reasonPhrase: reasonPhrase ?? "")
}
}
}
extension Status {
public var statusCode: Int {
switch self {
case .`continue`: return 100
case .switchingProtocols: return 101
case .processing: return 102
case .ok: return 200
case .created: return 201
case .accepted: return 202
case .nonAuthoritativeInformation: return 203
case .noContent: return 204
case .resetContent: return 205
case .partialContent: return 206
case .multipleChoices: return 300
case .movedPermanently: return 301
case .found: return 302
case .seeOther: return 303
case .notModified: return 304
case .useProxy: return 305
case .switchProxy: return 306
case .temporaryRedirect: return 307
case .permanentRedirect: return 308
case .badRequest: return 400
case .unauthorized: return 401
case .paymentRequired: return 402
case .forbidden: return 403
case .notFound: return 404
case .methodNotAllowed: return 405
case .notAcceptable: return 406
case .other(let statusCode, _): return statusCode
}
}
}
extension Status {
public var reasonPhrase: String {
switch self {
case .`continue`: return "Continue"
case .switchingProtocols: return "Switching Protocols"
case .processing: return "Processing"
case .ok: return "OK"
case .created: return "Created"
case .accepted: return "Accepted"
case .nonAuthoritativeInformation: return "Non Authoritative Information"
case .noContent: return "No Content"
case .resetContent: return "Reset Content"
case .partialContent: return "Partial Content"
case .multipleChoices: return "Multiple Choices"
case .movedPermanently: return "Moved Permanently"
case .found: return "Found"
case .seeOther: return "See Other"
case .notModified: return "Not Modified"
case .useProxy: return "Use Proxy"
case .switchProxy: return "Switch Proxy"
case .temporaryRedirect: return "Temporary Redirect"
case .permanentRedirect: return "Permanent Redirect"
case .badRequest: return "Bad Request"
case .unauthorized: return "Unauthorized"
case .paymentRequired: return "Payment Required"
case .forbidden: return "Forbidden"
case .notFound: return "Not Found"
case .methodNotAllowed: return "Method Not Allowed"
case .notAcceptable: return "Not Acceptable"
case .other(_, let reasonPhrase): return reasonPhrase
}
}
}
extension Status: Hashable {
public var hashValue: Int {
return statusCode
}
}
public func ==(lhs: Status, rhs: Status) -> Bool {
return lhs.hashValue == rhs.hashValue
}
這個定義我可以做一個
let status = Status (.notFound)
方式並用投擲使用它:然後
throw Abort (status)
的罰球將顯示404錯誤與以下文字:「未找到」。我想定製該文本。但是,創造一個狀態:
let status = Status(.notFound, reasonPhrase: "my own text")
仍然會顯示默認的文本
我唯一能做的事情就是創建一個狀態:
let status = Status(999, reasonPhrase: "my own text")
在狀態代碼是不是一個標準的錯誤號。
這可能會令人困惑,而不是標準。你能告訴我如何在Swift中我可以重寫這種行爲或擴展狀態或......以便我能夠用自定義文本創建標準錯誤(例如404 = .notFound)
*編輯爲與CRD解決遺留問題*
我添加使用init延伸狀態的文件: 擴展狀態
extension Status {
public init(status: Status, customReason: String)
{
self = .other(statusCode: status.statusCode, reasonPhrase: customReason)
}
}
在我的代碼,我用它:
let status = Status(status: .notFound, customReason: "test")
throw Abort(status)
它仍然顯示:404 +我沒有在我發現的HTML頁面上找到。 然後我增加了打印,就像CRD在操場上做的:
let status = Status(status: .notFound, customReason: "test")
print ("\(status.statusCode) : \(status.reasonPhrase)")
throw Abort(status)
打印顯示:404:測試在控制檯中,HTML錯誤頁面顯示404 +未找到就像它之前。顯然Vapor的中止函數正在操縱這個...GRRRR
望着'公共的init(的StatusCode的實現:詮釋,reasonPhrase:字符串? = nil)'初始化器,如果它存在,即使非調用者提供了非'nil'' reasonPhrase'參數,它將會退回到官方的'reasonPhrase'上。如果沒有正式的'reasonPhrase'存在並且沒有用戶提供,''「'將被使用。對於在類型聲明的不同文件上實現自定義初始值設定項的規則(例如Vapor的lib),我感到很慚愧,但是你可以在'Status'擴展中實現你自己的初始值設定項。 – dfri
這是一個想法,但我沒有找到一種方法來「覆蓋」現有的init。如果我只是用正確的代碼添加一個init,它會使用Vapor的lib – Glenn