Skip to content

Commit

Permalink
docs(web): add comprehensive documentation for responder module
Browse files Browse the repository at this point in the history
  • Loading branch information
zavakid committed Dec 12, 2024
1 parent 00e95b3 commit 732a300
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions crates/web/src/responder.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,42 @@
//! Response handling module that converts handler results into HTTP responses.
//!
//! This module provides the [`Responder`] trait which defines how different types
//! can be converted into HTTP responses. It includes implementations for common types
//! like Result, Option, String, etc.
//!
//! The [`Responder`] trait is a key part of the response pipeline, allowing handler
//! return values to be automatically converted into proper HTTP responses.
use crate::body::ResponseBody;
use crate::RequestContext;
use http::{Response, StatusCode};

/// A trait for types that can be converted into HTTP responses.
///
/// Types implementing this trait can be returned directly from request handlers
/// and will be automatically converted into HTTP responses.
///
/// # Examples
///
/// ```no_run
/// # use http::Response;
/// # use crate::web::{Responder, ResponseBody, RequestContext};
///
/// // Implementing Responder for a custom type
/// struct CustomResponse(String);
///
/// impl Responder for CustomResponse {
/// fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
/// Response::new(ResponseBody::from(self.0))
/// }
/// }
/// ```
pub trait Responder {
fn response_to(self, req: &RequestContext) -> Response<ResponseBody>;
}

/// Implementation for Result allows handlers to return Result types directly.
/// The Ok and Err variants must both implement Responder.
impl<T: Responder, E: Responder> Responder for Result<T, E> {
fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
match self {
Expand All @@ -15,6 +46,8 @@ impl<T: Responder, E: Responder> Responder for Result<T, E> {
}
}

/// Implementation for Option allows handlers to return Option types.
/// None case returns an empty response.
impl<T: Responder> Responder for Option<T> {
fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
match self {
Expand All @@ -24,6 +57,8 @@ impl<T: Responder> Responder for Option<T> {
}
}

/// Implementation for Response allows passing through pre-built responses.
/// The response body is converted to the internal ResponseBody type.
impl<B> Responder for Response<B>
where
B: Into<ResponseBody>,
Expand All @@ -33,6 +68,8 @@ where
}
}

/// Implementation for (StatusCode, T) tuple allows setting a status code
/// along with the response content.
impl<T: Responder> Responder for (StatusCode, T) {
fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
let (status, responder) = self;
Expand All @@ -42,25 +79,29 @@ impl<T: Responder> Responder for (StatusCode, T) {
}
}

/// Implementation for (T, StatusCode) tuple - same as above but with reversed order.
impl<T: Responder> Responder for (T, StatusCode) {
fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
let (responder, status) = self;
(status, responder).response_to(req)
}
}

/// Implementation for Box<T> allows boxing responders.
impl<T: Responder> Responder for Box<T> {
fn response_to(self, req: &RequestContext) -> Response<ResponseBody> {
(*self).response_to(req)
}
}

/// Implementation for unit type () returns an empty response.
impl Responder for () {
fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
Response::new(ResponseBody::empty())
}
}

/// Implementation for static strings returns them as plain text responses.
impl Responder for &'static str {
fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
let mut builder = Response::builder();
Expand All @@ -72,6 +113,7 @@ impl Responder for &'static str {
}
}

/// Implementation for String returns it as a plain text response.
impl Responder for String {
fn response_to(self, _req: &RequestContext) -> Response<ResponseBody> {
let mut builder = Response::builder();
Expand Down

0 comments on commit 732a300

Please sign in to comment.