use crate::{ handling::{ methods::Method, request::{MediaType, Request}, response::{Outcome, Response, Status}, }, utils::{mime::Mime, url_utils::RawUri}, }; /// A RouteBuilder struct pub struct RoutBuilder { /// An optional name of the route name: Option<&'static str>, /// The [Method] via which the route is accesable method: Method, /// The path of the route, allows special cases: /// # Examples /// ``` /// "/home"; // Only /home /// "/<home>/something"; /// // Variable content the users provides this acts for /<anything>/something /// "/<home..>"; /// // All Information after this sequence is irrelvent /// // Matches: /a, /a/b/c ... /// ``` path: &'static str, /// The Handler function for this route, which gets called when the request need the route. /// Inputs to the function are an [Request] and the [Data] which represents the body of the /// [Request]. The Outcome is expected to be an [Outcome], which is a [Response], A [Status] if /// something went wrong and a [Status] page is need or a [Outcome::Forward] of the requests /// [Data] for the next [Route] to take care of. handler: fn(Request, Data) -> Outcome<Response, Status, Data>, /// The Specific answer format of the [Route] as a [MediaType]. Optional format: Option<MediaType>, /// The Optional Rank of the Route, dependent on its specificness. so the rank of a uri `"/home"` would be /// ranked high, whereas a uri of `"/<anything..>"` would be ranked the lowest /// If not given generated based on parematers. rank: Option<isize>, } /// A struct to define Routes on the Server #[derive(Clone)] pub struct Route { /// An optional name of the route pub name: Option<&'static str>, /// The [Method] via which the route is accesable pub method: Method, /// The Uri of the route, allows special cases: /// # Examples /// ``` /// "/home"; // Only /home /// "/<home>/something"; /// // Variable content the users provides this acts for /<anything>/something /// "/<home..>"; /// // All Information after this sequence is irrelvent /// // Matches: /a, /a/b/c ... /// ``` pub uri: RawUri, /// The Handler function for this route, which gets called when the request need the route. /// Inputs to the function are an [Request] and the [Data] which represents the body of the /// [Request]. The Outcome is expected to be an [Outcome], which is a [Response], A [Status] if /// something went wrong and a [Status] page is need or a [Outcome::Forward] of the requests /// [Data] for the next [Route] to take care of. pub handler: fn(Request, Data) -> Outcome<Response, Status, Data>, /// The Rank of the Route, dependent on its specificness. so the rank of a uri `"/home"` would be /// ranked high, whereas a uri of `"/<anything..>"` would be ranked the lowest pub rank: isize, /// The Specific answer format of the [Route] as a [MediaType]. Optional pub format: Option<MediaType>, } impl Route { /// generates a Route from a Routebuilder //TODO: ranking pub fn from(routeinfo: RoutBuilder) -> Self { let rank = routeinfo.rank.unwrap_or(0); Route { name: routeinfo.name, method: routeinfo.method, uri: routeinfo .path .try_into() .unwrap_or_else(|_| panic!("Incorrect RawUri for path {}", routeinfo.path)), handler: routeinfo.handler, rank, format: routeinfo.format, } } } /// Alias for using a &'a str for Uri #[derive(Debug, Clone)] /// A basic Body type for respones pub struct Body { /// The Response body body: Vec<u8>, /// The Mime Type mime_type: Mime, } impl Body { /// New body of a Response pub fn new(body: Vec<u8>, mime_type: Mime) -> Self { Self { body, mime_type } } /// Sets the `mime_type` of the Body pub fn set_mime_type(&mut self, mime_type: Mime) { self.mime_type = mime_type; } /// Reassigns the body pub fn set_body(&mut self, body: Vec<u8>) { self.body = body; } /// mime_type of the body pub fn mime_type(&self) -> Mime { self.mime_type } /// cloned body as [`Vec<u8>`] pub fn body(&self) -> Vec<u8> { self.body.clone() } } #[derive(Debug, Clone)] /// Data of the Body of a [Request] pub struct Data { /// The Data pub buffer: Vec<u8>, /// For Split Data if it is complete pub is_complete: bool, } impl Data { /// Checks if the buffer.oen() is -0 pub fn is_empty(&self) -> bool { self.buffer.len() == 0 } }