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

Refactor #[derive(Filter)] for better parsing and readability #2437

Closed
ilchu opened this issue Jul 6, 2022 · 3 comments
Closed

Refactor #[derive(Filter)] for better parsing and readability #2437

ilchu opened this issue Jul 6, 2022 · 3 comments
Assignees
Labels
iroha2-dev The re-implementation of a BFT hyperledger in RUST

Comments

@ilchu
Copy link
Contributor

ilchu commented Jul 6, 2022

As mentioned in #2431 PR discussion, there are still a few improvements that could be made to the Filter derive macro in data_model/derive:

  • More modular functions
  • Custom structs with Parse to make invalid enums fail more predictably
  • Better naming conventions
  • Less nested mapping
ilchu added a commit to ilchu/iroha that referenced this issue Jul 13, 2022
…os for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>
ilchu added a commit to ilchu/iroha that referenced this issue Jul 13, 2022
…os for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>
ilchu added a commit to ilchu/iroha that referenced this issue Jul 13, 2022
…os for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>
ilchu added a commit to ilchu/iroha that referenced this issue Jul 13, 2022
…os for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>
ilchu added a commit to ilchu/iroha that referenced this issue Jul 20, 2022
…os for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>
ilchu added a commit to ilchu/iroha that referenced this issue Jul 20, 2022
…os for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>
ilchu added a commit to ilchu/iroha that referenced this issue Jul 22, 2022
…os for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>
ilchu added a commit to ilchu/iroha that referenced this issue Jul 25, 2022
…os for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>
ilchu added a commit that referenced this issue Jul 25, 2022
…#2476)

* [feature] #1988, #2437: Derive macros for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `OrdEqHash` into `Identifiable`

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `IdOrdEqHash` and `Filter` into separate files

Signed-off-by: Ilia Churin <[email protected]>
mversic pushed a commit to mversic/iroha that referenced this issue Sep 6, 2022
…os for Identifiable, Eq, Hash, Ord (hyperledger-iroha#2476)

* [feature] hyperledger-iroha#1988, hyperledger-iroha#2437: Derive macros for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `OrdEqHash` into `Identifiable`

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `IdOrdEqHash` and `Filter` into separate files

Signed-off-by: Ilia Churin <[email protected]>
mversic pushed a commit to mversic/iroha that referenced this issue Sep 6, 2022
…os for Identifiable, Eq, Hash, Ord (hyperledger-iroha#2476)

* [feature] hyperledger-iroha#1988, hyperledger-iroha#2437: Derive macros for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `OrdEqHash` into `Identifiable`

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `IdOrdEqHash` and `Filter` into separate files

Signed-off-by: Ilia Churin <[email protected]>
mversic pushed a commit to mversic/iroha that referenced this issue Sep 6, 2022
…os for Identifiable, Eq, Hash, Ord (hyperledger-iroha#2476)

* [feature] hyperledger-iroha#1988, hyperledger-iroha#2437: Derive macros for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `OrdEqHash` into `Identifiable`

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `IdOrdEqHash` and `Filter` into separate files

Signed-off-by: Ilia Churin <[email protected]>
mversic pushed a commit to mversic/iroha that referenced this issue Sep 7, 2022
…os for Identifiable, Eq, Hash, Ord (hyperledger-iroha#2476)

* [feature] hyperledger-iroha#1988, hyperledger-iroha#2437: Derive macros for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `OrdEqHash` into `Identifiable`

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `IdOrdEqHash` and `Filter` into separate files

Signed-off-by: Ilia Churin <[email protected]>
mversic pushed a commit to mversic/iroha that referenced this issue Sep 8, 2022
…os for Identifiable, Eq, Hash, Ord (hyperledger-iroha#2476)

* [feature] hyperledger-iroha#1988, hyperledger-iroha#2437: Derive macros for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `OrdEqHash` into `Identifiable`

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `IdOrdEqHash` and `Filter` into separate files

Signed-off-by: Ilia Churin <[email protected]>
mversic pushed a commit to mversic/iroha that referenced this issue Sep 9, 2022
…os for Identifiable, Eq, Hash, Ord (hyperledger-iroha#2476)

* [feature] hyperledger-iroha#1988, hyperledger-iroha#2437: Derive macros for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `OrdEqHash` into `Identifiable`

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `IdOrdEqHash` and `Filter` into separate files

Signed-off-by: Ilia Churin <[email protected]>
mversic pushed a commit to mversic/iroha that referenced this issue Sep 9, 2022
…os for Identifiable, Eq, Hash, Ord (hyperledger-iroha#2476)

* [feature] hyperledger-iroha#1988, hyperledger-iroha#2437: Derive macros for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `OrdEqHash` into `Identifiable`

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `IdOrdEqHash` and `Filter` into separate files

Signed-off-by: Ilia Churin <[email protected]>
mversic pushed a commit to mversic/iroha that referenced this issue Sep 9, 2022
…os for Identifiable, Eq, Hash, Ord (hyperledger-iroha#2476)

* [feature] hyperledger-iroha#1988, hyperledger-iroha#2437: Derive macros for Identifiable, Eq, Hash, Ord

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `OrdEqHash` into `Identifiable`

Signed-off-by: Ilia Churin <[email protected]>

* Refactor `IdOrdEqHash` and `Filter` into separate files

Signed-off-by: Ilia Churin <[email protected]>
@appetrosyan appetrosyan added the iroha2-dev The re-implementation of a BFT hyperledger in RUST label Oct 12, 2022
@appetrosyan appetrosyan moved this to Todo in Iroha 2.0 Dec 12, 2022
@0x009922
Copy link
Contributor

0x009922 commented Jul 3, 2023

I made some research about the Filter macro. I am confused by its documentation.

There is an example of how macro expands from this:

use iroha_data_model_derive::{Filter, IdEqOrdHash};
use iroha_data_model::prelude::{HasOrigin, Identifiable};
use serde::{Deserialize, Serialize};


#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Filter, Deserialize, Serialize)]
pub enum LayerEvent {
    SubLayer(SubLayerEvent),
    Created(LayerId),
}

pub enum SubLayerEvent {
    Created(SubLayerId),
}

pub struct LayerId {
    name: u32,
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SubLayerId {
    name: u32,
    parent_id: LayerId,
}

#[derive(Debug, Clone, IdEqOrdHash)]
pub struct Layer {
    id: <Self as Identifiable>::Id,
}

#[derive(Debug, Clone, IdEqOrdHash)]
pub struct SubLayer {
    id: <Self as Identifiable>::Id,
}

impl HasOrigin for LayerEvent {
    type Origin = Layer;

    fn origin_id(&self) -> &<Layer as Identifiable>::Id {
        match self {
            Self::SubLayer(sub_layer) => &sub_layer.origin_id().parent_id,
            Self::Created(id) => id,
        }
    }
}

impl HasOrigin for SubLayerEvent {
    type Origin = SubLayer;

    fn origin_id(&self) -> &<SubLayer as Identifiable>::Id {
        match self {
            Self::Created(id) => id,
        }
    }
}

To this:

#[doc = " Filter for LayerEvent entity"]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, derive_more::Constructor, Decode, Encode, Deserialize, Serialize, IntoSchema)]
pub struct LayerFilter {
    origin_filter:
        crate::prelude::FilterOpt<crate::prelude::OriginFilter<crate::prelude::LayerEvent>>,
    event_filter: crate::prelude::FilterOpt<LayerEventFilter>,
}
impl LayerFilter {
    #[doc = " Construct new LayerFilter"]
    pub const fn new(
        origin_filter: crate::prelude::FilterOpt<
            crate::prelude::OriginFilter<crate::prelude::LayerEvent>,
        >,
        event_filter: crate::prelude::FilterOpt<LayerEventFilter>,
    ) -> Self {
        Self {
            origin_filter,
            event_filter,
        }
    }
    #[doc = r" Get `origin_filter`"]
    #[inline]
    pub const fn origin_filter(
        &self,
    ) -> &crate::prelude::FilterOpt<crate::prelude::OriginFilter<crate::prelude::LayerEvent>> {
        &self.origin_filter
    }
    #[doc = r" Get `event_filter`"]
    #[inline]
    pub const fn event_filter(&self) -> &crate::prelude::FilterOpt<LayerEventFilter> {
        &self.event_filter
    }
}
impl crate::prelude::Filter for LayerFilter {
    type EventType = crate::prelude::LayerEvent;
    fn matches(&self, event: &Self::EventType) -> bool {
        self.origin_filter.matches(event) && self.event_filter.matches(event)
    }
}
#[doc = " Event filter for LayerEvent entity"]
#[allow(clippy::enum_variant_names, missing_docs)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Decode, Encode, Deserialize, Serialize, IntoSchema)]
pub enum LayerEventFilter {
    ByCreated,
    BySubLayer(crate::prelude::FilterOpt<SubLayerFilter>),
}
impl crate::prelude::Filter for LayerEventFilter {
    type EventType = crate::prelude::LayerEvent;
    fn matches(&self, event: &crate::prelude::LayerEvent) -> bool {
        match (self, event) {
            (Self::ByCreated, crate::prelude::LayerEvent::Created(_)) => true,
            (Self::BySubLayer(filter_opt), crate::prelude::LayerEvent::SubLayer(event)) => {
                filter_opt.matches(event)
            }
            _ => false,
        }
    }
}

However, when I expand it with cargo expand, it seems that there is no any output from Filter macro. You can see a repro in my fork.

@ilchu, could you comment on it?

Also, I think that the example is cumbersome and docstring should contain something shorter and more expressive.

@0x009922
Copy link
Contributor

0x009922 commented Jul 3, 2023

Several ideas I have to improve the macro:

  • Due to name scoping, the macro currently properly expands only from within the iroha_data_model crate as it relies on a few of crate::prelude imports.

    It relies not only on crate::prelude. Here is the complete set of imports required to use Filter properly:

    use iroha_data_model::prelude;
    use iroha_data_model_derive::Filter;
    use iroha_schema::IntoSchema;
    use parity_scale_codec::{Decode, Encode};
    use serde::{Deserialize, Serialize};
    
    #[derive(Filter)]
    enum AccountEvent {
        Registered(u32),
    }
    
    fn main() {}

    It is a self-contained integration test.

    In order to not rely on such a convention, I propose to declare a submodule for macro with essential imports, like iroha_data_model::derive::util:

    pub use parity_scale_codec::{Decode, Encode};
    // etc

    So that the macro could rely on imports from that module instead of assuming that something is imported in the scope.

  • This macro also depends on the naming conventions adopted so far, such as that
    Event enums always have tuple variants with either some sort of Id or another Event inside of them, as well as that all Event inner fields precede Id fields in the enum definition.

    As far as I can see, the macro doesn't emit any errors if this convention is violated.

Apart from this, I don't see what else to refactor in the impl_filter proc macro. Its code is quite straightforward and doesn't contain much logic. Maybe it makes sense to go away from manual impl Parse and rely on darling though, which is relevant to other macros in iroha_data_model_derive as well.

@DCNick3 DCNick3 self-assigned this Sep 12, 2023
DCNick3 added a commit to DCNick3/iroha that referenced this issue Sep 18, 2023
….filter_maps & get rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in hyperledger-iroha#2437

Signed-off-by: Nikita Strygin <[email protected]>
DCNick3 added a commit to DCNick3/iroha that referenced this issue Sep 18, 2023
….filter_maps & get rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in hyperledger-iroha#2437

Signed-off-by: Nikita Strygin <[email protected]>
DCNick3 added a commit to DCNick3/iroha that referenced this issue Sep 19, 2023
….filter_maps & get rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in hyperledger-iroha#2437

Signed-off-by: Nikita Strygin <[email protected]>
DCNick3 added a commit to DCNick3/iroha that referenced this issue Sep 19, 2023
….filter_maps & get rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in hyperledger-iroha#2437

Signed-off-by: Nikita Strygin <[email protected]>
DCNick3 added a commit to DCNick3/iroha that referenced this issue Sep 20, 2023
….filter_maps & get rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in hyperledger-iroha#2437

Signed-off-by: Nikita Strygin <[email protected]>
DCNick3 added a commit to DCNick3/iroha that referenced this issue Sep 25, 2023
….filter_maps & get rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in hyperledger-iroha#2437

Signed-off-by: Nikita Strygin <[email protected]>
mversic pushed a commit to DCNick3/iroha that referenced this issue Sep 26, 2023
….filter_maps & get rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in hyperledger-iroha#2437

Signed-off-by: Nikita Strygin <[email protected]>
DCNick3 added a commit that referenced this issue Sep 26, 2023
…t rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in #2437

Signed-off-by: Nikita Strygin <[email protected]>
@DCNick3
Copy link
Contributor

DCNick3 commented Oct 6, 2023

All of these were addressed in #3897 I think?

@DCNick3 DCNick3 closed this as completed Oct 6, 2023
@github-project-automation github-project-automation bot moved this from Todo to Done in Iroha 2.0 Oct 6, 2023
6r1d pushed a commit that referenced this issue Oct 17, 2023
…t rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in #2437

Signed-off-by: Nikita Strygin <[email protected]>
6r1d pushed a commit that referenced this issue Oct 17, 2023
…t rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in #2437

Signed-off-by: Nikita Strygin <[email protected]>
mversic pushed a commit that referenced this issue Oct 17, 2023
…t rid of unnecessary .except in derive(Filter)

This addresses the last of the concerns raised in #2437

Signed-off-by: Nikita Strygin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
iroha2-dev The re-implementation of a BFT hyperledger in RUST
Projects
None yet
Development

No branches or pull requests

4 participants