Rocket icon indicating copy to clipboard operation
Rocket copied to clipboard

Impl FromFormField for Decimal type

Open etsea117 opened this issue 2 years ago • 1 comments

Existing Functionality I am attempting to record monetary transactions and would like to use rust_decimal::Decimal for this field, but it requires me to implement FromFormField to use this. I would prefer not to use an f64 type for this, as it is not recommended.

Suggested Changes

Can rust_decimal::Decimal be included in the standard implementation?

I have been struggling to complete the implementation, as the example shows a struct with multiple key: value pairs and Decimal doesn't have this format.

etsea117 avatar Jul 31 '22 21:07 etsea117

Wouldn't an integer type be better for monetary values? If you store your prices in cents, you'll have the best precision and speed possible. However, if you're dealing with sub-cent values, it may indeed be better to use rust_decimal.

If you really want to use rust_decimal, you will have to make a newtype around Decimal so you can implement FromFormType yourself. Maybe something like that could work? (not tested)

struct MyDecimal(Decimal);

#[rocket::async_trait]
impl<'r> FromFormField<'r> for MyDecimal {
    fn from_value(field: ValueField<'r>) -> form::Result<'r, Self> {
        Decimal::from_str(field.value)
            .map(Self)
            .map_err(|e| rocket::form::Error::custom(e).into())
    }

    async fn from_data(field: DataField<'r, '_>) -> Result<'v, Self> {
        unimplemented!()
    }

    fn default() -> Option<Self> {
        Self(Decimal::default())
    }
]

edgarogh avatar Aug 29 '22 11:08 edgarogh

Can I take this up ?

GentBinaku avatar Sep 29 '22 11:09 GentBinaku

If you really want to use rust_decimal, you will have to make a newtype around Decimal so you can implement FromFormType yourself. Maybe something like that could work? (not tested)

Exactly. I don't think Rocket should be adding dependencies, optional or not, for every type we might want trait implementations for. Perhaps the other library would be willing to do, and that'd be great. Otherwise, we're unfortunately stuck with this limitation of Rust and the necessary workarounds.

SergioBenitez avatar Mar 31 '23 18:03 SergioBenitez