-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement ToPrimitive
and NumCast
traits
#58
base: main
Are you sure you want to change the base?
Conversation
7eed210
to
bb2bfdf
Compare
Signed-off-by: Nico Burns <[email protected]>
Signed-off-by: Nico Burns <[email protected]>
Signed-off-by: Nico Burns <[email protected]>
bb2bfdf
to
aa000a2
Compare
|
||
#[inline] | ||
fn to_i8(&self) -> Option<i8> { | ||
None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not much familiar with this, but shouldn't it be self.to_px().to_i8()
or such?
Analogous for all returning None
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None
basically means "we don't support this cast", so it seemed like a conservative default for:
- Unsigned integers. As casting an
Au
to an unsigned integer is likely a logic error. - Signed integers that have a size smaller than the range that
Au
supports. Again, we probably don't want to do this?
Taking a look at the implementations that num_traits
provides for analogous stdlib types, it looks like it does runtime checks to see whether the value is in a range that can be converted.
So we could do that if you think that's better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if it may be a weird conversion, if the value can be represented, it seems to make more sense to try to cast. But I will defer to Martin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting! I don't have a strong opinion about whether or not we should be conservative or liberal in what kind of casts we allow. Is it possible to make the cast conservative now and then make it more liberal in the future though, by no longer returning None
? If that's the case maybe it's better to not do something that is hard to undo and stay conservative for the time being.
src/app_unit.rs
Outdated
#[inline] | ||
fn to_u8(&self) -> Option<u8> { | ||
None | ||
} | ||
|
||
#[inline] | ||
fn to_u16(&self) -> Option<u16> { | ||
None | ||
} | ||
|
||
#[inline] | ||
fn to_u32(&self) -> Option<u32> { | ||
None | ||
} | ||
|
||
#[inline] | ||
fn to_u64(&self) -> Option<u64> { | ||
None | ||
} | ||
|
||
#[inline] | ||
fn to_u128(&self) -> Option<u128> { | ||
None | ||
} | ||
|
||
#[inline] | ||
fn to_usize(&self) -> Option<usize> { | ||
None | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like you could simply implement to_u64
and then the other implementations have defaults?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I could do. Did it this way to be explicit. But I can go down that route if you prefer?
@@ -453,3 +539,27 @@ fn serialize() { | |||
let serialized = ron::to_string(&Au(42)).unwrap(); | |||
assert_eq!(ron::from_str(&serialized), Ok(Au(42))); | |||
} | |||
|
|||
#[cfg(feature = "num_traits")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to expand the tests a bit. There should probably be tests for the unsupported casts for instance.
|
||
#[inline] | ||
fn to_i64(&self) -> Option<i64> { | ||
Some(self.to_px() as i64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can just implement to to_i64() and the others have default implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth special casing i32
, because that's what we actually have? I guess casting to i64 and back again is probably pretty cheap / likely to be inlined. But still...
src/app_unit.rs
Outdated
@@ -289,6 +289,92 @@ impl Au { | |||
} | |||
} | |||
|
|||
#[cfg(feature = "num_traits")] | |||
impl num_traits::ToPrimitive for Au { | |||
// Float conversions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these comments aren't adding too much. It's pretty obvious what the conversion is by looking at the type signature.
Yes. I believe so. And this was part of my reasoning for doing it like this. The effect of doing that is that initially (when |
I somewhat agree that this could be confusing. I think this is Euclid's fault for having "cast" as it's name/mechanism for doing this. We could potentially add a different method/mechanism. Taffy's "geom" containers have Although IMO |
Signed-off-by: Nico Burns <[email protected]>
This hooks
Au
intoeuclid
s type casting mechanism and will allow us to convert code like:into