1

您将如何更改 Rocket 网站上的示例以获取 date 而不是 age/ u8

来自网站的示例:

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use] extern crate rocket;

#[get("/hello/<name>/<age>")]
fn hello(name: String, age: u8) -> String {
    format!("Hello, {} year old named {}!", age, name)
}

fn main() {
    rocket::ignite().mount("/", routes![hello]).launch();
}

我想要或多或少相同的输出(你好,58 岁,名叫约翰!)但是有这样的东西

#[get("/hello/<name>/<birthdate>")]

而不是那个

#[get("/hello/<name>/<age>")]

我认为正确的结构是chrono::DateTime并且以某种方式涉及Rocket::request::FromParam但我从那里有点迷失了。

4

3 回答 3

2

有点糟糕,我们必须自己做这件事。

也许将来会提供一个库,让我们能够在 Rocket 和其他库之间进行互操作。

use chrono::NaiveDate;
use chrono::NaiveTime;
use chrono::NaiveDateTime;

// https://stackoverflow.com/questions/25413201/how-do-i-implement-a-trait-i-dont-own-for-a-type-i-dont-own
// https://github.com/SergioBenitez/Rocket/issues/602#issuecomment-380497269
pub struct NaiveDateForm(NaiveDate);
pub struct NaiveTimeForm(NaiveTime);
pub struct NaiveDateTimeForm(NaiveDateTime);

impl<'v> FromFormValue<'v> for NaiveDateForm {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<NaiveDateForm, &'v RawStr> {
        let decoded = form_value.url_decode().map_err(|_| form_value)?;
        if let Ok(date) = NaiveDate::parse_from_str(&decoded, "%Y-%m-%d") {
            return Ok(NaiveDateForm(date));
        }
        Err(form_value)
    }
}

impl<'v> FromFormValue<'v> for NaiveTimeForm {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<Self, Self::Error> {
        let decoded = form_value.url_decode().map_err(|_| form_value)?;
        if let Ok(time) = NaiveTime::parse_from_str(&decoded, "%H:%M:%S%.3f") {
            // if time.nanosecond() >= 1_000_000_000 {
            //     return Err(form_value);
            // }
            return Ok(NaiveTimeForm(time));
        }
        if let Ok(time) = NaiveTime::parse_from_str(&decoded, "%H:%M") {
            return Ok(NaiveTimeForm(time));
        }
        Err(form_value)
    }
}

impl<'v> FromFormValue<'v> for NaiveDateTimeForm {
    type Error = &'v RawStr;

    fn from_form_value(form_value: &'v RawStr) -> Result<NaiveDateTimeForm, &'v RawStr> {
        let decoded = form_value.url_decode().map_err(|_| form_value)?;
        if decoded.len() < "0000-00-00T00:00".len() {
            return Err(form_value)
        }
        let date = NaiveDateForm::from_form_value(RawStr::from_str(&decoded[.."0000-00-00".len()]))
            .map_err(|_| form_value)?;
        let time = NaiveTimeForm::from_form_value(RawStr::from_str(&decoded["0000-00-00T".len()..]))
            .map_err(|_| form_value)?;
        Ok(NaiveDateTimeForm(NaiveDateTime::new(*date, *time)))
    }
}

impl Deref for NaiveDateForm {
    type Target = NaiveDate;
    fn deref(&self) -> &NaiveDate {
        &self.0
    }
}

impl Deref for NaiveTimeForm {
    type Target = NaiveTime;
    fn deref(&self) -> &NaiveTime {
        &self.0
    }
}

impl Deref for NaiveDateTimeForm {
    type Target = NaiveDateTime;
    fn deref(&self) -> &NaiveDateTime {
        &self.0
    }
}

然后,您应该能够:

#[get("/hello/<name>/<age>")]
fn hello(name: String, age: NaiveDateTimeForm) -> String {
    // Deref back to chrono::NaiveDatetime
    let date_time = *age;

    // write some code to figure out their age
}

我的依赖:

chrono = { version = "0.4.19", features = ["serde"] }
rocket = "0.4.2"

这个实现主要是从https://github.com/chronotope/chrono/pull/362/files偷来的,有人做了 PR 试图把这些东西放到 Chrono 中。

可能而不是age,你应该有birthday,所以你可以计算他们的年龄。

于 2020-12-04T00:42:43.067 回答
0

NaiveDate可以用 type 表示为“自 1 月 1 日以来的天数” i32。有方法self.num_days_from_ce()from_num_days_from_ce()。我相信这是最方便的方式。文档

于 2019-03-07T07:57:40.287 回答
0

我使用火箭 0.5 的工作版本遵循 harvzor 的代码。

  use chrono::NaiveDate;
  use chrono::ParseError;
  
  use rocket::request::FromParam;
  
  // https://stackoverflow.com/questions/25413201/how-do-i-implement-a-      trait-i-dont-own-for-a-type-i-dont-own
  // https://github.com/SergioBenitez/Rocket/issues/602#issuecomment-380497269
  pub struct NaiveDateForm(pub NaiveDate);


  impl<'a> FromParam<'a> for NaiveDateForm {
      type Error = ParseError;
  
      fn from_param(param: &'a str) -> Result<Self, Self::Error>{
        match NaiveDate::parse_from_str(&param, "%Y-%m-%d") {
            Ok(date)=> Ok(NaiveDateForm(date)),
            Err(e) =>Err(e),
          }
      }
  }
于 2021-08-27T08:40:15.020 回答