mz_catalog/durable/objects/
serialization.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! This module is responsible for serializing catalog objects into Protobuf.
11
12use mz_ore::cast::CastFrom;
13use mz_proto::{IntoRustIfSome, ProtoType, RustType, TryFromProtoError};
14
15use crate::durable::objects::state_update::StateUpdateKindJson;
16use crate::durable::objects::{
17    AuditLogKey, ClusterIntrospectionSourceIndexKey, ClusterIntrospectionSourceIndexValue,
18    ClusterKey, ClusterReplicaKey, ClusterReplicaValue, ClusterValue, CommentKey, CommentValue,
19    ConfigKey, ConfigValue, DatabaseKey, DatabaseValue, DefaultPrivilegesKey,
20    DefaultPrivilegesValue, GidMappingKey, GidMappingValue, IdAllocKey, IdAllocValue,
21    IntrospectionSourceIndexCatalogItemId, IntrospectionSourceIndexGlobalId, ItemKey, ItemValue,
22    NetworkPolicyKey, NetworkPolicyValue, RoleKey, RoleValue, SchemaKey, SchemaValue,
23    ServerConfigurationKey, ServerConfigurationValue, SettingKey, SettingValue, SourceReference,
24    SourceReferencesKey, SourceReferencesValue, StorageCollectionMetadataKey,
25    StorageCollectionMetadataValue, SystemCatalogItemId, SystemGlobalId, SystemPrivilegesKey,
26    SystemPrivilegesValue, TxnWalShardValue, UnfinalizedShardKey,
27};
28use crate::durable::{
29    ClusterConfig, ClusterVariant, ClusterVariantManaged, ReplicaConfig, ReplicaLocation,
30};
31
32use super::{RoleAuthKey, RoleAuthValue};
33
34pub mod proto {
35    pub use mz_catalog_protos::objects::*;
36}
37
38impl From<proto::StateUpdateKind> for StateUpdateKindJson {
39    fn from(value: proto::StateUpdateKind) -> Self {
40        StateUpdateKindJson::from_serde(value)
41    }
42}
43
44impl TryFrom<StateUpdateKindJson> for proto::StateUpdateKind {
45    type Error = String;
46
47    fn try_from(value: StateUpdateKindJson) -> Result<Self, Self::Error> {
48        value.try_to_serde::<Self>().map_err(|err| err.to_string())
49    }
50}
51
52impl RustType<proto::ClusterConfig> for ClusterConfig {
53    fn into_proto(&self) -> proto::ClusterConfig {
54        proto::ClusterConfig {
55            variant: Some(self.variant.into_proto()),
56            workload_class: self.workload_class.clone(),
57        }
58    }
59
60    fn from_proto(proto: proto::ClusterConfig) -> Result<Self, TryFromProtoError> {
61        Ok(Self {
62            variant: proto.variant.into_rust_if_some("ClusterConfig::variant")?,
63            workload_class: proto.workload_class,
64        })
65    }
66}
67
68impl RustType<proto::cluster_config::Variant> for ClusterVariant {
69    fn into_proto(&self) -> proto::cluster_config::Variant {
70        match self {
71            ClusterVariant::Managed(ClusterVariantManaged {
72                size,
73                availability_zones,
74                logging,
75                replication_factor,
76                disk,
77                optimizer_feature_overrides,
78                schedule,
79            }) => proto::cluster_config::Variant::Managed(proto::cluster_config::ManagedCluster {
80                size: size.to_string(),
81                availability_zones: availability_zones.clone(),
82                logging: Some(logging.into_proto()),
83                replication_factor: *replication_factor,
84                disk: *disk,
85                optimizer_feature_overrides: optimizer_feature_overrides.into_proto(),
86                schedule: Some(schedule.into_proto()),
87            }),
88            ClusterVariant::Unmanaged => proto::cluster_config::Variant::Unmanaged(proto::Empty {}),
89        }
90    }
91
92    fn from_proto(proto: proto::cluster_config::Variant) -> Result<Self, TryFromProtoError> {
93        match proto {
94            proto::cluster_config::Variant::Unmanaged(_) => Ok(Self::Unmanaged),
95            proto::cluster_config::Variant::Managed(managed) => {
96                Ok(Self::Managed(ClusterVariantManaged {
97                    size: managed.size,
98                    availability_zones: managed.availability_zones,
99                    logging: managed
100                        .logging
101                        .into_rust_if_some("ManagedCluster::logging")?,
102                    replication_factor: managed.replication_factor,
103                    disk: managed.disk,
104                    optimizer_feature_overrides: managed.optimizer_feature_overrides.into_rust()?,
105                    schedule: managed.schedule.unwrap_or_default().into_rust()?,
106                }))
107            }
108        }
109    }
110}
111
112impl RustType<proto::ReplicaConfig> for ReplicaConfig {
113    fn into_proto(&self) -> proto::ReplicaConfig {
114        proto::ReplicaConfig {
115            logging: Some(self.logging.into_proto()),
116            location: Some(self.location.into_proto()),
117        }
118    }
119
120    fn from_proto(proto: proto::ReplicaConfig) -> Result<Self, TryFromProtoError> {
121        Ok(ReplicaConfig {
122            location: proto
123                .location
124                .into_rust_if_some("ReplicaConfig::location")?,
125            logging: proto.logging.into_rust_if_some("ReplicaConfig::logging")?,
126        })
127    }
128}
129
130impl RustType<proto::replica_config::Location> for ReplicaLocation {
131    fn into_proto(&self) -> proto::replica_config::Location {
132        match self {
133            ReplicaLocation::Unmanaged {
134                storagectl_addrs,
135                storage_addrs,
136                computectl_addrs,
137                compute_addrs,
138                workers,
139            } => proto::replica_config::Location::Unmanaged(
140                proto::replica_config::UnmanagedLocation {
141                    storagectl_addrs: storagectl_addrs.clone(),
142                    storage_addrs: storage_addrs.clone(),
143                    computectl_addrs: computectl_addrs.clone(),
144                    compute_addrs: compute_addrs.clone(),
145                    workers: CastFrom::cast_from(*workers),
146                },
147            ),
148            ReplicaLocation::Managed {
149                size,
150                availability_zone,
151                disk,
152                billed_as,
153                internal,
154                pending,
155            } => proto::replica_config::Location::Managed(proto::replica_config::ManagedLocation {
156                size: size.to_string(),
157                availability_zone: availability_zone.clone(),
158                disk: *disk,
159                billed_as: billed_as.clone(),
160                internal: *internal,
161                pending: *pending,
162            }),
163        }
164    }
165
166    fn from_proto(proto: proto::replica_config::Location) -> Result<Self, TryFromProtoError> {
167        match proto {
168            proto::replica_config::Location::Unmanaged(location) => {
169                Ok(ReplicaLocation::Unmanaged {
170                    storagectl_addrs: location.storagectl_addrs,
171                    storage_addrs: location.storage_addrs,
172                    computectl_addrs: location.computectl_addrs,
173                    compute_addrs: location.compute_addrs,
174                    workers: CastFrom::cast_from(location.workers),
175                })
176            }
177            proto::replica_config::Location::Managed(location) => Ok(ReplicaLocation::Managed {
178                availability_zone: location.availability_zone,
179                billed_as: location.billed_as,
180                disk: location.disk,
181                internal: location.internal,
182                size: location.size,
183                pending: location.pending,
184            }),
185        }
186    }
187}
188
189impl RustType<proto::SettingKey> for SettingKey {
190    fn into_proto(&self) -> proto::SettingKey {
191        proto::SettingKey {
192            name: self.name.to_string(),
193        }
194    }
195
196    fn from_proto(proto: proto::SettingKey) -> Result<Self, TryFromProtoError> {
197        Ok(SettingKey { name: proto.name })
198    }
199}
200
201impl RustType<proto::SettingValue> for SettingValue {
202    fn into_proto(&self) -> proto::SettingValue {
203        proto::SettingValue {
204            value: self.value.to_string(),
205        }
206    }
207
208    fn from_proto(proto: proto::SettingValue) -> Result<Self, TryFromProtoError> {
209        Ok(SettingValue { value: proto.value })
210    }
211}
212
213impl RustType<proto::IdAllocKey> for IdAllocKey {
214    fn into_proto(&self) -> proto::IdAllocKey {
215        proto::IdAllocKey {
216            name: self.name.to_string(),
217        }
218    }
219
220    fn from_proto(proto: proto::IdAllocKey) -> Result<Self, TryFromProtoError> {
221        Ok(IdAllocKey { name: proto.name })
222    }
223}
224
225impl RustType<proto::IdAllocValue> for IdAllocValue {
226    fn into_proto(&self) -> proto::IdAllocValue {
227        proto::IdAllocValue {
228            next_id: self.next_id,
229        }
230    }
231
232    fn from_proto(proto: proto::IdAllocValue) -> Result<Self, TryFromProtoError> {
233        Ok(IdAllocValue {
234            next_id: proto.next_id,
235        })
236    }
237}
238
239impl RustType<proto::GidMappingKey> for GidMappingKey {
240    fn into_proto(&self) -> proto::GidMappingKey {
241        proto::GidMappingKey {
242            schema_name: self.schema_name.to_string(),
243            object_type: self.object_type.into_proto().into(),
244            object_name: self.object_name.to_string(),
245        }
246    }
247
248    fn from_proto(proto: proto::GidMappingKey) -> Result<Self, TryFromProtoError> {
249        let object_type = proto::CatalogItemType::try_from(proto.object_type)
250            .map_err(|_| TryFromProtoError::unknown_enum_variant("CatalogItemType"))?;
251        Ok(GidMappingKey {
252            schema_name: proto.schema_name,
253            object_type: object_type.into_rust()?,
254            object_name: proto.object_name,
255        })
256    }
257}
258
259impl RustType<proto::GidMappingValue> for GidMappingValue {
260    fn into_proto(&self) -> proto::GidMappingValue {
261        proto::GidMappingValue {
262            id: self.catalog_id.0,
263            global_id: Some(self.global_id.into_proto()),
264            fingerprint: self.fingerprint.to_string(),
265        }
266    }
267
268    fn from_proto(proto: proto::GidMappingValue) -> Result<Self, TryFromProtoError> {
269        Ok(GidMappingValue {
270            catalog_id: SystemCatalogItemId(proto.id),
271            global_id: proto
272                .global_id
273                .into_rust_if_some("GidMappingValue::global_id")?,
274            fingerprint: proto.fingerprint,
275        })
276    }
277}
278
279impl RustType<proto::ClusterKey> for ClusterKey {
280    fn into_proto(&self) -> proto::ClusterKey {
281        proto::ClusterKey {
282            id: Some(self.id.into_proto()),
283        }
284    }
285
286    fn from_proto(proto: proto::ClusterKey) -> Result<Self, TryFromProtoError> {
287        Ok(ClusterKey {
288            id: proto.id.into_rust_if_some("ClusterKey::id")?,
289        })
290    }
291}
292
293impl RustType<proto::ClusterValue> for ClusterValue {
294    fn into_proto(&self) -> proto::ClusterValue {
295        proto::ClusterValue {
296            name: self.name.to_string(),
297            config: Some(self.config.into_proto()),
298            owner_id: Some(self.owner_id.into_proto()),
299            privileges: self.privileges.into_proto(),
300        }
301    }
302
303    fn from_proto(proto: proto::ClusterValue) -> Result<Self, TryFromProtoError> {
304        Ok(ClusterValue {
305            name: proto.name,
306            config: proto.config.unwrap_or_default().into_rust()?,
307            owner_id: proto.owner_id.into_rust_if_some("ClusterValue::owner_id")?,
308            privileges: proto.privileges.into_rust()?,
309        })
310    }
311}
312
313impl RustType<proto::ClusterIntrospectionSourceIndexKey> for ClusterIntrospectionSourceIndexKey {
314    fn into_proto(&self) -> proto::ClusterIntrospectionSourceIndexKey {
315        proto::ClusterIntrospectionSourceIndexKey {
316            cluster_id: Some(self.cluster_id.into_proto()),
317            name: self.name.to_string(),
318        }
319    }
320
321    fn from_proto(
322        proto: proto::ClusterIntrospectionSourceIndexKey,
323    ) -> Result<Self, TryFromProtoError> {
324        Ok(ClusterIntrospectionSourceIndexKey {
325            cluster_id: proto
326                .cluster_id
327                .into_rust_if_some("ClusterIntrospectionSourceIndexKey::cluster_id")?,
328            name: proto.name,
329        })
330    }
331}
332
333impl RustType<proto::ClusterIntrospectionSourceIndexValue>
334    for ClusterIntrospectionSourceIndexValue
335{
336    fn into_proto(&self) -> proto::ClusterIntrospectionSourceIndexValue {
337        proto::ClusterIntrospectionSourceIndexValue {
338            index_id: self.catalog_id.0,
339            global_id: Some(self.global_id.into_proto()),
340            oid: self.oid,
341        }
342    }
343
344    fn from_proto(
345        proto: proto::ClusterIntrospectionSourceIndexValue,
346    ) -> Result<Self, TryFromProtoError> {
347        Ok(ClusterIntrospectionSourceIndexValue {
348            catalog_id: IntrospectionSourceIndexCatalogItemId(proto.index_id),
349            global_id: proto
350                .global_id
351                .into_rust_if_some("ClusterIntrospectionSourceIndexValue::global_id")?,
352            oid: proto.oid,
353        })
354    }
355}
356
357impl RustType<proto::ClusterReplicaKey> for ClusterReplicaKey {
358    fn into_proto(&self) -> proto::ClusterReplicaKey {
359        proto::ClusterReplicaKey {
360            id: Some(self.id.into_proto()),
361        }
362    }
363
364    fn from_proto(proto: proto::ClusterReplicaKey) -> Result<Self, TryFromProtoError> {
365        Ok(ClusterReplicaKey {
366            id: proto.id.into_rust_if_some("ClusterReplicaKey::id")?,
367        })
368    }
369}
370
371impl RustType<proto::ClusterReplicaValue> for ClusterReplicaValue {
372    fn into_proto(&self) -> proto::ClusterReplicaValue {
373        proto::ClusterReplicaValue {
374            cluster_id: Some(self.cluster_id.into_proto()),
375            name: self.name.to_string(),
376            config: Some(self.config.into_proto()),
377            owner_id: Some(self.owner_id.into_proto()),
378        }
379    }
380
381    fn from_proto(proto: proto::ClusterReplicaValue) -> Result<Self, TryFromProtoError> {
382        Ok(ClusterReplicaValue {
383            cluster_id: proto
384                .cluster_id
385                .into_rust_if_some("ClusterReplicaValue::cluster_id")?,
386            name: proto.name,
387            config: proto
388                .config
389                .into_rust_if_some("ClusterReplicaValue::config")?,
390            owner_id: proto
391                .owner_id
392                .into_rust_if_some("ClusterReplicaValue::owner_id")?,
393        })
394    }
395}
396
397impl RustType<proto::DatabaseKey> for DatabaseKey {
398    fn into_proto(&self) -> proto::DatabaseKey {
399        proto::DatabaseKey {
400            id: Some(self.id.into_proto()),
401        }
402    }
403
404    fn from_proto(proto: proto::DatabaseKey) -> Result<Self, TryFromProtoError> {
405        Ok(DatabaseKey {
406            id: proto.id.into_rust_if_some("DatabaseKey::value")?,
407        })
408    }
409}
410
411impl RustType<proto::DatabaseValue> for DatabaseValue {
412    fn into_proto(&self) -> proto::DatabaseValue {
413        proto::DatabaseValue {
414            name: self.name.clone(),
415            owner_id: Some(self.owner_id.into_proto()),
416            privileges: self.privileges.into_proto(),
417            oid: self.oid,
418        }
419    }
420
421    fn from_proto(proto: proto::DatabaseValue) -> Result<Self, TryFromProtoError> {
422        Ok(DatabaseValue {
423            name: proto.name,
424            owner_id: (proto
425                .owner_id
426                .into_rust_if_some("DatabaseValue::owner_id")?),
427            privileges: proto.privileges.into_rust()?,
428            oid: proto.oid,
429        })
430    }
431}
432
433impl RustType<proto::SchemaKey> for SchemaKey {
434    fn into_proto(&self) -> proto::SchemaKey {
435        proto::SchemaKey {
436            id: Some(self.id.into_proto()),
437        }
438    }
439
440    fn from_proto(proto: proto::SchemaKey) -> Result<Self, TryFromProtoError> {
441        Ok(SchemaKey {
442            id: proto.id.into_rust_if_some("SchemaKey::id")?,
443        })
444    }
445}
446
447impl RustType<proto::SchemaValue> for SchemaValue {
448    fn into_proto(&self) -> proto::SchemaValue {
449        proto::SchemaValue {
450            name: self.name.clone(),
451            database_id: self.database_id.map(|id| id.into_proto()),
452            owner_id: Some(self.owner_id.into_proto()),
453            privileges: self.privileges.into_proto(),
454            oid: self.oid,
455        }
456    }
457
458    fn from_proto(proto: proto::SchemaValue) -> Result<Self, TryFromProtoError> {
459        Ok(SchemaValue {
460            name: proto.name,
461            database_id: proto.database_id.into_rust()?,
462            owner_id: (proto.owner_id.into_rust_if_some("SchemaValue::owner_id")?),
463            privileges: proto.privileges.into_rust()?,
464            oid: proto.oid,
465        })
466    }
467}
468
469impl RustType<proto::ItemKey> for ItemKey {
470    fn into_proto(&self) -> proto::ItemKey {
471        proto::ItemKey {
472            gid: Some(self.id.into_proto()),
473        }
474    }
475
476    fn from_proto(proto: proto::ItemKey) -> Result<Self, TryFromProtoError> {
477        Ok(ItemKey {
478            id: proto.gid.into_rust_if_some("ItemKey::gid")?,
479        })
480    }
481}
482
483impl RustType<proto::ItemValue> for ItemValue {
484    fn into_proto(&self) -> proto::ItemValue {
485        let definition = proto::CatalogItem {
486            value: Some(proto::catalog_item::Value::V1(proto::catalog_item::V1 {
487                create_sql: self.create_sql.clone(),
488            })),
489        };
490        proto::ItemValue {
491            schema_id: Some(self.schema_id.into_proto()),
492            name: self.name.to_string(),
493            definition: Some(definition),
494            owner_id: Some(self.owner_id.into_proto()),
495            privileges: self.privileges.into_proto(),
496            oid: self.oid,
497            global_id: Some(self.global_id.into_proto()),
498            extra_versions: self
499                .extra_versions
500                .iter()
501                .map(|(version, global_id)| proto::ItemVersion {
502                    global_id: Some(global_id.into_proto()),
503                    version: Some(version.into_proto()),
504                })
505                .collect(),
506        }
507    }
508
509    fn from_proto(proto: proto::ItemValue) -> Result<Self, TryFromProtoError> {
510        let create_sql_value = proto
511            .definition
512            .ok_or_else(|| TryFromProtoError::missing_field("ItemValue::definition"))?
513            .value
514            .ok_or_else(|| TryFromProtoError::missing_field("CatalogItem::value"))?;
515        let create_sql = match create_sql_value {
516            proto::catalog_item::Value::V1(c) => c.create_sql,
517        };
518        let extra_versions = proto
519            .extra_versions
520            .into_iter()
521            .map(|item_version| {
522                let version = item_version
523                    .version
524                    .into_rust_if_some("ItemVersion::version")?;
525                let global_id = item_version
526                    .global_id
527                    .into_rust_if_some("ItemVersion::global_id")?;
528                Ok::<_, TryFromProtoError>((version, global_id))
529            })
530            .collect::<Result<_, _>>()?;
531        Ok(ItemValue {
532            schema_id: proto.schema_id.into_rust_if_some("ItemValue::schema_id")?,
533            name: proto.name,
534            create_sql,
535            owner_id: proto.owner_id.into_rust_if_some("ItemValue::owner_id")?,
536            privileges: proto.privileges.into_rust()?,
537            oid: proto.oid,
538            global_id: proto.global_id.into_rust_if_some("ItemValue::global_id")?,
539            extra_versions,
540        })
541    }
542}
543
544impl RustType<proto::CommentKey> for CommentKey {
545    fn into_proto(&self) -> proto::CommentKey {
546        let sub_component = match &self.sub_component {
547            Some(pos) => Some(proto::comment_key::SubComponent::ColumnPos(
548                CastFrom::cast_from(*pos),
549            )),
550            None => None,
551        };
552        proto::CommentKey {
553            object: Some(self.object_id.into_proto()),
554            sub_component,
555        }
556    }
557
558    fn from_proto(proto: proto::CommentKey) -> Result<Self, TryFromProtoError> {
559        let sub_component = match proto.sub_component {
560            Some(proto::comment_key::SubComponent::ColumnPos(pos)) => {
561                Some(CastFrom::cast_from(pos))
562            }
563            None => None,
564        };
565        Ok(CommentKey {
566            object_id: proto.object.into_rust_if_some("CommentKey::object")?,
567            sub_component,
568        })
569    }
570}
571
572impl RustType<proto::CommentValue> for CommentValue {
573    fn into_proto(&self) -> proto::CommentValue {
574        proto::CommentValue {
575            comment: self.comment.clone(),
576        }
577    }
578
579    fn from_proto(proto: proto::CommentValue) -> Result<Self, TryFromProtoError> {
580        Ok(CommentValue {
581            comment: proto.comment,
582        })
583    }
584}
585
586impl RustType<proto::RoleKey> for RoleKey {
587    fn into_proto(&self) -> proto::RoleKey {
588        proto::RoleKey {
589            id: Some(self.id.into_proto()),
590        }
591    }
592
593    fn from_proto(proto: proto::RoleKey) -> Result<Self, TryFromProtoError> {
594        Ok(RoleKey {
595            id: proto.id.into_rust_if_some("RoleKey::id")?,
596        })
597    }
598}
599
600impl RustType<proto::RoleValue> for RoleValue {
601    fn into_proto(&self) -> proto::RoleValue {
602        proto::RoleValue {
603            name: self.name.to_string(),
604            attributes: Some(self.attributes.into_proto()),
605            membership: Some(self.membership.into_proto()),
606            vars: Some(self.vars.into_proto()),
607            oid: self.oid,
608        }
609    }
610
611    fn from_proto(proto: proto::RoleValue) -> Result<Self, TryFromProtoError> {
612        Ok(RoleValue {
613            name: proto.name,
614            attributes: proto
615                .attributes
616                .into_rust_if_some("RoleValue::attributes")?,
617            membership: proto
618                .membership
619                .into_rust_if_some("RoleValue::membership")?,
620            vars: proto.vars.into_rust_if_some("RoleValue::vars")?,
621            oid: proto.oid,
622        })
623    }
624}
625
626impl RustType<proto::RoleAuthKey> for RoleAuthKey {
627    fn into_proto(&self) -> proto::RoleAuthKey {
628        proto::RoleAuthKey {
629            id: Some(self.role_id.into_proto()),
630        }
631    }
632
633    fn from_proto(proto: proto::RoleAuthKey) -> Result<Self, TryFromProtoError> {
634        Ok(RoleAuthKey {
635            role_id: proto.id.into_rust_if_some("RoleAuthKey::id")?,
636        })
637    }
638}
639
640impl RustType<proto::RoleAuthValue> for RoleAuthValue {
641    fn into_proto(&self) -> proto::RoleAuthValue {
642        proto::RoleAuthValue {
643            password_hash: self.password_hash.clone(),
644            updated_at: Some(proto::EpochMillis {
645                millis: self.updated_at,
646            }),
647        }
648    }
649
650    fn from_proto(proto: proto::RoleAuthValue) -> Result<Self, TryFromProtoError> {
651        Ok(RoleAuthValue {
652            password_hash: proto.password_hash,
653            updated_at: proto
654                .updated_at
655                .into_rust_if_some("RoleAuthValue::updated_at")?,
656        })
657    }
658}
659
660impl RustType<proto::NetworkPolicyKey> for NetworkPolicyKey {
661    fn into_proto(&self) -> proto::NetworkPolicyKey {
662        proto::NetworkPolicyKey {
663            id: Some(self.id.into_proto()),
664        }
665    }
666
667    fn from_proto(proto: proto::NetworkPolicyKey) -> Result<Self, TryFromProtoError> {
668        Ok(NetworkPolicyKey {
669            id: proto.id.into_rust_if_some("NetworkPolicyKey::id")?,
670        })
671    }
672}
673
674impl RustType<proto::NetworkPolicyValue> for NetworkPolicyValue {
675    fn into_proto(&self) -> proto::NetworkPolicyValue {
676        proto::NetworkPolicyValue {
677            name: self.name.to_string(),
678            rules: self.rules.into_proto(),
679            owner_id: Some(self.owner_id.into_proto()),
680            privileges: self.privileges.into_proto(),
681            oid: self.oid,
682        }
683    }
684
685    fn from_proto(proto: proto::NetworkPolicyValue) -> Result<Self, TryFromProtoError> {
686        Ok(NetworkPolicyValue {
687            name: proto.name,
688            rules: proto.rules.into_rust()?,
689            owner_id: proto
690                .owner_id
691                .into_rust_if_some("NetworkPolicyValue::owner_id,")?,
692            privileges: proto.privileges.into_rust()?,
693            oid: proto.oid,
694        })
695    }
696}
697
698impl RustType<proto::ConfigKey> for ConfigKey {
699    fn into_proto(&self) -> proto::ConfigKey {
700        proto::ConfigKey {
701            key: self.key.to_string(),
702        }
703    }
704
705    fn from_proto(proto: proto::ConfigKey) -> Result<Self, TryFromProtoError> {
706        Ok(ConfigKey { key: proto.key })
707    }
708}
709
710impl RustType<proto::ConfigValue> for ConfigValue {
711    fn into_proto(&self) -> proto::ConfigValue {
712        proto::ConfigValue { value: self.value }
713    }
714
715    fn from_proto(proto: proto::ConfigValue) -> Result<Self, TryFromProtoError> {
716        Ok(ConfigValue { value: proto.value })
717    }
718}
719
720impl RustType<proto::AuditLogKey> for AuditLogKey {
721    fn into_proto(&self) -> proto::AuditLogKey {
722        proto::AuditLogKey {
723            event: Some(self.event.into_proto()),
724        }
725    }
726
727    fn from_proto(proto: proto::AuditLogKey) -> Result<Self, TryFromProtoError> {
728        Ok(AuditLogKey {
729            event: proto.event.into_rust_if_some("AuditLogKey::event")?,
730        })
731    }
732}
733
734impl RustType<proto::StorageCollectionMetadataKey> for StorageCollectionMetadataKey {
735    fn into_proto(&self) -> proto::StorageCollectionMetadataKey {
736        proto::StorageCollectionMetadataKey {
737            id: Some(self.id.into_proto()),
738        }
739    }
740
741    fn from_proto(proto: proto::StorageCollectionMetadataKey) -> Result<Self, TryFromProtoError> {
742        Ok(StorageCollectionMetadataKey {
743            id: proto
744                .id
745                .into_rust_if_some("StorageCollectionMetadataKey::id")?,
746        })
747    }
748}
749
750impl RustType<proto::StorageCollectionMetadataValue> for StorageCollectionMetadataValue {
751    fn into_proto(&self) -> proto::StorageCollectionMetadataValue {
752        proto::StorageCollectionMetadataValue {
753            shard: self.shard.to_string(),
754        }
755    }
756
757    fn from_proto(proto: proto::StorageCollectionMetadataValue) -> Result<Self, TryFromProtoError> {
758        Ok(StorageCollectionMetadataValue {
759            shard: proto.shard.into_rust()?,
760        })
761    }
762}
763
764impl RustType<proto::UnfinalizedShardKey> for UnfinalizedShardKey {
765    fn into_proto(&self) -> proto::UnfinalizedShardKey {
766        proto::UnfinalizedShardKey {
767            shard: self.shard.to_string(),
768        }
769    }
770
771    fn from_proto(proto: proto::UnfinalizedShardKey) -> Result<Self, TryFromProtoError> {
772        Ok(UnfinalizedShardKey {
773            shard: proto.shard.into_rust()?,
774        })
775    }
776}
777
778impl RustType<proto::TxnWalShardValue> for TxnWalShardValue {
779    fn into_proto(&self) -> proto::TxnWalShardValue {
780        proto::TxnWalShardValue {
781            shard: self.shard.to_string(),
782        }
783    }
784
785    fn from_proto(proto: proto::TxnWalShardValue) -> Result<Self, TryFromProtoError> {
786        Ok(TxnWalShardValue {
787            shard: proto.shard.into_rust()?,
788        })
789    }
790}
791
792impl RustType<proto::ServerConfigurationKey> for ServerConfigurationKey {
793    fn into_proto(&self) -> proto::ServerConfigurationKey {
794        proto::ServerConfigurationKey {
795            name: self.name.clone(),
796        }
797    }
798
799    fn from_proto(proto: proto::ServerConfigurationKey) -> Result<Self, TryFromProtoError> {
800        Ok(ServerConfigurationKey { name: proto.name })
801    }
802}
803
804impl RustType<proto::ServerConfigurationValue> for ServerConfigurationValue {
805    fn into_proto(&self) -> proto::ServerConfigurationValue {
806        proto::ServerConfigurationValue {
807            value: self.value.clone(),
808        }
809    }
810
811    fn from_proto(proto: proto::ServerConfigurationValue) -> Result<Self, TryFromProtoError> {
812        Ok(ServerConfigurationValue { value: proto.value })
813    }
814}
815
816impl RustType<proto::SourceReferencesKey> for SourceReferencesKey {
817    fn into_proto(&self) -> proto::SourceReferencesKey {
818        proto::SourceReferencesKey {
819            source: Some(self.source_id.into_proto()),
820        }
821    }
822    fn from_proto(proto: proto::SourceReferencesKey) -> Result<Self, TryFromProtoError> {
823        Ok(SourceReferencesKey {
824            source_id: proto
825                .source
826                .into_rust_if_some("SourceReferencesKey::source_id")?,
827        })
828    }
829}
830
831impl RustType<proto::SourceReferencesValue> for SourceReferencesValue {
832    fn into_proto(&self) -> proto::SourceReferencesValue {
833        proto::SourceReferencesValue {
834            updated_at: Some(proto::EpochMillis {
835                millis: self.updated_at,
836            }),
837            references: self
838                .references
839                .iter()
840                .map(|reference| reference.into_proto())
841                .collect(),
842        }
843    }
844    fn from_proto(proto: proto::SourceReferencesValue) -> Result<Self, TryFromProtoError> {
845        Ok(SourceReferencesValue {
846            updated_at: proto
847                .updated_at
848                .into_rust_if_some("SourceReferencesValue::updated_at")?,
849            references: proto
850                .references
851                .into_iter()
852                .map(|reference| reference.into_rust())
853                .collect::<Result<_, _>>()?,
854        })
855    }
856}
857
858impl RustType<proto::SourceReference> for SourceReference {
859    fn into_proto(&self) -> proto::SourceReference {
860        proto::SourceReference {
861            name: self.name.clone(),
862            namespace: self.namespace.clone(),
863            columns: self.columns.clone(),
864        }
865    }
866    fn from_proto(proto: proto::SourceReference) -> Result<Self, TryFromProtoError> {
867        Ok(SourceReference {
868            name: proto.name,
869            namespace: proto.namespace,
870            columns: proto.columns,
871        })
872    }
873}
874
875impl RustType<proto::DefaultPrivilegesKey> for DefaultPrivilegesKey {
876    fn into_proto(&self) -> proto::DefaultPrivilegesKey {
877        proto::DefaultPrivilegesKey {
878            role_id: Some(self.role_id.into_proto()),
879            database_id: self.database_id.map(|database_id| database_id.into_proto()),
880            schema_id: self.schema_id.map(|schema_id| schema_id.into_proto()),
881            object_type: self.object_type.into_proto().into(),
882            grantee: Some(self.grantee.into_proto()),
883        }
884    }
885
886    fn from_proto(proto: proto::DefaultPrivilegesKey) -> Result<Self, TryFromProtoError> {
887        Ok(DefaultPrivilegesKey {
888            role_id: proto
889                .role_id
890                .into_rust_if_some("DefaultPrivilegesKey::role_id")?,
891            database_id: proto.database_id.into_rust()?,
892            schema_id: proto.schema_id.into_rust()?,
893            object_type: proto::ObjectType::try_from(proto.object_type)
894                .map_err(|_| TryFromProtoError::unknown_enum_variant("ObjectType"))?
895                .into_rust()?,
896            grantee: proto
897                .grantee
898                .into_rust_if_some("DefaultPrivilegesKey::grantee")?,
899        })
900    }
901}
902
903impl RustType<proto::DefaultPrivilegesValue> for DefaultPrivilegesValue {
904    fn into_proto(&self) -> proto::DefaultPrivilegesValue {
905        proto::DefaultPrivilegesValue {
906            privileges: Some(self.privileges.into_proto()),
907        }
908    }
909
910    fn from_proto(proto: proto::DefaultPrivilegesValue) -> Result<Self, TryFromProtoError> {
911        Ok(DefaultPrivilegesValue {
912            privileges: proto
913                .privileges
914                .into_rust_if_some("DefaultPrivilegesValue::privileges")?,
915        })
916    }
917}
918
919impl RustType<proto::SystemPrivilegesKey> for SystemPrivilegesKey {
920    fn into_proto(&self) -> proto::SystemPrivilegesKey {
921        proto::SystemPrivilegesKey {
922            grantee: Some(self.grantee.into_proto()),
923            grantor: Some(self.grantor.into_proto()),
924        }
925    }
926
927    fn from_proto(proto: proto::SystemPrivilegesKey) -> Result<Self, TryFromProtoError> {
928        Ok(SystemPrivilegesKey {
929            grantee: proto
930                .grantee
931                .into_rust_if_some("SystemPrivilegesKey::grantee")?,
932            grantor: proto
933                .grantor
934                .into_rust_if_some("SystemPrivilegesKey::grantor")?,
935        })
936    }
937}
938
939impl RustType<proto::SystemPrivilegesValue> for SystemPrivilegesValue {
940    fn into_proto(&self) -> proto::SystemPrivilegesValue {
941        proto::SystemPrivilegesValue {
942            acl_mode: Some(self.acl_mode.into_proto()),
943        }
944    }
945
946    fn from_proto(proto: proto::SystemPrivilegesValue) -> Result<Self, TryFromProtoError> {
947        Ok(SystemPrivilegesValue {
948            acl_mode: proto
949                .acl_mode
950                .into_rust_if_some("SystemPrivilegesKey::acl_mode")?,
951        })
952    }
953}
954
955impl RustType<proto::SystemCatalogItemId> for SystemCatalogItemId {
956    fn into_proto(&self) -> proto::SystemCatalogItemId {
957        proto::SystemCatalogItemId { value: self.0 }
958    }
959
960    fn from_proto(proto: proto::SystemCatalogItemId) -> Result<Self, TryFromProtoError> {
961        Ok(SystemCatalogItemId(proto.value))
962    }
963}
964
965impl RustType<proto::IntrospectionSourceIndexCatalogItemId>
966    for IntrospectionSourceIndexCatalogItemId
967{
968    fn into_proto(&self) -> proto::IntrospectionSourceIndexCatalogItemId {
969        proto::IntrospectionSourceIndexCatalogItemId { value: self.0 }
970    }
971
972    fn from_proto(
973        proto: proto::IntrospectionSourceIndexCatalogItemId,
974    ) -> Result<Self, TryFromProtoError> {
975        Ok(IntrospectionSourceIndexCatalogItemId(proto.value))
976    }
977}
978
979impl RustType<proto::SystemGlobalId> for SystemGlobalId {
980    fn into_proto(&self) -> proto::SystemGlobalId {
981        proto::SystemGlobalId { value: self.0 }
982    }
983
984    fn from_proto(proto: proto::SystemGlobalId) -> Result<Self, TryFromProtoError> {
985        Ok(SystemGlobalId(proto.value))
986    }
987}
988
989impl RustType<proto::IntrospectionSourceIndexGlobalId> for IntrospectionSourceIndexGlobalId {
990    fn into_proto(&self) -> proto::IntrospectionSourceIndexGlobalId {
991        proto::IntrospectionSourceIndexGlobalId { value: self.0 }
992    }
993
994    fn from_proto(
995        proto: proto::IntrospectionSourceIndexGlobalId,
996    ) -> Result<Self, TryFromProtoError> {
997        Ok(IntrospectionSourceIndexGlobalId(proto.value))
998    }
999}
1000
1001#[cfg(test)]
1002mod tests {
1003    use mz_audit_log::VersionedEvent;
1004    use mz_proto::RustType;
1005    use proptest::prelude::*;
1006
1007    proptest! {
1008        #[mz_ore::test]
1009        #[cfg_attr(miri, ignore)] // slow
1010        fn proptest_audit_log_roundtrips(event: VersionedEvent) {
1011            let proto = event.into_proto();
1012            let roundtrip = VersionedEvent::from_proto(proto).expect("valid proto");
1013
1014            prop_assert_eq!(event, roundtrip);
1015        }
1016    }
1017}