lambda_router/runtime/
try_route.rs

1//! # try_route
2//! "tries" to match a route and method to a request, also tries to deserialize inputs if the routes and methods check out.
3
4use lambda_http::{http::Method, RequestExt, RequestPayloadExt};
5use serde::de::DeserializeOwned;
6
7use super::error::Error;
8
9/// attemps to match an inbound route to a route given by a handler
10/// it is the runtime version of routing for the app! macro
11/// it simply checks if the routes are equal as str
12/// if they match it then checks that the methods are the same
13/// from there it desererializes data either from json or url encoded
14/// based on the method, if all goes well, it returns the deserialized type "T"
15/// which is later passed to the handler you write
16pub fn try_route<T: DeserializeOwned>(
17    event: &lambda_http::Request,
18    method: lambda_http::http::Method,
19    route: &str,
20    inbound: Option<&str>,
21) -> Result<T, Error> {
22    if inbound.map(|el| el != route).unwrap_or_default() {
23        return Err(Error::NotFound);
24    }
25    if event.method() != method {
26        return Err(Error::MethodNotAllowed);
27    }
28
29    match event.method() {
30        &Method::GET | &Method::DELETE => {
31            let qs = event.query_string_parameters().to_query_string();
32            Ok(serde_urlencoded::from_str(&qs)?)
33        }
34        _ => match event.payload() {
35            Ok(Some(payload)) => Ok(payload),
36            Ok(None) => Err(Error::NoPayload),
37            Err(err) => Err(Error::Payload(err)),
38        },
39    }
40}