mirror of
https://github.com/zerotier/ratpack.git
synced 2026-05-22 16:27:23 -07:00
about halfway done with API docs
Signed-off-by: Erik Hollensbe <linux@hollensbe.org>
This commit is contained in:
+63
@@ -6,6 +6,37 @@ use tokio::{net::TcpListener, sync::Mutex};
|
||||
|
||||
use crate::{handler::Handler, router::Router, Error, ServerError};
|
||||
|
||||
/// App is used to define application-level functionality and initialize the server. Routes are
|
||||
/// typically programmed here.
|
||||
///
|
||||
/// ```ignore
|
||||
/// async fn item(
|
||||
/// req: Request<Body>,
|
||||
/// resp: Option<Response<Body>>,
|
||||
/// params: Params,
|
||||
/// app: App<()>
|
||||
/// ) -> HTTPResult {
|
||||
/// Ok((
|
||||
/// req,
|
||||
/// Response::builder().
|
||||
/// status(StatusCode::OK).
|
||||
/// body(Body::default()).
|
||||
/// unwrap()
|
||||
/// ))
|
||||
/// }
|
||||
///
|
||||
/// #[tokio::main]
|
||||
/// async fn main() -> Result<(), ServerError> {
|
||||
/// let app = App::new();
|
||||
/// app.get("/:item", compose_handler!(item));
|
||||
/// app.serve("localhost:0").await
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Note that App here has _no state_. It will have a type signature of `App<()>`. To carry state,
|
||||
/// look at the `with_state` method which will change the type signature of the `item` call (and
|
||||
/// other handlers).
|
||||
///
|
||||
#[derive(Clone)]
|
||||
pub struct App<S: Clone + Send> {
|
||||
router: Router<S>,
|
||||
@@ -13,6 +44,7 @@ pub struct App<S: Clone + Send> {
|
||||
}
|
||||
|
||||
impl<S: 'static + Clone + Send> App<S> {
|
||||
/// Construct a new App with no state; it will be passed to handlers as `App<()>`.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
router: Router::new(),
|
||||
@@ -20,6 +52,11 @@ impl<S: 'static + Clone + Send> App<S> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct an App with state.
|
||||
///
|
||||
/// This has the type `App<S>` where S is `+ 'static + Clone + Send` and will be passed to
|
||||
/// handlers with the appropriate concrete type.
|
||||
///
|
||||
pub fn with_state(state: S) -> Self {
|
||||
Self {
|
||||
router: Router::new(),
|
||||
@@ -27,46 +64,70 @@ impl<S: 'static + Clone + Send> App<S> {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME Currently you must await this, seems pointless.
|
||||
/// Return the state of the App. This is returned as `Arc<Mutex<S>>` and must be acquired under
|
||||
/// lock. In situations where there is no state, [std::option::Option::None] is returned.
|
||||
pub async fn state(&self) -> Option<Arc<Mutex<S>>> {
|
||||
self.global_state.clone()
|
||||
}
|
||||
|
||||
/// Create a route for a GET request. See [crate::path::Path] and [crate::handler::Handler] for
|
||||
/// more information.
|
||||
pub fn get(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::GET, path.to_string(), ch);
|
||||
}
|
||||
|
||||
/// Create a route for a POST request. See [crate::path::Path] and [crate::handler::Handler] for
|
||||
/// more information.
|
||||
pub fn post(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::POST, path.to_string(), ch);
|
||||
}
|
||||
|
||||
/// Create a route for a DELETE request. See [crate::path::Path] and [crate::handler::Handler] for
|
||||
/// more information.
|
||||
pub fn delete(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::DELETE, path.to_string(), ch);
|
||||
}
|
||||
|
||||
/// Create a route for a PUT request. See [crate::path::Path] and [crate::handler::Handler] for
|
||||
/// more information.
|
||||
pub fn put(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::PUT, path.to_string(), ch);
|
||||
}
|
||||
|
||||
/// Create a route for an OPTIONS request. See [crate::path::Path] and
|
||||
/// [crate::handler::Handler] for more information.
|
||||
pub fn options(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::OPTIONS, path.to_string(), ch);
|
||||
}
|
||||
|
||||
/// Create a route for a PATCH request. See [crate::path::Path] and
|
||||
/// [crate::handler::Handler] for more information.
|
||||
pub fn patch(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::PATCH, path.to_string(), ch);
|
||||
}
|
||||
|
||||
/// Create a route for a HEAD request. See [crate::path::Path] and
|
||||
/// [crate::handler::Handler] for more information.
|
||||
pub fn head(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::HEAD, path.to_string(), ch);
|
||||
}
|
||||
|
||||
/// Create a route for a CONNECT request. See [crate::path::Path] and
|
||||
/// [crate::handler::Handler] for more information.
|
||||
pub fn connect(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::CONNECT, path.to_string(), ch);
|
||||
}
|
||||
|
||||
/// Create a route for a TRACE request. See [crate::path::Path] and
|
||||
/// [crate::handler::Handler] for more information.
|
||||
pub fn trace(&mut self, path: &str, ch: Handler<S>) {
|
||||
self.router.add(Method::TRACE, path.to_string(), ch);
|
||||
}
|
||||
|
||||
/// Dispatch a route based on the request. Returns a response based on the error status of the
|
||||
/// handler chain following the normal chain of responsibility rules described elsewhere. Only
|
||||
/// needed by server implementors.
|
||||
pub async fn dispatch(&self, req: Request<Body>) -> Result<Response<Body>, Infallible> {
|
||||
match self.router.dispatch(req, self.clone()).await {
|
||||
Ok(resp) => Ok(resp),
|
||||
@@ -83,6 +144,8 @@ impl<S: 'static + Clone + Send> App<S> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Start a TCP/HTTP server with tokio. Performs dispatch on an as-needed basis. This is a more
|
||||
/// common path for users to start a server.
|
||||
pub async fn serve(self, addr: &str) -> Result<(), ServerError> {
|
||||
let socketaddr: SocketAddr = addr.parse()?;
|
||||
|
||||
|
||||
+14
@@ -1,7 +1,12 @@
|
||||
/// Application/Server-level management and routing configuration; outermost functionality.
|
||||
pub mod app;
|
||||
/// Handler construction and prototypes
|
||||
pub mod handler;
|
||||
/// Macros for quality-of-life when interacting with Handlers
|
||||
pub mod macros;
|
||||
/// Path management for Routes
|
||||
pub mod path;
|
||||
/// Router, Route management and organization
|
||||
pub mod router;
|
||||
|
||||
use http::{Request, Response};
|
||||
@@ -9,6 +14,7 @@ use std::pin::Pin;
|
||||
|
||||
pub(crate) type PinBox<F> = Pin<Box<F>>;
|
||||
|
||||
/// An error for server-related issues.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ServerError(String);
|
||||
|
||||
@@ -21,6 +27,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// General errors for ratpack handlers. Yield either a StatusCode for a literal status, or a
|
||||
/// String for a 500 Internal Server Error. Other status codes should be yielded through
|
||||
/// [http::Response] returns.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Error {
|
||||
StatusCode(http::StatusCode),
|
||||
@@ -34,6 +43,7 @@ impl Default for Error {
|
||||
}
|
||||
|
||||
impl Error {
|
||||
/// Convenience method to pass anything in that accepts a .to_string method.
|
||||
pub fn new<T>(message: T) -> Self
|
||||
where
|
||||
T: ToString,
|
||||
@@ -41,6 +51,7 @@ impl Error {
|
||||
Self::InternalServerError(message.to_string())
|
||||
}
|
||||
|
||||
/// A convenient way to return status codes.
|
||||
pub fn new_status(error: http::StatusCode) -> Self {
|
||||
Self::StatusCode(error)
|
||||
}
|
||||
@@ -55,4 +66,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// HTTPResult is the return type for handlers. If a handler terminates at the end of its chain
|
||||
/// with [std::option::Option::None] as the [http::Response], a 500 Internal Server Error will be
|
||||
/// returned.
|
||||
pub type HTTPResult = Result<(Request<hyper::Body>, Option<Response<hyper::Body>>), Error>;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/// compose_handler allows you to combine [crate::handler::HandlerFunc] functions into a single [crate::handler::Handler], so that
|
||||
/// they cascade through a chain of responsibility. This means that each handler will feed its
|
||||
/// output into the input of the next. To start, the first [http::Response] is
|
||||
/// [std::option::Option::None], and the final return Response must be non-None otherwise a 500
|
||||
/// Internal Server Error is returned. Handlers may do anything they wish to the [http::Request] between
|
||||
/// processing periods, including replacing the request entirely.
|
||||
#[macro_export]
|
||||
macro_rules! compose_handler {
|
||||
($( $x:path ),*) => {
|
||||
|
||||
Reference in New Issue
Block a user