Skip to content
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 Debug for generic Address<V: NetworkValidation> #1578

Merged
merged 1 commit into from Jan 23, 2023

Conversation

jirijakes
Copy link
Contributor

@jirijakes jirijakes commented Jan 22, 2023

Previously Debug was implemented for both Address<NetworkChecked> and Address<NetworkUnchecked>, but not for cases when the NetworkValidation parameter was generic. This change adds this ability. Based on Kixunil's tip.

With previous implementation, the test_address_debug() resulted in error:

image

The added Debug on NetworkChecked and NetworkUnchecked are required by compiler.


While dealing with derives and impls, I also attempted to turn all the derives on Address into manual impls (see Kixunil's suggestion in #1489 (comment)). The motivation behind this was the possibility to remove derives on NetworkChecked and NetworkUnchecked, too. However, even with manual impls, all the traits on NetworkChecked and NetworkUnchecked were still required by compiler in this sort of situations (see also the rest of the same discussion linked above). I do not fully understand why, perhaps limitation of this way of sealing traits?

It can be demonstrated by removing Debug derivation on NetworkUnchecked and NetworkChecked in this PR and running test_address_debug().

Therefore, if we want to allow users of the library to define types generic in NetworkValidation and at the same time derive impls, it seems to me that NetworkChecked and NetworkUnchecked will have to have the same set of impls as Address itself.

Previously `Debug` was implemented for both `Address<NetworkChecked>`
and `Address<NetworkUnchecked>`, but not for cases when the
`NetworkValidation` parameter was generic. This change adds this
ability.
@jirijakes
Copy link
Contributor Author

Unrelated but it's getting difficult to move around address.rs (1700 lines). Would someone object if it's split into multiple files? Perhaps address/mod.rs, address/address.rs, address/payload.rs and address/tests.rs?

@Kixunil
Copy link
Collaborator

Kixunil commented Jan 22, 2023

However, even with manual impls, all the traits on NetworkChecked and NetworkUnchecked were still required by compiler in this sort of situations (see also the rest of the same discussion linked above). I do not fully understand why

I'm not sure if I understand what you're saying correctly, but I think you're experiencing an annoying "poisoning" of downstream generic types which are also forced to do manual impls. I didn't fully realize this when suggesting manual impls. I suspect that just keeping the derive is lesser evil but it depends on how many people and how often will they write generic structs.

I suggest we remove it anyway for now and re-add it if many people complain. I will take a look at it myself since I've done something similar in another project.

Copy link
Collaborator

@Kixunil Kixunil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ebfbe74

Nice PR, thanks!

@jirijakes
Copy link
Contributor Author

I think you're experiencing an annoying "poisoning" of downstream generic types which are also forced to do manual impls.

Oh, you're right! I didn't think of it before. Yes, manual impl on the generic struct will work.

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ebfbe74

@apoelstra
Copy link
Member

Unrelated but it's getting difficult to move around address.rs (1700 lines). Would someone object if it's split into multiple files? Perhaps address/mod.rs, address/address.rs, address/payload.rs and address/tests.rs?

No objection from me. Though we probably want to discuss, in general, the idea of moving unit tests into their own files, because I think it's a common pattern for 50%+ of source files to be unit tests, which can make it hard to navigate.

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK ebfbe74

@apoelstra apoelstra merged commit 4b02d90 into rust-bitcoin:master Jan 23, 2023
@tcharding
Copy link
Member

I don't think having tests in a separate file is helpful for navigating files, the tests are at the bottom of the file anyways. I'd prefer not to have a proliferation of foo_test.rs files.

FTR I navigate files almost entirely by jumping up and down so file layout is always on my mind.

One thing that could be done, is putting important stuff first, as opposed to putting stuff before its used i.e., error types and code can be at the bottom instead of at the top where it is in many files - I've made an effort to start this already with no push back so far :) Also, private methods after they are called.

@jirijakes jirijakes deleted the address_gen_debug branch January 24, 2023 02:14
@Kixunil
Copy link
Collaborator

Kixunil commented Jan 27, 2023

Yeah, tests aren't that bad. The Rust std does put them in subdirectories though.

Errors could also go to a separate module.

@tcharding
Copy link
Member

Yeah, tests aren't that bad. The Rust std does put them in subdirectories though.

Well I've exposed my lack of reading std code here then haven't I. If std does this then I rescind my comment. Does that mean we should but benches in a separate module as well? I see std uses the "new" module naming and has many directories that hold just the test.rs file, I guess we should have bench.rs along side all those.

@tcharding
Copy link
Member

How about we do this restructure during the feature freeze right before next release?

@Kixunil
Copy link
Collaborator

Kixunil commented Jan 27, 2023

I'm not trying to imply we have to do what std does, just pointing out that some other, presumably experienced :), Rust devs found that style useful, so might be worth considering. I don't have strong preference right now. Doing it during feature freeze sounds good.

@tcharding
Copy link
Member

Cool, I willing to give it a try, time will tell if we like it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants