Open MitchellNeill opened 1 year ago
Hmm, I wonder if you can achieve this by calling out to try_from
(of which we implement for each primitive type) followed by ok()
to turn it into an option? The one tricky part may be the ToPrimitive
constraint - though perhaps you could guard against that too.
Something like:
impl NumCast for Decimal where Decimal: TryFrom<T>,
{
fn from<T: ToPrimitive>(n: T) -> Option<Self> {
Decimal::try_from(n).ok()
}
}
The one thing that this implementation wouldn't do however is return None
if the type was not implemented for Decimal
- it'd be a compiler error instead I guess. In that case, you'd need to create a wrapper for Decimal
and implement TryFrom/NumCast
for the wrapper.
I'm a little nervous about doing explicit type dispatch - I feel that there is probably something we could do to get the compiler doing that for us instead, though I could be wrong.
I'm happy to take a look at this, perhaps later next week? That said: more than happy to review a PR if you get something working.
On second thoughts, this may be a bit trickier to implement because NumCast
doesn't expose T
at the trait level but instead at the function level... I'd need to have a deeper look into this.
It certainly makes it a better trickier, especially since we can't be sure if the input type implements any sort of helpful methods. At the moment I am working around it so no rush. Once I get a bit better at Rust lifetime I might take a look at the second option I listed.
Disclaimer I am pretty new to rust
I was wondering if support could be added for the num_traits::cast::NumCast
The trait is defined as part of this file: https://docs.rs/num-traits/latest/src/num_traits/cast.rs.html#721
I would like to implement it as I wish to use Decimal with the geo library: geo::Coord::::{x: 1., y:1.}
however it only accepts types which implement numcast.
I had a go at implementing how I think it should look , I think there are three high level options:
1) Figure out the input type and call the appropriate conversion method (requires figuring out input type) 2) Always convert input to an f64 and convert f64 to a Decimal (has some data loss when input is i128) 3) Use some magic I am unaware of
I was wondering if I could get some pointers, or help implementing this.
In regards to figuring out the type, It looks like the standard approach here will not work, due to lifetimes, but I am not very good at using them, so there may be a work around. I have included code for this approach at the bottom of this pitiful cry for help. https://doc.rust-lang.org/std/any/index.html
I found a hacky looking, but powerful(?) approach here
which I modified and included below, but the method I use to check types is maybe dangerous:
Another attempt using ID but has problems with static life time
edit: fixed copy paste error where I used u8 everywhere edit: added second approach with issues around life times