servo / euclid

Geometry primitives (basic linear algebra) for Rust
Other
462 stars 102 forks source link

Support for numeric casts through `az` crate #472

Closed haibane-tenshi closed 3 years ago

haibane-tenshi commented 3 years ago

Just as title says, is there desire to add support for numeric casts mediated by az crate?

Motivating example: interoperation with fixed crate of fixed-point arithmetic types.

This is easily the most comprehensive crate for fixed-point numbers in ecosystem and it implements most of traits provided by num-traits, so in general it works well with euclid already. However type casts inside this crate require NumCast trait which is not (and shouldn't be) implemented by fixed types.

Instead, generic casting between primitives and fixed-point is performed via traits from az crate. Unlike NumCast they avoid being pipelined through a primitive and are casted directly from one into the other.

I'm not aware of any other prominent uses of az. crates.io hints at rug, but that's about it. Actually all three are made by the same author.

If there is no objection I will prepare a PR.

nical commented 3 years ago

I'm a bit reticent to adding a dependency to euclid because a lot of euclid's users are pretty vocal about having as few dependencies as possible. The other reason is that euclid breaking changes cause a lot of downstream crates to have to update and publish a breaking release as well which we try to avoid as much as possible.

az looks small, is no_std and hasn't changed in a while so depending on it is not out of the question if the motivation is really strong. Since it is only for the casting methods and we haven't heard from other users of euclid with fixed, I would prefer to let users make helper functions outside euclid for casts with numbers that aren't covered by NumTraits.

haibane-tenshi commented 3 years ago

Yeah, understandable.

Actually, I was in a little bit of trouble when posting this: at the time there is no way to use any casting functionality (even integer to fixed of vice versa) and it required something like 10+ different casting functions to cover all types in my case. Such setup felt very cumbersome and annoying. But then after glancing through itertools docs another time I suddenly realized: you can use traits not only to generalize/abstract over APIs, but also to extend it. I guess I'll count it as learning experience :)

Now with this in mind, I would say it makes most sense to create an interoperability crate for the two which will provide traits with conversion functions instead of pushing change into euclid itself.

Anyways I'm closing the issue.