Skip to content

Instantly share code, notes, and snippets.

@rob4226
Forked from vlio20/StatusCode.kt
Last active September 22, 2024 16:48
Show Gist options
  • Save rob4226/d7996d5e1947bebaeb01f6f7cf2b9281 to your computer and use it in GitHub Desktop.
Save rob4226/d7996d5e1947bebaeb01f6f7cf2b9281 to your computer and use it in GitHub Desktop.
Kotlin HTTP Status Codes enum with code in enum constant names
package com.rob4226.networking
/**
* HTTP status codes.
*
* [Hypertext Transfer Protocol (HTTP) Status Code Registry](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml)
*
* __Status code categories:__
* + __1xx: Informational__ - Request received, continuing process.
* + __2xx: Success__ - The action was successfully received, understood, and accepted.
* + __3xx: Redirection__ - Further action must be taken in order to complete the request.
* + __4xx: Client Error__ - The request contains bad syntax or cannot be fulfilled.
* + __5xx: Server Error__ - The server failed to fulfill an apparently valid request.
*/
enum class HttpStatus(
val code: Int,
) {
CONTINUE_100(100),
SWITCHING_PROTOCOLS_101(101),
PROCESSING_102(102),
EARLY_HINTS_103(103),
OK_200(200),
CREATED_201(201),
ACCEPTED_202(202),
NON_AUTHORITATIVE_INFORMATION_203(203),
NO_CONTENT_204(204),
RESET_CONTENT_205(205),
PARTIAL_CONTENT_206(206),
MULTI_STATUS_207(207),
ALREADY_REPORTED_208(208),
IM_USED_226(226),
MULTIPLE_CHOICES_300(300),
MOVED_PERMANENTLY_301(301),
FOUND_302(302),
SEE_OTHER_303(303),
NOT_MODIFIED_304(304),
USE_PROXY_305(305),
TEMPORARY_REDIRECT_307(307),
PERMANENT_REDIRECT_308(308),
BAD_REQUEST_400(400),
UNAUTHORIZED_401(401),
PAYMENT_REQUIRED_402(402),
FORBIDDEN_403(403),
NOT_FOUND_404(404),
METHOD_NOT_ALLOWED_405(405),
NOT_ACCEPTABLE_406(406),
PROXY_AUTHENTICATION_REQUIRED_407(407),
REQUEST_TIMEOUT_408(408),
CONFLICT_409(409),
GONE_410(410),
LENGTH_REQUIRED_411(411),
PRECONDITION_FAILED_412(412),
CONTENT_TOO_LARGE_413(413),
URI_TOO_LONG_414(414),
UNSUPPORTED_MEDIA_TYPE_415(415),
RANGE_NOT_SATISFIABLE_416(416),
EXPECTATION_FAILED_417(417),
I_AM_A_TEAPOT_418(418),
MISDIRECTED_REQUEST_421(421),
UNPROCESSABLE_CONTENT_422(422),
LOCKED_423(423),
FAILED_DEPENDENCY_424(424),
TOO_EARLY_425(425),
UPGRADE_REQUIRED_426(426),
PRECONDITION_REQUIRED_428(428),
TOO_MANY_REQUESTS_429(429),
REQUEST_HEADER_FIELDS_TOO_LARGE_431(431),
UNAVAILABLE_FOR_LEGAL_REASONS_451(451),
INTERNAL_SERVER_ERROR_500(500),
NOT_IMPLEMENTED_501(501),
BAD_GATEWAY_502(502),
SERVICE_UNAVAILABLE_503(503),
GATEWAY_TIMEOUT_504(504),
HTTP_VERSION_NOT_SUPPORTED_505(505),
VARIANT_ALSO_NEGOTIATES_506(506),
INSUFFICIENT_STORAGE_507(507),
LOOP_DETECTED_508(508),
NOT_EXTENDED_510(510),
NETWORK_AUTHENTICATION_REQUIRED_511(511),
UNKNOWN(0),
;
/** The message of this HTTP code status (really just the enum constant [name]) */
val message: String
get() = this.name
/**
* Determine if this HTTP status falls into the
* __Informational__ message category as defined in the
* [RFC 1945 - HTTP/1.0](http://tools.ietf.org/html/rfc1945), and
* [RFC 7231 - HTTP/1.1](http://tools.ietf.org/html/rfc7231).
*
* > __1xx: Informational__ - Request received, continuing process.
*
* @return `true` if within range of codes that belongs to
* __Informational__ messages.
*/
fun isInformational(): Boolean = ((CONTINUE_100.code <= this.code) && (this.code <= 199))
/**
* Determine if this HTTP status is informational but not
* [SWITCHING_PROTOCOLS_101].
*
* @return whether this HTTP status is informational but not __101
* Switching Protocols__.
*/
fun isInterim(): Boolean = this.isInformational() && this != SWITCHING_PROTOCOLS_101
/**
* Determine if this HTTP status falls into the
* __Success__ message category as defined in the
* [RFC 1945 - HTTP/1.0](http://tools.ietf.org/html/rfc1945), and
* [RFC 7231 - HTTP/1.1](http://tools.ietf.org/html/rfc7231).
*
* > __2xx: Success__ - The action was successfully received, understood, and accepted.
*
* @return `true` if within range of codes that belongs to __Success__
* messages.
*/
fun isSuccess(): Boolean = ((OK_200.code <= this.code) && (this.code <= 299))
/**
* Determine if this HTTP status falls into the
* __Redirection__ message category as defined in the
* [RFC 1945 - HTTP/1.0](http://tools.ietf.org/html/rfc1945), and
* [RFC 7231 - HTTP/1.1](http://tools.ietf.org/html/rfc7231).
*
* > __3xx: Redirection__ - Further action must be taken in order to complete the request.
*
* @return `true` if within range of codes that belongs to __Redirection__
* messages.
*/
fun isRedirection(): Boolean = ((MULTIPLE_CHOICES_300.code <= this.code) && (this.code <= 399))
/**
* Determine if this HTTP status falls into the
* __Client Error__ message category as defined in the
* [RFC 1945 - HTTP/1.0](http://tools.ietf.org/html/rfc1945), and
* [RFC 7231 - HTTP/1.1](http://tools.ietf.org/html/rfc7231).
*
* > __4xx: Client Error__ - The request contains bad syntax or cannot be fulfilled.
*
* @return `true` if within range of codes that belongs to __Client Error__
* messages.
*/
fun isClientError(): Boolean = ((BAD_REQUEST_400.code <= this.code) && (this.code <= 499))
/**
* Determine if this HTTP status falls into the
* __Server Error__ message category as defined in the
* [RFC 1945 - HTTP/1.0](http://tools.ietf.org/html/rfc1945), and
* [RFC 7231 - HTTP/1.1](http://tools.ietf.org/html/rfc7231).
*
* > __5xx: Server Error__ - The server failed to fulfill an apparently valid request.
*
* @return `true` if within range of codes that belongs to __Server Error__
* messages.
*/
fun isServerError(): Boolean = ((INTERNAL_SERVER_ERROR_500.code <= this.code) && (this.code <= 599))
/**
* Determine if this HTTP status normally has no body.
*
* @return `true` if this HTTP status normally does not have a body.
*/
fun hasNoBody(): Boolean =
when (this) {
NO_CONTENT_204, RESET_CONTENT_205, PARTIAL_CONTENT_206, NOT_MODIFIED_304 -> true
else -> this.code < OK_200.code
}
companion object {
/** Get HTTP status constant from the given [code]. */
fun from(code: Int): HttpStatus =
HttpStatus.entries.find {
it.code == code
} ?: UNKNOWN
/** Get HTTP status from [Int]. */
fun Int.toHttpStatus(): HttpStatus = HttpStatus.from(this)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment