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

Common API modules #33

Merged
merged 4 commits into from
May 26, 2020
Merged

Common API modules #33

merged 4 commits into from
May 26, 2020

Conversation

dr-orlovsky
Copy link
Member

No description provided.

@dr-orlovsky dr-orlovsky added the enhancement Improvement to existing functionality or refactoring label Apr 11, 2020
@dr-orlovsky dr-orlovsky self-assigned this Apr 11, 2020
@dr-orlovsky dr-orlovsky added this to In progress in Client-side-validation via automation Apr 11, 2020
Copy link
Member

@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.

I think we should take some time to think about the self issue. Looking at the code, it seems that my assumption was correct and we should use &self instead.

Sorry about the comments outside of the review, I was confused by several notifications due to you mentioning me in each commit, so missed that there's PR for the whole thing.

src/api/encode.rs Show resolved Hide resolved
src/api/encode.rs Show resolved Hide resolved
fn into_message(self) -> Message {
Message::from(consensus_serialize(&self.into_inner()))
}
fn try_from_message(message: Message) -> Result<Self, Self::Error> {
Copy link
Member

Choose a reason for hiding this comment

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

Forgot to add in the other comment that &Message might be more useful as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

If we can use to_ instead of into_ for passing references; is there some convention for from_s passing references and not consuming the argument?

Copy link
Member Author

Choose a reason for hiding this comment

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

Also, another important point: we use impl From to actually serialize many data structures into Message, and this is just a helper method. If we will pass a reference here, we will have to consume the argument still with the underlying From, so I don't understand the reason of changing self->&self in into/from_message functions here...

Copy link
Member

Choose a reason for hiding this comment

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

I'm not aware of any convention for from. I've seen from_* function take values and references. Just to_*/into_* are differentiated. I suppose because Foo::from_something(&bar) immediately tells the reader what's going on, where bar.to_foo() wouldn't if not for the convention.

From could be implemented for references too. Implementing it for references only might be even better as it might help avoiding accidental clones.

Copy link
Member Author

Choose a reason for hiding this comment

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

Tried to move from selfs to &self, however got plenty of problems throughout the code; in particular many parts depend on further into_/from_ consuming selfs, so I will keep it this way for now and at some point later, when I will have more time, revisit this and refactor the most of codebase


#[derive(Debug, Display)]
#[display_from(Debug)]
pub enum Error {
Copy link
Member

Choose a reason for hiding this comment

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

I expect the API to be in flux for some time, so making the enum private and bundling it into a newtype struct might improve forward compatibility for the time being.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think just adding #[non_exhaustive] (which I simply forgot here) will do the job?

Copy link
Member

Choose a reason for hiding this comment

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

An advantage of struct over non_exhaustive is that it can change its internal representation without breaking backwards compatibility. This may be important in the early stage. Once possible errors are well-understood, making the enum public (possibly with non_exhaustive) will be fine.

WIP on ZMQ APIs: fixed marker traits

Refactoring API after @Kixunil suggestion: Step 1

Refactoring API after @Kixunil suggestion: Step 2

Refactoring API after @Kixunil suggestion: Step 3

Refactoring API after @Kixunil suggestion: Step 4

Refactoring API after @Kixunil suggestion: Step 5

Refactoring API after @Kixunil suggestion: Step 6

Refactoring API after @Kixunil suggestion: Step 7

Refactoring API after @Kixunil suggestion: removing markers for bp and rgb

Refactoring API after @Kixunil suggestion: Step 8
@dr-orlovsky dr-orlovsky force-pushed the feat-api branch 2 times, most recently from 64031fe to c800df4 Compare April 19, 2020 15:41
Copy link
Member

@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.

I think the extra bounds should really be removed. I could nit pick some more things, but I don't think it's needed at this stage of the project. :)

pub enum Native { }

/// Strategy used for custom implementation of data structure encoding
pub trait Other { type Strategy: Clone + fmt::Debug + fmt::Display; }
Copy link
Member

Choose a reason for hiding this comment

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

The Clone + fmt::Debug + fmt::Display bounds aren't necessary because Strategy is only type-level marker and in the case of empty enums, it can't be even instantiated.

#[cfg(feature="use-rgb")]
impl<T> MessageEncode for strategy::Holder<T, strategy::RGBStrategy>
where T: csv::serialize::Network {
type Error = Error;
Copy link
Member

Choose a reason for hiding this comment

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

The general convention is to not have fixed Error type everywhere, but use the original error type. type Error; would be unnecessary otherwise, since the trait could require conversion to some specific type. std::io::{Read, Write} uses fixed errors (std::io::Error) and from my experience, it's quite unfortunate in these cases:

  • Application needs to do something smart around errors (real life example: translate messages)
  • no_std is out of question
  • Inconvenient when transferring more information is needed (e.g. both OS code and file name)

So my recommendation is to prefer the original error and let the client of the library unify it if needed.

@UkolovaOlga UkolovaOlga mentioned this pull request Apr 22, 2020
34 tasks
@dr-orlovsky dr-orlovsky moved this from Agenda to Under review in Development Calls Agenda May 8, 2020
@dr-orlovsky dr-orlovsky moved this from Under review to Accepted in Development Calls Agenda May 8, 2020
@dr-orlovsky dr-orlovsky merged commit eff4347 into master May 26, 2020
Client-side-validation automation moved this from In progress to Done May 26, 2020
Development Calls Agenda automation moved this from Accepted to Implemented / Done May 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement to existing functionality or refactoring
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

2 participants