-
Notifications
You must be signed in to change notification settings - Fork 633
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
Improve units #2370
Improve units #2370
Conversation
Pull Request Test Coverage Report for Build 7656656308
💛 - Coveralls |
Oh, found it's because I was also working on #2266 and interrupted that work for some reason. |
9a30b76
to
1146f19
Compare
1146f19
to
c1558ea
Compare
match self { | ||
ParseError::Amount(error) => write_err!(f, "invalid amount"; error), | ||
ParseError::Denomination(error) => write_err!(f, "invalid denomination"; error), | ||
} |
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.
Any reason why this uses different style to other code we have e.g.,
use ParseError::*;
match *self {
Amount(error) => write_err!(f, "invalid amount"; error),
Denomination(error) => write_err!(f, "invalid denomination"; error),
}
In hindsight I kind of wish we used use Self::*
instead of naming the type to make maintenance slightly cheaper.
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.
Note please this is not a my style vs your style thing, I think the style we use is clearer. (I intentionally did not change error
to e
.)
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.
Various reasons:
- I actually wrote this a long time ago
- I didn't notice we've adopted this as official style
- I don't mind typing the enum name so I wasn't trying to get rid of it
I think Swift got this one better having .Foo
meaning "variant Foo of self", I wish this was available in Rust somehow!
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.
In hindsight I kind of wish we used
use Self::*
I checked and this doesn't work, that is a surprise to me.
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.
Yeah, I hit it recently in another project. Was surprised as well.
units/src/amount.rs
Outdated
match *self { | ||
Negative | TooBig | TooPrecise | InvalidFormat | InputTooLarge | ||
match self { | ||
TooPrecise | InvalidFormat | InputTooLarge | ||
| InvalidCharacter(_) => None, | ||
InvalidDenomination(ref e) => Some(e), | ||
OutOfRange(error) => Some(error), |
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.
@apoelstra do you want to please weigh in with the argument you made to me a year or so ago about why you think using *self
and ref
is better. Save me butchering your argument.
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 personally consider ref
to be mostly old style except for rare borrow checker limitations. Just using &self
and not sprinkling ref
everywhere is less annoying. Also this is used in most codebases I've seen so I expect newbies to be more familiar with it.
IIUC the argument for ref
is that it's more accurate description of what the types are. It's not wrong but I think the fact that the matching on references is obvious (which was also the reason it got implemented; yes, I was around before it was available) makes it non-issue.
Oh, and since I experienced being forced to write ref
: it was horrible. The single most annoying thing in Rust at the time. Not only forgetting about it and doing pointless edits but also harder to refactor and noisy.
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.
@apoelstra do you want to please weigh in with the argument you made to me a year or so ago about why you think using
*self
andref
is better. Save me butchering your argument.
I prefer my code's semantics to be explicit. It saves nearly zero time when programming for the compiler to implicitly screw around with levels of dereferencing and literally zero time when reviewing (it may actually increase review time because it eliminates visual hints as to the types of various objects).
But since the compiler refuses to give you any help in noticing when it's inserting implicit ref
s and &
s and *
s, I've given up on trying to enforce this by hand. There's also no clippy lint for it.
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.
With that said, and since we (I) have, over the last year, nearly completely used the *self
and ref
style codebase wide can we agree to keep it @Kixunil ?
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'd rather not bother with it in general but since this is top commit and it makes diff smaller I changed it.
#[cfg(feature = "std")] | ||
impl std::error::Error for OutOfRangeError {} |
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.
@Kixunil I put literally hours into repeatedly opening every file in the codebase that contains error code to get all the error code exactly the same so that it becomes boilerplate and devs don't have to look at it. This {}
is different (in style not functionality). Can we please have a uniform policy? I don't care which it is but if you want to do this can you change every instance of struct errors (or create an issue that describes that and I'll do it).
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.
Also we can then reasonably expect newer devs to use the correct style because its uniform.
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 honestly don't believe it matters and for no-item traits I personally prefer using {}
because it's shorter and no less clear than whatever else we could have.
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.
Ok, I'm going to mentally move to using {}
for structs, but keep explicit match for enums. Codebase wide will be basically an all red diff that shouldn't merge conflict too much so I'll do that at some stage when I'm too tired to do anything else.
Previousle we copied `unsigned_abs` method from `core` because it was unstable in older MSRV. Our current MSRV allows using the method directly so this removes our old one and uses the one from standard library instead.
The `from_str_in` methods on amounts returned `ParseAmountError` which contained `InvalidDenomination` among its variants. This one was never returned because the method doesn't parse denomination. This change separates the error out. Closes rust-bitcoin#2265
This better conveys the intention that we're checking the lower bound.
The error returned when parsing amount had a `Negative` variant which was weird/unreachable when parsing `SignedAmount`. Also weirdly, parsing would return `TooBig` when the amount was negative - too low. To resolve this we merge them into one `OutOfRange` variant that nuges the consumers to make principled decisions and print error messages as amounts being more than or less than a specific value which is easier to understand for the users. Notably, the API still allows getting information about which type was parsed and which bound was crossed but in a less obvious way. This is OK since users who have a very good reason can use this information but most won't. Closes rust-bitcoin#2266
c1558ea
to
7bf4783
Compare
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.
ACK 7bf4783
@@ -1324,6 +1419,30 @@ pub mod serde { | |||
fn ser_btc_opt<S: Serializer>(self, s: S) -> Result<S::Ok, S::Error>; | |||
} | |||
|
|||
struct DisplayFullError(ParseAmountError); |
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.
In 7bf4783:
I guess this is a question for a followup PR, but do we want to make this a generic thing and use it in all of our serde impls?
Relatedly, could we replace our write_err!
macro with a wrapper type like this that simply has different Display
impls with std
and non-std
?
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.
do we want to make this a generic thing and use it in all of our serde impls?
Yes, I think so. Honestly this is the kind of thing that really should've been in core
.
Relatedly, could we replace our
write_err!
macro with a wrapper type like this that simply has differentDisplay
impls withstd
and non-std
?
I think that would just create more code, not less because we'd still need format_args!
to supply the arguments.
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.
ACK 7bf4783
@Kixunil your |
Oh, it does show up, I just needed to fetch. But since it's a straggling merge commit and neither Tobin nor I ACKed it, can you remove it? |
fb5139b
to
7bf4783
Compare
What the hell? I don't see it, I tried to simply force push and it looks like it did something. Is it OK now? If not, please provide the hash of the merge commit. |
Fixed. But for your curiosity the commit ID was fb5139b It has @tcharding as the author -- I suspect he pushed it by accident. |
I've done stupider things before :) Was definitely not intentional. I'm surprised I have write perms to arbitrary branches on other peoples forks. |
I'll re-ack since its the same commit hash now as last time. |
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.
ACK 7bf4783
As a maintainer, you do by default. (And I never disallow it.) |
It's only branches that have PRs associated with them. Which I agree feels surprising, but it's the only way that maintainers can edit PRs. |
Oh TIL, I didn't know we could edit PRs. |
Closes #2265
Closes #2266
Disclaimer: I did this in December and don't remember why I haven't pushed it. Maybe because it's somehow broken but I don't see how so please review a bit more carefully just in case.