Replies: 2 comments
-
I'm not sure if this is the best way of doing this, but my approach for this kind of issue is like so: use rocket::http::Status;
use rocket::request::{FromRequest, Outcome, Request};
use rocket::{get, launch, routes};
#[derive(Debug)]
pub struct NaiveDate {
year: u64,
}
#[derive(Debug)]
pub struct NaiveDateGuard {
inner: Option<NaiveDate>,
}
#[derive(Debug)]
pub enum NaiveDateError {
Missing,
Invalid,
}
// In this trait we can pick and chose the outcome and reject/continue the request accordingly
// however this trait can't be implemented for Option<NaiveDate> so instead we wrap the optionality
// into it's params
#[rocket::async_trait]
impl<'r> FromRequest<'r> for NaiveDateGuard {
type Error = NaiveDateError;
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let query_params = req.uri().query().map(|qp| {
qp.split("&")
.map(|r| r.as_str())
.filter(|param| param.contains("date"))
.next()
.map(|date| {
date.split_terminator('=').skip(1).next().map(|segment| {
segment
.split_terminator('-')
.next()
.map(|segment| segment.parse::<u64>())
})
})
});
match query_params {
Some(Some(Some(Some(Ok(year))))) => Outcome::Success(NaiveDateGuard {
inner: Some(NaiveDate { year }),
}),
None | Some(None) => Outcome::Success(NaiveDateGuard { inner: None }),
_ => Outcome::Failure((Status::Unauthorized, NaiveDateError::Missing)),
}
}
}
#[get("/")]
async fn get_competition(date: NaiveDateGuard) -> String {
format!("{date:?}")
}
#[launch]
fn rocket_mount() -> _ {
rocket::build().mount("/", routes![get_competition])
}
#[cfg(test)]
mod test {
use super::rocket_mount;
use rocket::http::Status;
use rocket::local::blocking::Client;
#[test]
fn when_no_date_is_provided_continue_with_none() {
let client = Client::tracked(rocket_mount()).expect("valid rocket instance");
let response = client.get("/").dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(
response.into_string().unwrap(),
"NaiveDateGuard { inner: None }"
);
}
#[test]
fn when_some_date_is_provided_continue_with_some_date() {
let client = Client::tracked(rocket_mount()).expect("valid rocket instance");
let response = client.get("/?date=2023-01-23").dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(
response.into_string().unwrap(),
"NaiveDateGuard { inner: Some(NaiveDate { year: 2023 }) }"
);
}
#[test]
fn when_invalid_date_is_provided_return_401() {
let client = Client::tracked(rocket_mount()).expect("valid rocket instance");
let response = client.get("/?date=not_a_year-01-23").dispatch();
assert_eq!(response.status(), Status::Unauthorized);
}
} By using the |
Beta Was this translation helpful? Give feedback.
0 replies
-
I have the same issue, any idea how to solve this ? I use |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I have this scenario:
And I'd like the following to happen:
Is there a way to accomplish the third requirement?
Beta Was this translation helpful? Give feedback.
All reactions