我正在使用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