@@ -41,10 +41,19 @@ use uuid::Uuid;
4141
4242// TODO: Break up types into multiple files
4343
44- /// This macro implements serialization and deserialization of an enum type
45- /// from our database into our model types.
46- /// See [`VpcRouterKindEnum`] and [`VpcRouterKind`] for a sample usage
47- macro_rules! impl_enum_type {
44+ // TODO: The existence of both impl_enum_type and impl_enum_wrapper is a
45+ // temporary state of affairs while we do the work of converting uses of
46+ // impl_enum_wrapper to impl_enum_type. This is part of a broader initiative to
47+ // move types out of the common crate into Nexus where possible. See
48+ // https://github.com/oxidecomputer/omicron/issues/388
49+
50+ /// This macro implements serialization and deserialization of an enum type from
51+ /// our database into our model types. This version wraps an enum imported from
52+ /// the common crate in a struct so we can implement DB traits on it. We are
53+ /// moving those enum definitions into this file and using impl_enum_type
54+ /// instead, so eventually this macro will go away. See [`InstanceState`] for a
55+ /// sample usage.
56+ macro_rules! impl_enum_wrapper {
4857 (
4958 $( #[ $enum_meta: meta] ) *
5059 pub struct $diesel_type: ident;
@@ -101,6 +110,70 @@ macro_rules! impl_enum_type {
101110 }
102111}
103112
113+ /// This macro implements serialization and deserialization of an enum type from
114+ /// our database into our model types. See [`VpcRouterKindEnum`] and
115+ /// [`VpcRouterKind`] for a sample usage
116+ macro_rules! impl_enum_type {
117+ (
118+ $( #[ $enum_meta: meta] ) *
119+ pub struct $diesel_type: ident;
120+
121+ $( #[ $model_meta: meta] ) *
122+ pub enum $model_type: ident;
123+ $( $enum_item: ident => $sql_value: literal) +
124+ ) => {
125+
126+ $( #[ $enum_meta] ) *
127+ pub struct $diesel_type;
128+
129+ $( #[ $model_meta] ) *
130+ pub enum $model_type {
131+ $(
132+ $enum_item,
133+ ) *
134+ }
135+
136+ impl <DB > ToSql <$diesel_type, DB > for $model_type
137+ where
138+ DB : Backend ,
139+ {
140+ fn to_sql<W : std:: io:: Write >(
141+ & self ,
142+ out: & mut serialize:: Output <W , DB >,
143+ ) -> serialize:: Result {
144+ match self {
145+ $(
146+ $model_type:: $enum_item => {
147+ out. write_all( $sql_value) ?
148+ }
149+ ) *
150+ }
151+ Ok ( IsNull :: No )
152+ }
153+ }
154+
155+ impl <DB > FromSql <$diesel_type, DB > for $model_type
156+ where
157+ DB : Backend + for <' a> BinaryRawValue <' a>,
158+ {
159+ fn from_sql( bytes: RawValue <DB >) -> deserialize:: Result <Self > {
160+ match DB :: as_bytes( bytes) {
161+ $(
162+ $sql_value => {
163+ Ok ( $model_type:: $enum_item)
164+ }
165+ ) *
166+ _ => {
167+ Err ( concat!( "Unrecognized enum variant for " ,
168+ stringify!{ $model_type} )
169+ . into( ) )
170+ }
171+ }
172+ }
173+ }
174+ }
175+ }
176+
104177/// Newtype wrapper around [external::Name].
105178#[ derive(
106179 Clone ,
@@ -634,7 +707,7 @@ impl_enum_type!(
634707
635708 #[ derive( Clone , Debug , AsExpression , FromSqlRow , Serialize , Deserialize , PartialEq ) ]
636709 #[ sql_type = "DatasetKindEnum" ]
637- pub struct DatasetKind ( pub internal_api :: params :: DatasetKind ) ;
710+ pub enum DatasetKind ;
638711
639712 // Enum values
640713 Crucible => b"crucible"
@@ -644,7 +717,17 @@ impl_enum_type!(
644717
645718impl From < internal_api:: params:: DatasetKind > for DatasetKind {
646719 fn from ( k : internal_api:: params:: DatasetKind ) -> Self {
647- Self ( k)
720+ match k {
721+ internal_api:: params:: DatasetKind :: Crucible => {
722+ DatasetKind :: Crucible
723+ }
724+ internal_api:: params:: DatasetKind :: Cockroach => {
725+ DatasetKind :: Cockroach
726+ }
727+ internal_api:: params:: DatasetKind :: Clickhouse => {
728+ DatasetKind :: Clickhouse
729+ }
730+ }
648731 }
649732}
650733
@@ -687,7 +770,7 @@ impl Dataset {
687770 kind : DatasetKind ,
688771 ) -> Self {
689772 let size_used = match kind {
690- DatasetKind ( internal_api :: params :: DatasetKind :: Crucible ) => Some ( 0 ) ,
773+ DatasetKind :: Crucible => Some ( 0 ) ,
691774 _ => None ,
692775 } ;
693776 Self {
@@ -1067,7 +1150,7 @@ impl Into<internal::nexus::InstanceRuntimeState> for InstanceRuntimeState {
10671150 }
10681151}
10691152
1070- impl_enum_type ! (
1153+ impl_enum_wrapper ! (
10711154 #[ derive( SqlType , Debug ) ]
10721155 #[ postgres( type_name = "instance_state" , type_schema = "public" ) ]
10731156 pub struct InstanceStateEnum ;
@@ -1587,9 +1670,9 @@ impl_enum_type!(
15871670 #[ postgres( type_name = "vpc_router_kind" , type_schema = "public" ) ]
15881671 pub struct VpcRouterKindEnum ;
15891672
1590- #[ derive( Clone , Debug , AsExpression , FromSqlRow ) ]
1673+ #[ derive( Clone , Copy , Debug , AsExpression , FromSqlRow , PartialEq ) ]
15911674 #[ sql_type = "VpcRouterKindEnum" ]
1592- pub struct VpcRouterKind ( pub external :: VpcRouterKind ) ;
1675+ pub enum VpcRouterKind ;
15931676
15941677 // Enum values
15951678 System => b"system"
@@ -1611,16 +1694,11 @@ impl VpcRouter {
16111694 pub fn new (
16121695 router_id : Uuid ,
16131696 vpc_id : Uuid ,
1614- kind : external :: VpcRouterKind ,
1697+ kind : VpcRouterKind ,
16151698 params : params:: VpcRouterCreate ,
16161699 ) -> Self {
16171700 let identity = VpcRouterIdentity :: new ( router_id, params. identity ) ;
1618- Self {
1619- identity,
1620- vpc_id,
1621- kind : VpcRouterKind ( kind) ,
1622- rcgen : Generation :: new ( ) ,
1623- }
1701+ Self { identity, vpc_id, kind, rcgen : Generation :: new ( ) }
16241702 }
16251703}
16261704
@@ -1631,16 +1709,6 @@ impl DatastoreCollection<RouterRoute> for VpcRouter {
16311709 type CollectionIdColumn = router_route:: dsl:: router_id ;
16321710}
16331711
1634- impl Into < external:: VpcRouter > for VpcRouter {
1635- fn into ( self ) -> external:: VpcRouter {
1636- external:: VpcRouter {
1637- identity : self . identity ( ) ,
1638- vpc_id : self . vpc_id ,
1639- kind : self . kind . 0 ,
1640- }
1641- }
1642- }
1643-
16441712#[ derive( AsChangeset ) ]
16451713#[ table_name = "vpc_router" ]
16461714pub struct VpcRouterUpdate {
@@ -1659,7 +1727,7 @@ impl From<params::VpcRouterUpdate> for VpcRouterUpdate {
16591727 }
16601728}
16611729
1662- impl_enum_type ! (
1730+ impl_enum_wrapper ! (
16631731 #[ derive( SqlType , Debug ) ]
16641732 #[ postgres( type_name = "router_route_kind" , type_schema = "public" ) ]
16651733 pub struct RouterRouteKindEnum ;
@@ -1807,7 +1875,7 @@ impl From<external::RouterRouteUpdateParams> for RouterRouteUpdate {
18071875 }
18081876}
18091877
1810- impl_enum_type ! (
1878+ impl_enum_wrapper ! (
18111879 #[ derive( SqlType , Debug ) ]
18121880 #[ postgres( type_name = "vpc_firewall_rule_status" , type_schema = "public" ) ]
18131881 pub struct VpcFirewallRuleStatusEnum ;
@@ -1822,7 +1890,7 @@ impl_enum_type!(
18221890NewtypeFrom ! { ( ) pub struct VpcFirewallRuleStatus ( external:: VpcFirewallRuleStatus ) ; }
18231891NewtypeDeref ! { ( ) pub struct VpcFirewallRuleStatus ( external:: VpcFirewallRuleStatus ) ; }
18241892
1825- impl_enum_type ! (
1893+ impl_enum_wrapper ! (
18261894 #[ derive( SqlType , Debug ) ]
18271895 #[ postgres( type_name = "vpc_firewall_rule_direction" , type_schema = "public" ) ]
18281896 pub struct VpcFirewallRuleDirectionEnum ;
@@ -1837,7 +1905,7 @@ impl_enum_type!(
18371905NewtypeFrom ! { ( ) pub struct VpcFirewallRuleDirection ( external:: VpcFirewallRuleDirection ) ; }
18381906NewtypeDeref ! { ( ) pub struct VpcFirewallRuleDirection ( external:: VpcFirewallRuleDirection ) ; }
18391907
1840- impl_enum_type ! (
1908+ impl_enum_wrapper ! (
18411909 #[ derive( SqlType , Debug ) ]
18421910 #[ postgres( type_name = "vpc_firewall_rule_action" , type_schema = "public" ) ]
18431911 pub struct VpcFirewallRuleActionEnum ;
@@ -1852,7 +1920,7 @@ impl_enum_type!(
18521920NewtypeFrom ! { ( ) pub struct VpcFirewallRuleAction ( external:: VpcFirewallRuleAction ) ; }
18531921NewtypeDeref ! { ( ) pub struct VpcFirewallRuleAction ( external:: VpcFirewallRuleAction ) ; }
18541922
1855- impl_enum_type ! (
1923+ impl_enum_wrapper ! (
18561924 #[ derive( SqlType , Debug ) ]
18571925 #[ postgres( type_name = "vpc_firewall_rule_protocol" , type_schema = "public" ) ]
18581926 pub struct VpcFirewallRuleProtocolEnum ;
@@ -2252,7 +2320,7 @@ impl RoleAssignmentBuiltin {
22522320 }
22532321}
22542322
2255- impl_enum_type ! (
2323+ impl_enum_wrapper ! (
22562324 #[ derive( SqlType , Debug , QueryId ) ]
22572325 #[ postgres( type_name = "update_artifact_kind" , type_schema = "public" ) ]
22582326 pub struct UpdateArtifactKindEnum ;
0 commit comments