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