Manually implement PartialOrd and Ord for Denomination#3934
Manually implement PartialOrd and Ord for Denomination#3934tcharding wants to merge 2 commits intorust-bitcoin:masterfrom
PartialOrd and Ord for Denomination#3934Conversation
Currently `units::amount::Denomination` does not implement `PartialOrd` or `Ord`. This prevents any type that includes a Denomination from being used in contexts that require these traits (e.g. as key to a `BTreeMap`). This is an unnecessary restriction. We had an extensive discussion in rust-bitcoin#3865 about whether the order of enum variants with no inner data matters. This patch manually implements the traits on `Denomination`. Even though I started all this writing this patch feels a bit silly.
In preparation for release add a changelog entry, bump the version, and update the lock files. `v1.0` here we come. Before we merge this we should add: - rust-bitcoin#3934 or rust-bitcoin#3866 - rust-bitcoin#3933 - rust-bitcoin#3932 - rust-bitcoin#3929 - rust-bitcoin#3926 - rust-bitcoin#3923 - rust-bitcoin#3893 - rust-bitcoin#3866 - rust-bitcoin#3794
| // less that bitcoin because it is in a way smaller. | ||
| fn cmp(&self, other: &Self) -> Ordering { | ||
| use Denomination as D; | ||
| use cmp::Ordering::*; |
There was a problem hiding this comment.
| use cmp::Ordering::*; | |
| use cmp::Ordering::{Equal, Greater, Less}; |
This wildcard import is what is causing the CI fail
|
In 33fb56f: Can you reimagine this so that it just assigns every variant a number and then we directly compare those? I doubt there will be any measurable performance impact and it will make it much clearer that the resulting order is correct and consistent. |
|
Yeah I thought of doing that but I thought then that every reader of the enum would be like "WTF, why do these variants have this weird non-consecutive value assigned to them. Oh for |
|
Nobody is going to think "who cares about |
|
There is already a number assignment for each denomination in impl PartialEq for Denomination {
fn eq(&self, other: &Self) -> bool {
self.precision() == other.precision()
}
}
impl Ord for Denomination {
fn cmp(&self, other: &Self) -> Ordering {
other.precision().cmp(&self.precision())
}
}
impl PartialOrd for Denomination {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}The above gives |
| } | ||
|
|
||
| impl Ord for Denomination { | ||
| // This implementation is probably excessively precautions. |
There was a problem hiding this comment.
| // This implementation is probably excessively precautions. | |
| // This implementation is probably excessively precautious. |
There was a problem hiding this comment.
I think just cautious is better. "precautious" might be a word but I've never heard it before :).
There was a problem hiding this comment.
Yes indeed, that is surely what my brain was trying to tell me. I definitely didn't mean precocious.
There was a problem hiding this comment.
Sweet, this is mad, with two grammar nerds on this team I may finally up my grammar game to a level I'm happy with.
is probably excessively precautions.
How embarrassment. (Joke based on an Australian movie almost certainly lost on non-Australians.)
"precautious" might be a word but I've never heard it before :).
I'm chalking this up as a win, I had assumed the learning new words (excluding slang) was one directional from Andrew to me.
https://duckduckgo.com/?q=precautous+def&t=canonical&ia=web
I do note however that I still misspelled it in the search.
| impl Ord for Denomination { | ||
| // This implementation is probably excessively precautions. | ||
| // | ||
| // A user may one day compare `Denomination` types and assume the 'natural' order satoshi is |
There was a problem hiding this comment.
| // A user may one day compare `Denomination` types and assume the 'natural' order satoshi is | |
| // A user may one day compare `Denomination` types and assume the 'natural' order where smaller denominations like satoshi are considered 'less than' larger ones like bitcoin. |
We don't... in this case we want |
|
Oh, crap. I see the problem. Ideally we would have I know this will be unpopular but I suspect having I suggest dropping the impls entirely. We can still have methods |
|
Honestly I'd rather drop |
|
Are both these units used in practice? |
|
"bit" feels more like slang while "microbitcoin" feels "formal" to me. But that might be alright if people prefer bit. Strictly speaking, we don't need them both since people can write their own enum and manually implement displaying. I was also thinking of having |
Yes, except that this was a bug-ridden slog for us and nobody else wants to redo that work.
|
|
With @Kixunil's point that we can add trait impls after 1.0 I'm going to chalk this up to not important enough to think about right now and leave the |
|
Great point. Yeah, let's not add trait impls that we don't agree on unless there's an obvious or known usecase. |
|
And amusingly (since we are considering removing it) folk can just use |
|
Should we remove |
Yes, if we are willing to put |
In my view it's obvious that they're not equal in the sense of |
Oh I mispoke. I was thinking we didn't need the |
Yes, the trouble is someone might forget that some variants have duplicated magnitude and they'd assume inequality implies different magnitude. That being said, I'm not sure where people would deal with that if they can just use our parsing/displaying code. |
|
Yeah, behind all this discussion is an open question about what anybody is actually doing directly manipulating the |
We are trying a new strategy to get to 1.0 more quickly - remove `amount` and `fee` and release everything else. In preparation for release add a changelog entry, bump the version, and update the lock files. `v1.0` here we come. Before we merge this we should add: - rust-bitcoin#3934 or rust-bitcoin#3866 - rust-bitcoin#3933 - rust-bitcoin#3932 - rust-bitcoin#3929 - rust-bitcoin#3926 - rust-bitcoin#3923 - rust-bitcoin#3893 - rust-bitcoin#3866 - rust-bitcoin#3794
We are trying a new strategy to get to 1.0 more quickly - remove `amount` and `fee` and release everything else. In preparation for release add a changelog entry, bump the version, and update the lock files. `v1.0` here we come. Before we merge this we should add: - rust-bitcoin#3934 or rust-bitcoin#3866 - rust-bitcoin#3933 - rust-bitcoin#3932 - rust-bitcoin#3929 - rust-bitcoin#3926 - rust-bitcoin#3923 - rust-bitcoin#3893 - rust-bitcoin#3866 - rust-bitcoin#3794
We are trying a new strategy to get to 1.0 more quickly - remove `amount` and `fee` and release everything else. In preparation for release add a changelog entry, bump the version, and update the lock files. `v1.0` here we come. Before we merge this we should add: - rust-bitcoin#3934 or rust-bitcoin#3866 - rust-bitcoin#3933 - rust-bitcoin#3932 - rust-bitcoin#3929 - rust-bitcoin#3926 - rust-bitcoin#3923 - rust-bitcoin#3893 - rust-bitcoin#3866 - rust-bitcoin#3794
We are trying a new strategy to get to 1.0 more quickly - remove `amount` and `fee` and release everything else. In preparation for release add a changelog entry, bump the version, and update the lock files. `v1.0` here we come. Before we merge this we should add: - rust-bitcoin#3934 or rust-bitcoin#3866 - rust-bitcoin#3933 - rust-bitcoin#3932 - rust-bitcoin#3929 - rust-bitcoin#3926 - rust-bitcoin#3923 - rust-bitcoin#3893 - rust-bitcoin#3866 - rust-bitcoin#3794
We are trying a new strategy to get to 1.0 more quickly - remove `amount` and `fee` and release everything else. In preparation for release add a changelog entry, bump the version, and update the lock files. `v1.0` here we come. Before we merge this we should add: - rust-bitcoin#3934 or rust-bitcoin#3866 - rust-bitcoin#3933 - rust-bitcoin#3932 - rust-bitcoin#3929 - rust-bitcoin#3926 - rust-bitcoin#3923 - rust-bitcoin#3893 - rust-bitcoin#3866 - rust-bitcoin#3794
Currently
units::amount::Denominationdoes not implementPartialOrdorOrd. This prevents any type that includes a Denomination from being used in contexts that require these traits (e.g. as key to aBTreeMap). This is an unnecessary restriction.We had an extensive discussion in #3865 about whether the order of enum variants with no inner data matters.
This patch manually implements the traits on
Denomination. Even though I started all this writing this patch feels a bit silly.This is an alternative to #3866. I personally think we should do 3866 and not this one.