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

core/either: Remove EitherName in favor of Either #2798

Closed
wants to merge 10 commits into from

Conversation

thomaseizinger
Copy link
Contributor

@thomaseizinger thomaseizinger commented Aug 4, 2022

Description

Links to any relevant issues

#2650

Open Questions

Change checklist

  • I have performed a self-review of my own code
    - [ ] I have made corresponding changes to the documentation
    - [ ] I have added tests that prove my fix is effective or that my feature works
  • A changelog entry has been made in the appropriate crates

core/CHANGELOG.md Outdated Show resolved Hide resolved
@mxinden
Copy link
Member

mxinden commented Aug 8, 2022

This does not compile because the blanket impl for ProtocolName over anything that implements AsRef<u8> is conflicting with the implementation on Either.

I don't have a strong opinion on this. Given the complication above I am inclined to just leave it as is. Any additional benefits of this patch beyond consistency?

@thomaseizinger
Copy link
Contributor Author

This does not compile because the blanket impl for ProtocolName over anything that implements AsRef<u8> is conflicting with the implementation on Either.

I don't have a strong opinion on this. Given the complication above I am inclined to just leave it as is. Any additional benefits of this patch beyond consistency?

I'll give it a bit more thought but I don't think so.

Instead of just adding impls that we need, I can see to refactor some code to streamline, how we generate ProtocolNames.

It is a bit weird that we allow so many things to be ProtocolNames and on the trait, we define two requirements that aren't really enforced:

  • Max length of 140
  • Must start with /

Maybe we should introduce a ProtocolName newtype?

@mxinden
Copy link
Member

mxinden commented Aug 9, 2022

On the meta level, I think we could do better modelling protocol names.

Part of the problem is the conflict between multistream select and libp2p-identify on the specification level. One accepts a [u8], the other expects a String.

Maybe we should introduce a ProtocolName newtype?

Or a unit type for each protocol name, each implementing ProtocolName.

@thomaseizinger
Copy link
Contributor Author

On the meta level, I think we could do better modelling protocol names.

Part of the problem is the conflict between multistream select and libp2p-identify on the specification level. One accepts a [u8], the other expects a String.

Damn. Of course it wasn't that easy to fix :)

Maybe we should introduce a ProtocolName newtype?

Or a unit type for each protocol name, each implementing ProtocolName.

Nice idea but it won't allow us to enforce invariants, right?

@mxinden
Copy link
Member

mxinden commented Aug 10, 2022

Nice idea but it won't allow us to enforce invariants, right?

True. Would be great to enforce these at runtime. Would be wonderful to enforce these at compile time 😇

@thomaseizinger
Copy link
Contributor Author

Nice idea but it won't allow us to enforce invariants, right?

True. Would be great to enforce these at runtime. Would be wonderful to enforce these at compile time 😇

Something for a future issue? I have some ideas :)

To progress on this issue, would it be okay to transition all/most usages to std types like &static [u8] and String?

@mxinden
Copy link
Member

mxinden commented Aug 13, 2022

Nice idea but it won't allow us to enforce invariants, right?

True. Would be great to enforce these at runtime. Would be wonderful to enforce these at compile time innocent

Something for a future issue? I have some ideas :)

👍

To progress on this issue, would it be okay to transition all/most usages to std types like &static [u8] and String?

Given that Either also implements AsRef<[u8]> when the two subtypes implement AsRef<[u8]>, is the implementation of ProtocolName on Either still needed?

https://docs.rs/either/latest/either/enum.Either.html#impl-AsRef%3C%5BTarget%5D%3E

@thomaseizinger
Copy link
Contributor Author

thomaseizinger commented Aug 16, 2022

To progress on this issue, would it be okay to transition all/most usages to std types like &static [u8] and String?

Given that Either also implements AsRef<[u8]> when the two subtypes implement AsRef<[u8]>, is the implementation of ProtocolName on Either still needed?

https://docs.rs/either/latest/either/enum.Either.html#impl-AsRef%3C%5BTarget%5D%3E

(Un)fortunately yes. I remember trying this and it is not working.

I think the reason is in Rust's explicit strong-typing system. Just because something implements all super traits of a trait A does not mean it implements trait A by itself unless it is actively declared as such. In Golang, this would work :)

@mxinden
Copy link
Member

mxinden commented Aug 19, 2022

To progress on this issue, would it be okay to transition all/most usages to std types like &static [u8] and String?

I am fine with that.

@@ -6,13 +6,16 @@
- Change `StreamMuxer` interface to be entirely poll-based. All functions on `StreamMuxer` now
require a `Context` and return `Poll`. This gives callers fine-grained control over what they
would like to make progress on. See [PR 2724] and [PR 2797].
- Remove `EitherName` in favor of `Either` from the `either` crate. See [PR 2798].
- Replace blanket `ProtocolName` impl with specific ones on `&'static [u8]` and `Cow<'static, [u8]>`. See [PR 2798].
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could split this out into a different PR if you want.

Copy link
Member

Choose a reason for hiding this comment

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

I am fine with a single pull request only.

@thomaseizinger thomaseizinger marked this pull request as ready for review August 19, 2022 09:29
@thomaseizinger thomaseizinger requested review from mxinden and removed request for mxinden August 19, 2022 09:29
Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

I would actually suggest making String the default protocol representation. See #2831. What do you think @thomaseizinger?

@@ -6,13 +6,16 @@
- Change `StreamMuxer` interface to be entirely poll-based. All functions on `StreamMuxer` now
require a `Context` and return `Poll`. This gives callers fine-grained control over what they
would like to make progress on. See [PR 2724] and [PR 2797].
- Remove `EitherName` in favor of `Either` from the `either` crate. See [PR 2798].
- Replace blanket `ProtocolName` impl with specific ones on `&'static [u8]` and `Cow<'static, [u8]>`. See [PR 2798].
Copy link
Member

Choose a reason for hiding this comment

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

I am fine with a single pull request only.

B: ProtocolName,
{
fn protocol_name(&self) -> &[u8] {
::either::for_both!(self, inner => inner.protocol_name())
Copy link
Member

Choose a reason for hiding this comment

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

Neat!

@@ -6,13 +6,16 @@
- Change `StreamMuxer` interface to be entirely poll-based. All functions on `StreamMuxer` now
require a `Context` and return `Poll`. This gives callers fine-grained control over what they
would like to make progress on. See [PR 2724] and [PR 2797].
- Remove `EitherName` in favor of `Either` from the `either` crate. See [PR 2798].
- Replace blanket `ProtocolName` impl with specific ones on `&'static [u8]` and `Cow<'static, [u8]>`. See [PR 2798].
Copy link
Member

Choose a reason for hiding this comment

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

Why not implement ProtocolName for String and str?

@thomaseizinger
Copy link
Contributor Author

I would actually suggest making String the default protocol representation. See #2831. What do you think @thomaseizinger?

Yeah we can move to string! Should we do that as part of this PR or make another one? It is getting a bit OT from the original goal haha.

I am happy to fix #2831 first and then come back to this!

@mxinden
Copy link
Member

mxinden commented Aug 23, 2022

I think the following order makes most sense:

  1. misc/multistream-select: Treat protocol as String and not [u8] #2831
  2. Move ProtocolName to String
  3. Do the actual change here, namely to use Either

That said, I don't think we have to stick with that order.

@thomaseizinger
Copy link
Contributor Author

I think the following order makes most sense:

1. [misc/multistream-select: Treat protocol as `String` and not `[u8]` #2831](https://github.com/libp2p/rust-libp2p/issues/2831)

2. Move `ProtocolName` to `String`

3. Do the actual change here, namely to use `Either`

That said, I don't think we have to stick with that order.

I agree, leave it with me 😊

@thomaseizinger
Copy link
Contributor Author

Closing in favor of #2966.

@thomaseizinger thomaseizinger deleted the replace-either-name-with-either branch November 17, 2022 01:18
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.

2 participants