From 1151612d0e743f3985e76e748fbab1c66b6db93a Mon Sep 17 00:00:00 2001 From: Georgy Moshkin <gmoshkin@picodata.io> Date: Thu, 22 Dec 2022 18:44:50 +0300 Subject: [PATCH] refactor(storage): hide boilerplate behind a macro --- src/storage.rs | 134 ++++++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 58 deletions(-) diff --git a/src/storage.rs b/src/storage.rs index 700e45c1e5..642516ad9c 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -17,14 +17,84 @@ use std::marker::PhantomData; // ClusterwideSpace //////////////////////////////////////////////////////////////////////////////// -::tarantool::define_str_enum! { +macro_rules! define_clusterwide_spaces { + ( + $(#[$space_meta:meta])* + pub enum $cw_space:ident { + $( + $(#[$field_meta:meta])* + $cw_space_var:ident = $cw_space_name:expr => $cw_space_struct:ty, + )+ + } + + $(#[$index_meta:meta])* + pub enum $cw_index:ident { + #space_name( $index_of:ident <#space_struct_name>), + } + ) => { + ::tarantool::define_str_enum! { + $(#[$space_meta])* + pub enum $cw_space { + $( + $(#[$field_meta])* + $cw_space_var = $cw_space_name, + )+ + } + } + + $(#[$index_meta])* + #[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash)] + pub enum $cw_index { + $( $cw_space_var($index_of<$cw_space_struct>),)+ + } + + impl From<$cw_space> for $cw_index { + fn from(space: $cw_space) -> Self { + match space { + $( + $cw_space::$cw_space_var => Self::$cw_space_var(<$cw_space_struct>::primary_index()), + )+ + } + } + } + + impl $cw_index { + pub const fn space(&self) -> $cw_space { + match self { + $( + Self::$cw_space_var(_) => $cw_space::$cw_space_var, + )+ + } + } + + pub const fn index_name(&self) -> &'static str { + match self { + $( Self::$cw_space_var(idx) => idx.as_str(), )+ + } + } + + pub fn is_primary(&self) -> bool { + match self { + $( Self::$cw_space_var(idx) => idx.is_primary(), )+ + } + } + } + } +} + +define_clusterwide_spaces! { /// An enumeration of builtin cluster-wide spaces pub enum ClusterwideSpace { - Instance = "_picodata_instance", - Address = "_picodata_peer_address", - Property = "_picodata_property", - Replicaset = "_picodata_replicaset", - Migration = "_picodata_migration", + Instance = "_picodata_instance" => Instances, + Address = "_picodata_peer_address" => PeerAddresses, + Property = "_picodata_property" => Properties, + Replicaset = "_picodata_replicaset" => Replicasets, + Migration = "_picodata_migration" => Migrations, + } + + /// An index of a clusterwide space. + pub enum ClusterwideSpaceIndex { + #space_name(IndexOf<#space_struct_name>), } } @@ -70,16 +140,6 @@ pub trait TClusterwideSpace { /// A type alias for getting the enumeration of indexes for a clusterwide space. pub type IndexOf<T> = <T as TClusterwideSpace>::Index; -/// An index of a clusterwide space. -#[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash)] -pub enum ClusterwideSpaceIndex { - Property(IndexOf<Properties>), - Instance(IndexOf<Instances>), - Address(IndexOf<PeerAddresses>), - Replicaset(IndexOf<Replicasets>), - Migration(IndexOf<Migrations>), -} - impl ClusterwideSpaceIndex { #[inline] fn get(&self) -> tarantool::Result<Index> { @@ -108,48 +168,6 @@ impl ClusterwideSpaceIndex { pub fn delete(&self, key: &impl ToTupleBuffer) -> tarantool::Result<Option<Tuple>> { self.get()?.delete(key) } - - pub const fn space(&self) -> ClusterwideSpace { - match self { - Self::Property(_) => ClusterwideSpace::Property, - Self::Instance(_) => ClusterwideSpace::Instance, - Self::Address(_) => ClusterwideSpace::Address, - Self::Replicaset(_) => ClusterwideSpace::Replicaset, - Self::Migration(_) => ClusterwideSpace::Migration, - } - } - - pub const fn index_name(&self) -> &'static str { - match self { - Self::Property(idx) => idx.as_str(), - Self::Instance(idx) => idx.as_str(), - Self::Address(idx) => idx.as_str(), - Self::Replicaset(idx) => idx.as_str(), - Self::Migration(idx) => idx.as_str(), - } - } - - pub fn is_primary(&self) -> bool { - match self { - Self::Property(idx) => idx.is_primary(), - Self::Instance(idx) => idx.is_primary(), - Self::Address(idx) => idx.is_primary(), - Self::Replicaset(idx) => idx.is_primary(), - Self::Migration(idx) => idx.is_primary(), - } - } -} - -impl From<ClusterwideSpace> for ClusterwideSpaceIndex { - fn from(space: ClusterwideSpace) -> Self { - match space { - ClusterwideSpace::Property => Self::Property(Properties::primary_index()), - ClusterwideSpace::Instance => Self::Instance(Instances::primary_index()), - ClusterwideSpace::Address => Self::Address(PeerAddresses::primary_index()), - ClusterwideSpace::Replicaset => Self::Replicaset(Replicasets::primary_index()), - ClusterwideSpace::Migration => Self::Migration(Migrations::primary_index()), - } - } } impl std::fmt::Display for ClusterwideSpaceIndex { -- GitLab