Skip to main content

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::TryFromProtoError;
14use mz_repr::ColumnName;
15
16use crate::durable::objects::state_update::StateUpdateKindJson;
17use crate::durable::objects::{
18    AuditLogKey, ClusterIntrospectionSourceIndexKey, ClusterIntrospectionSourceIndexValue,
19    ClusterKey, ClusterReplicaKey, ClusterReplicaSizeKey, ClusterReplicaSizeValue,
20    ClusterReplicaValue, ClusterSystemConfigurationKey, ClusterSystemConfigurationValue,
21    ClusterValue, CommentKey, CommentValue, ConfigKey, ConfigValue, DatabaseKey, DatabaseValue,
22    DefaultPrivilegesKey, DefaultPrivilegesValue, GidMappingKey, GidMappingValue, IdAllocKey,
23    IdAllocValue, IndexColumn, IndexColumnsKey, IndexColumnsValue,
24    IntrospectionSourceIndexCatalogItemId, IntrospectionSourceIndexGlobalId, ItemColumn,
25    ItemColumnsKey, ItemColumnsValue, ItemKey, ItemValue, NetworkPolicyKey, NetworkPolicyValue,
26    ReplicaSystemConfigurationKey, ReplicaSystemConfigurationValue, RoleKey, RoleValue, SchemaKey,
27    SchemaValue, ServerConfigurationKey, ServerConfigurationValue, SettingKey, SettingValue,
28    SourceReference, SourceReferencesKey, SourceReferencesValue, StorageCollectionMetadataKey,
29    StorageCollectionMetadataValue, SystemCatalogItemId, SystemGlobalId, SystemPrivilegesKey,
30    SystemPrivilegesValue, TxnWalShardValue, UnfinalizedShardKey,
31};
32use crate::durable::{
33    BurstState, ClusterConfig, ClusterVariant, ClusterVariantManaged, ReconfigurationState,
34    ReconfigurationStatus, ReconfigurationTarget, ReplicaConfig, ReplicaLocation,
35};
36
37use super::{RoleAuthKey, RoleAuthValue};
38
39mod audit_log;
40mod foreign;
41mod rust_type;
42
43pub use rust_type::{ProtoMapEntry, ProtoType, RustType};
44
45pub mod proto {
46    pub use mz_catalog_protos::objects::*;
47}
48
49impl From<proto::StateUpdateKind> for StateUpdateKindJson {
50    fn from(value: proto::StateUpdateKind) -> Self {
51        StateUpdateKindJson::from_serde(value)
52    }
53}
54
55impl TryFrom<StateUpdateKindJson> for proto::StateUpdateKind {
56    type Error = String;
57
58    fn try_from(value: StateUpdateKindJson) -> Result<Self, Self::Error> {
59        value.try_to_serde::<Self>().map_err(|err| err.to_string())
60    }
61}
62
63impl RustType<proto::ClusterConfig> for ClusterConfig {
64    fn into_proto(&self) -> proto::ClusterConfig {
65        proto::ClusterConfig {
66            variant: self.variant.into_proto(),
67            workload_class: self.workload_class.clone(),
68        }
69    }
70
71    fn from_proto(proto: proto::ClusterConfig) -> Result<Self, TryFromProtoError> {
72        Ok(Self {
73            variant: proto.variant.into_rust()?,
74            workload_class: proto.workload_class,
75        })
76    }
77}
78
79impl RustType<proto::ClusterVariant> for ClusterVariant {
80    fn into_proto(&self) -> proto::ClusterVariant {
81        match self {
82            ClusterVariant::Managed(ClusterVariantManaged {
83                size,
84                availability_zones,
85                logging,
86                arrangement_compression,
87                replication_factor,
88                optimizer_feature_overrides,
89                schedule,
90                auto_scaling_strategy,
91                reconfiguration,
92                burst,
93            }) => proto::ClusterVariant::Managed(proto::ManagedCluster {
94                size: size.to_string(),
95                availability_zones: availability_zones.clone(),
96                logging: logging.into_proto(),
97                arrangement_compression: *arrangement_compression,
98                replication_factor: *replication_factor,
99                optimizer_feature_overrides: optimizer_feature_overrides.into_proto(),
100                schedule: schedule.into_proto(),
101                auto_scaling_strategy: auto_scaling_strategy.into_proto(),
102                reconfiguration: reconfiguration.into_proto(),
103                burst: burst.into_proto(),
104            }),
105            ClusterVariant::Unmanaged => proto::ClusterVariant::Unmanaged,
106        }
107    }
108
109    fn from_proto(proto: proto::ClusterVariant) -> Result<Self, TryFromProtoError> {
110        match proto {
111            proto::ClusterVariant::Unmanaged => Ok(Self::Unmanaged),
112            proto::ClusterVariant::Managed(managed) => Ok(Self::Managed(ClusterVariantManaged {
113                size: managed.size,
114                availability_zones: managed.availability_zones,
115                logging: managed.logging.into_rust()?,
116                arrangement_compression: managed.arrangement_compression,
117                replication_factor: managed.replication_factor,
118                optimizer_feature_overrides: managed.optimizer_feature_overrides.into_rust()?,
119                schedule: managed.schedule.into_rust()?,
120                auto_scaling_strategy: managed.auto_scaling_strategy.into_rust()?,
121                reconfiguration: managed.reconfiguration.into_rust()?,
122                burst: managed.burst.into_rust()?,
123            })),
124        }
125    }
126}
127
128impl RustType<proto::ReconfigurationState> for ReconfigurationState {
129    fn into_proto(&self) -> proto::ReconfigurationState {
130        proto::ReconfigurationState {
131            target: self.target.into_proto(),
132            deadline: self.deadline.into(),
133            on_timeout: self.on_timeout.into_proto(),
134            status: self.status.into_proto(),
135        }
136    }
137
138    fn from_proto(proto: proto::ReconfigurationState) -> Result<Self, TryFromProtoError> {
139        Ok(Self {
140            target: proto.target.into_rust()?,
141            deadline: mz_repr::Timestamp::new(proto.deadline),
142            on_timeout: proto.on_timeout.into_rust()?,
143            status: proto.status.into_rust()?,
144        })
145    }
146}
147
148impl RustType<proto::ReconfigurationStatus> for ReconfigurationStatus {
149    fn into_proto(&self) -> proto::ReconfigurationStatus {
150        match self {
151            ReconfigurationStatus::InProgress => proto::ReconfigurationStatus::InProgress,
152            ReconfigurationStatus::Finalized => proto::ReconfigurationStatus::Finalized,
153            ReconfigurationStatus::TimedOut => proto::ReconfigurationStatus::TimedOut,
154            ReconfigurationStatus::Cancelled => proto::ReconfigurationStatus::Cancelled,
155            ReconfigurationStatus::ResourceExhausted => {
156                proto::ReconfigurationStatus::ResourceExhausted
157            }
158        }
159    }
160
161    fn from_proto(proto: proto::ReconfigurationStatus) -> Result<Self, TryFromProtoError> {
162        Ok(match proto {
163            proto::ReconfigurationStatus::InProgress => ReconfigurationStatus::InProgress,
164            proto::ReconfigurationStatus::Finalized => ReconfigurationStatus::Finalized,
165            proto::ReconfigurationStatus::TimedOut => ReconfigurationStatus::TimedOut,
166            proto::ReconfigurationStatus::Cancelled => ReconfigurationStatus::Cancelled,
167            proto::ReconfigurationStatus::ResourceExhausted => {
168                ReconfigurationStatus::ResourceExhausted
169            }
170        })
171    }
172}
173
174impl RustType<proto::ReconfigurationTarget> for ReconfigurationTarget {
175    fn into_proto(&self) -> proto::ReconfigurationTarget {
176        proto::ReconfigurationTarget {
177            size: self.size.clone(),
178            replication_factor: self.replication_factor,
179            availability_zones: self.availability_zones.clone(),
180            logging: self.logging.into_proto(),
181            arrangement_compression: self.arrangement_compression,
182        }
183    }
184
185    fn from_proto(proto: proto::ReconfigurationTarget) -> Result<Self, TryFromProtoError> {
186        Ok(Self {
187            size: proto.size,
188            replication_factor: proto.replication_factor,
189            availability_zones: proto.availability_zones,
190            logging: proto.logging.into_rust()?,
191            arrangement_compression: proto.arrangement_compression,
192        })
193    }
194}
195
196impl RustType<proto::BurstState> for BurstState {
197    fn into_proto(&self) -> proto::BurstState {
198        proto::BurstState {
199            burst_size: self.burst_size.clone(),
200            linger_duration: self.linger_duration.into_proto(),
201            steady_ready_at: self.steady_ready_at.map(Into::into),
202        }
203    }
204
205    fn from_proto(proto: proto::BurstState) -> Result<Self, TryFromProtoError> {
206        Ok(Self {
207            burst_size: proto.burst_size,
208            linger_duration: proto.linger_duration.into_rust()?,
209            steady_ready_at: proto.steady_ready_at.map(mz_repr::Timestamp::new),
210        })
211    }
212}
213
214impl RustType<proto::ReplicaConfig> for ReplicaConfig {
215    fn into_proto(&self) -> proto::ReplicaConfig {
216        proto::ReplicaConfig {
217            logging: self.logging.into_proto(),
218            location: self.location.into_proto(),
219            arrangement_compression: self.arrangement_compression,
220        }
221    }
222
223    fn from_proto(proto: proto::ReplicaConfig) -> Result<Self, TryFromProtoError> {
224        Ok(ReplicaConfig {
225            location: proto.location.into_rust()?,
226            logging: proto.logging.into_rust()?,
227            arrangement_compression: proto.arrangement_compression,
228        })
229    }
230}
231
232impl RustType<proto::ReplicaLocation> for ReplicaLocation {
233    fn into_proto(&self) -> proto::ReplicaLocation {
234        match self {
235            ReplicaLocation::Unmanaged {
236                storagectl_addrs,
237                computectl_addrs,
238            } => proto::ReplicaLocation::Unmanaged(proto::UnmanagedLocation {
239                storagectl_addrs: storagectl_addrs.clone(),
240                computectl_addrs: computectl_addrs.clone(),
241            }),
242            ReplicaLocation::Managed {
243                size,
244                availability_zones,
245                billed_as,
246                internal,
247                pending,
248            } => proto::ReplicaLocation::Managed(proto::ManagedLocation {
249                size: size.to_string(),
250                availability_zones: availability_zones.clone(),
251                billed_as: billed_as.clone(),
252                internal: *internal,
253                pending: *pending,
254            }),
255        }
256    }
257
258    fn from_proto(proto: proto::ReplicaLocation) -> Result<Self, TryFromProtoError> {
259        match proto {
260            proto::ReplicaLocation::Unmanaged(location) => Ok(ReplicaLocation::Unmanaged {
261                storagectl_addrs: location.storagectl_addrs,
262                computectl_addrs: location.computectl_addrs,
263            }),
264            proto::ReplicaLocation::Managed(location) => Ok(ReplicaLocation::Managed {
265                availability_zones: location.availability_zones,
266                billed_as: location.billed_as,
267                internal: location.internal,
268                size: location.size,
269                pending: location.pending,
270            }),
271        }
272    }
273}
274
275impl RustType<proto::SettingKey> for SettingKey {
276    fn into_proto(&self) -> proto::SettingKey {
277        proto::SettingKey {
278            name: self.name.to_string(),
279        }
280    }
281
282    fn from_proto(proto: proto::SettingKey) -> Result<Self, TryFromProtoError> {
283        Ok(SettingKey { name: proto.name })
284    }
285}
286
287impl RustType<proto::SettingValue> for SettingValue {
288    fn into_proto(&self) -> proto::SettingValue {
289        proto::SettingValue {
290            value: self.value.to_string(),
291        }
292    }
293
294    fn from_proto(proto: proto::SettingValue) -> Result<Self, TryFromProtoError> {
295        Ok(SettingValue { value: proto.value })
296    }
297}
298
299impl RustType<proto::IdAllocKey> for IdAllocKey {
300    fn into_proto(&self) -> proto::IdAllocKey {
301        proto::IdAllocKey {
302            name: self.name.to_string(),
303        }
304    }
305
306    fn from_proto(proto: proto::IdAllocKey) -> Result<Self, TryFromProtoError> {
307        Ok(IdAllocKey { name: proto.name })
308    }
309}
310
311impl RustType<proto::IdAllocValue> for IdAllocValue {
312    fn into_proto(&self) -> proto::IdAllocValue {
313        proto::IdAllocValue {
314            next_id: self.next_id,
315        }
316    }
317
318    fn from_proto(proto: proto::IdAllocValue) -> Result<Self, TryFromProtoError> {
319        Ok(IdAllocValue {
320            next_id: proto.next_id,
321        })
322    }
323}
324
325impl RustType<proto::GidMappingKey> for GidMappingKey {
326    fn into_proto(&self) -> proto::GidMappingKey {
327        proto::GidMappingKey {
328            schema_name: self.schema_name.to_string(),
329            object_type: self.object_type.into_proto(),
330            object_name: self.object_name.to_string(),
331        }
332    }
333
334    fn from_proto(proto: proto::GidMappingKey) -> Result<Self, TryFromProtoError> {
335        Ok(GidMappingKey {
336            schema_name: proto.schema_name,
337            object_type: proto.object_type.into_rust()?,
338            object_name: proto.object_name,
339        })
340    }
341}
342
343impl RustType<proto::GidMappingValue> for GidMappingValue {
344    fn into_proto(&self) -> proto::GidMappingValue {
345        proto::GidMappingValue {
346            catalog_id: self.catalog_id.into_proto(),
347            global_id: self.global_id.into_proto(),
348            fingerprint: self.fingerprint.to_string(),
349        }
350    }
351
352    fn from_proto(proto: proto::GidMappingValue) -> Result<Self, TryFromProtoError> {
353        Ok(GidMappingValue {
354            catalog_id: proto.catalog_id.into_rust()?,
355            global_id: proto.global_id.into_rust()?,
356            fingerprint: proto.fingerprint,
357        })
358    }
359}
360
361impl RustType<proto::ClusterKey> for ClusterKey {
362    fn into_proto(&self) -> proto::ClusterKey {
363        proto::ClusterKey {
364            id: self.id.into_proto(),
365        }
366    }
367
368    fn from_proto(proto: proto::ClusterKey) -> Result<Self, TryFromProtoError> {
369        Ok(ClusterKey {
370            id: proto.id.into_rust()?,
371        })
372    }
373}
374
375impl RustType<proto::ClusterValue> for ClusterValue {
376    fn into_proto(&self) -> proto::ClusterValue {
377        proto::ClusterValue {
378            name: self.name.to_string(),
379            config: self.config.into_proto(),
380            owner_id: self.owner_id.into_proto(),
381            privileges: self.privileges.into_proto(),
382        }
383    }
384
385    fn from_proto(proto: proto::ClusterValue) -> Result<Self, TryFromProtoError> {
386        Ok(ClusterValue {
387            name: proto.name,
388            config: proto.config.into_rust()?,
389            owner_id: proto.owner_id.into_rust()?,
390            privileges: proto.privileges.into_rust()?,
391        })
392    }
393}
394
395impl RustType<proto::ClusterIntrospectionSourceIndexKey> for ClusterIntrospectionSourceIndexKey {
396    fn into_proto(&self) -> proto::ClusterIntrospectionSourceIndexKey {
397        proto::ClusterIntrospectionSourceIndexKey {
398            cluster_id: self.cluster_id.into_proto(),
399            name: self.name.to_string(),
400        }
401    }
402
403    fn from_proto(
404        proto: proto::ClusterIntrospectionSourceIndexKey,
405    ) -> Result<Self, TryFromProtoError> {
406        Ok(ClusterIntrospectionSourceIndexKey {
407            cluster_id: proto.cluster_id.into_rust()?,
408            name: proto.name,
409        })
410    }
411}
412
413impl RustType<proto::ClusterIntrospectionSourceIndexValue>
414    for ClusterIntrospectionSourceIndexValue
415{
416    fn into_proto(&self) -> proto::ClusterIntrospectionSourceIndexValue {
417        proto::ClusterIntrospectionSourceIndexValue {
418            catalog_id: self.catalog_id.into_proto(),
419            global_id: self.global_id.into_proto(),
420            oid: self.oid,
421        }
422    }
423
424    fn from_proto(
425        proto: proto::ClusterIntrospectionSourceIndexValue,
426    ) -> Result<Self, TryFromProtoError> {
427        Ok(ClusterIntrospectionSourceIndexValue {
428            catalog_id: proto.catalog_id.into_rust()?,
429            global_id: proto.global_id.into_rust()?,
430            oid: proto.oid,
431        })
432    }
433}
434
435impl RustType<proto::ClusterReplicaKey> for ClusterReplicaKey {
436    fn into_proto(&self) -> proto::ClusterReplicaKey {
437        proto::ClusterReplicaKey {
438            id: self.id.into_proto(),
439        }
440    }
441
442    fn from_proto(proto: proto::ClusterReplicaKey) -> Result<Self, TryFromProtoError> {
443        Ok(ClusterReplicaKey {
444            id: proto.id.into_rust()?,
445        })
446    }
447}
448
449impl RustType<proto::ClusterReplicaValue> for ClusterReplicaValue {
450    fn into_proto(&self) -> proto::ClusterReplicaValue {
451        proto::ClusterReplicaValue {
452            cluster_id: self.cluster_id.into_proto(),
453            name: self.name.to_string(),
454            config: self.config.into_proto(),
455            owner_id: self.owner_id.into_proto(),
456        }
457    }
458
459    fn from_proto(proto: proto::ClusterReplicaValue) -> Result<Self, TryFromProtoError> {
460        Ok(ClusterReplicaValue {
461            cluster_id: proto.cluster_id.into_rust()?,
462            name: proto.name,
463            config: proto.config.into_rust()?,
464            owner_id: proto.owner_id.into_rust()?,
465        })
466    }
467}
468
469impl RustType<proto::DatabaseKey> for DatabaseKey {
470    fn into_proto(&self) -> proto::DatabaseKey {
471        proto::DatabaseKey {
472            id: self.id.into_proto(),
473        }
474    }
475
476    fn from_proto(proto: proto::DatabaseKey) -> Result<Self, TryFromProtoError> {
477        Ok(DatabaseKey {
478            id: proto.id.into_rust()?,
479        })
480    }
481}
482
483impl RustType<proto::DatabaseValue> for DatabaseValue {
484    fn into_proto(&self) -> proto::DatabaseValue {
485        proto::DatabaseValue {
486            name: self.name.clone(),
487            owner_id: self.owner_id.into_proto(),
488            privileges: self.privileges.into_proto(),
489            oid: self.oid,
490        }
491    }
492
493    fn from_proto(proto: proto::DatabaseValue) -> Result<Self, TryFromProtoError> {
494        Ok(DatabaseValue {
495            name: proto.name,
496            owner_id: proto.owner_id.into_rust()?,
497            privileges: proto.privileges.into_rust()?,
498            oid: proto.oid,
499        })
500    }
501}
502
503impl RustType<proto::SchemaKey> for SchemaKey {
504    fn into_proto(&self) -> proto::SchemaKey {
505        proto::SchemaKey {
506            id: self.id.into_proto(),
507        }
508    }
509
510    fn from_proto(proto: proto::SchemaKey) -> Result<Self, TryFromProtoError> {
511        Ok(SchemaKey {
512            id: proto.id.into_rust()?,
513        })
514    }
515}
516
517impl RustType<proto::SchemaValue> for SchemaValue {
518    fn into_proto(&self) -> proto::SchemaValue {
519        proto::SchemaValue {
520            name: self.name.clone(),
521            database_id: self.database_id.map(|id| id.into_proto()),
522            owner_id: self.owner_id.into_proto(),
523            privileges: self.privileges.into_proto(),
524            oid: self.oid,
525        }
526    }
527
528    fn from_proto(proto: proto::SchemaValue) -> Result<Self, TryFromProtoError> {
529        Ok(SchemaValue {
530            name: proto.name,
531            database_id: proto.database_id.into_rust()?,
532            owner_id: proto.owner_id.into_rust()?,
533            privileges: proto.privileges.into_rust()?,
534            oid: proto.oid,
535        })
536    }
537}
538
539impl RustType<proto::ItemKey> for ItemKey {
540    fn into_proto(&self) -> proto::ItemKey {
541        proto::ItemKey {
542            gid: self.id.into_proto(),
543        }
544    }
545
546    fn from_proto(proto: proto::ItemKey) -> Result<Self, TryFromProtoError> {
547        Ok(ItemKey {
548            id: proto.gid.into_rust()?,
549        })
550    }
551}
552
553impl RustType<proto::ItemValue> for ItemValue {
554    fn into_proto(&self) -> proto::ItemValue {
555        let definition = proto::CatalogItem::V1(proto::CatalogItemV1 {
556            create_sql: self.create_sql.clone(),
557        });
558        proto::ItemValue {
559            schema_id: self.schema_id.into_proto(),
560            name: self.name.to_string(),
561            definition,
562            owner_id: self.owner_id.into_proto(),
563            privileges: self.privileges.into_proto(),
564            oid: self.oid,
565            global_id: self.global_id.into_proto(),
566            extra_versions: self
567                .extra_versions
568                .iter()
569                .map(|(version, global_id)| proto::ItemVersion {
570                    global_id: global_id.into_proto(),
571                    version: version.into_proto(),
572                })
573                .collect(),
574            ephemeral_owner_session: self.ephemeral_owner_session,
575        }
576    }
577
578    fn from_proto(proto: proto::ItemValue) -> Result<Self, TryFromProtoError> {
579        let create_sql = match proto.definition {
580            proto::CatalogItem::V1(c) => c.create_sql,
581        };
582        let extra_versions = proto
583            .extra_versions
584            .into_iter()
585            .map(|item_version| {
586                let version = item_version.version.into_rust()?;
587                let global_id = item_version.global_id.into_rust()?;
588                Ok::<_, TryFromProtoError>((version, global_id))
589            })
590            .collect::<Result<_, _>>()?;
591        Ok(ItemValue {
592            schema_id: proto.schema_id.into_rust()?,
593            name: proto.name,
594            create_sql,
595            owner_id: proto.owner_id.into_rust()?,
596            privileges: proto.privileges.into_rust()?,
597            oid: proto.oid,
598            global_id: proto.global_id.into_rust()?,
599            extra_versions,
600            ephemeral_owner_session: proto.ephemeral_owner_session,
601        })
602    }
603}
604
605impl RustType<proto::ItemColumnsKey> for ItemColumnsKey {
606    fn into_proto(&self) -> proto::ItemColumnsKey {
607        proto::ItemColumnsKey {
608            id: self.id.into_proto(),
609        }
610    }
611
612    fn from_proto(proto: proto::ItemColumnsKey) -> Result<Self, TryFromProtoError> {
613        Ok(ItemColumnsKey {
614            id: proto.id.into_rust()?,
615        })
616    }
617}
618
619impl RustType<proto::ItemColumnsValue> for ItemColumnsValue {
620    fn into_proto(&self) -> proto::ItemColumnsValue {
621        proto::ItemColumnsValue {
622            columns: self.columns.into_proto(),
623        }
624    }
625
626    fn from_proto(proto: proto::ItemColumnsValue) -> Result<Self, TryFromProtoError> {
627        Ok(ItemColumnsValue {
628            columns: proto.columns.into_rust()?,
629        })
630    }
631}
632
633impl RustType<proto::ItemColumn> for ItemColumn {
634    fn into_proto(&self) -> proto::ItemColumn {
635        proto::ItemColumn {
636            name: self.name.to_string(),
637            nullable: self.nullable,
638            type_oid: self.type_oid,
639            type_mod: self.type_mod,
640            custom_type: self.custom_type.into_proto(),
641        }
642    }
643
644    fn from_proto(proto: proto::ItemColumn) -> Result<Self, TryFromProtoError> {
645        Ok(ItemColumn {
646            name: ColumnName::from(proto.name),
647            nullable: proto.nullable,
648            type_oid: proto.type_oid,
649            type_mod: proto.type_mod,
650            custom_type: proto.custom_type.into_rust()?,
651        })
652    }
653}
654
655impl RustType<proto::IndexColumnsKey> for IndexColumnsKey {
656    fn into_proto(&self) -> proto::IndexColumnsKey {
657        proto::IndexColumnsKey {
658            id: self.id.into_proto(),
659        }
660    }
661
662    fn from_proto(proto: proto::IndexColumnsKey) -> Result<Self, TryFromProtoError> {
663        Ok(IndexColumnsKey {
664            id: proto.id.into_rust()?,
665        })
666    }
667}
668
669impl RustType<proto::IndexColumnsValue> for IndexColumnsValue {
670    fn into_proto(&self) -> proto::IndexColumnsValue {
671        proto::IndexColumnsValue {
672            columns: self.columns.into_proto(),
673        }
674    }
675
676    fn from_proto(proto: proto::IndexColumnsValue) -> Result<Self, TryFromProtoError> {
677        Ok(IndexColumnsValue {
678            columns: proto.columns.into_rust()?,
679        })
680    }
681}
682
683impl RustType<proto::IndexColumn> for IndexColumn {
684    fn into_proto(&self) -> proto::IndexColumn {
685        proto::IndexColumn {
686            column: self.column.map(u64::cast_from),
687            nullable: self.nullable,
688        }
689    }
690
691    fn from_proto(proto: proto::IndexColumn) -> Result<Self, TryFromProtoError> {
692        Ok(IndexColumn {
693            column: proto.column.map(usize::cast_from),
694            nullable: proto.nullable,
695        })
696    }
697}
698
699impl RustType<proto::CommentKey> for CommentKey {
700    fn into_proto(&self) -> proto::CommentKey {
701        let sub_component = match &self.sub_component {
702            Some(pos) => Some(proto::CommentSubComponent::ColumnPos(CastFrom::cast_from(
703                *pos,
704            ))),
705            None => None,
706        };
707        proto::CommentKey {
708            object: self.object_id.into_proto(),
709            sub_component,
710        }
711    }
712
713    fn from_proto(proto: proto::CommentKey) -> Result<Self, TryFromProtoError> {
714        let sub_component = match proto.sub_component {
715            Some(proto::CommentSubComponent::ColumnPos(pos)) => Some(CastFrom::cast_from(pos)),
716            None => None,
717        };
718        Ok(CommentKey {
719            object_id: proto.object.into_rust()?,
720            sub_component,
721        })
722    }
723}
724
725impl RustType<proto::CommentValue> for CommentValue {
726    fn into_proto(&self) -> proto::CommentValue {
727        proto::CommentValue {
728            comment: self.comment.clone(),
729        }
730    }
731
732    fn from_proto(proto: proto::CommentValue) -> Result<Self, TryFromProtoError> {
733        Ok(CommentValue {
734            comment: proto.comment,
735        })
736    }
737}
738
739impl RustType<proto::RoleKey> for RoleKey {
740    fn into_proto(&self) -> proto::RoleKey {
741        proto::RoleKey {
742            id: self.id.into_proto(),
743        }
744    }
745
746    fn from_proto(proto: proto::RoleKey) -> Result<Self, TryFromProtoError> {
747        Ok(RoleKey {
748            id: proto.id.into_rust()?,
749        })
750    }
751}
752
753impl RustType<proto::RoleValue> for RoleValue {
754    fn into_proto(&self) -> proto::RoleValue {
755        proto::RoleValue {
756            name: self.name.to_string(),
757            attributes: self.attributes.into_proto(),
758            membership: self.membership.into_proto(),
759            vars: self.vars.into_proto(),
760            oid: self.oid,
761        }
762    }
763
764    fn from_proto(proto: proto::RoleValue) -> Result<Self, TryFromProtoError> {
765        Ok(RoleValue {
766            name: proto.name,
767            attributes: proto.attributes.into_rust()?,
768            membership: proto.membership.into_rust()?,
769            vars: proto.vars.into_rust()?,
770            oid: proto.oid,
771        })
772    }
773}
774
775impl RustType<proto::RoleAuthKey> for RoleAuthKey {
776    fn into_proto(&self) -> proto::RoleAuthKey {
777        proto::RoleAuthKey {
778            id: self.role_id.into_proto(),
779        }
780    }
781
782    fn from_proto(proto: proto::RoleAuthKey) -> Result<Self, TryFromProtoError> {
783        Ok(RoleAuthKey {
784            role_id: proto.id.into_rust()?,
785        })
786    }
787}
788
789impl RustType<proto::RoleAuthValue> for RoleAuthValue {
790    fn into_proto(&self) -> proto::RoleAuthValue {
791        proto::RoleAuthValue {
792            password_hash: self.password_hash.clone(),
793            updated_at: proto::EpochMillis {
794                millis: self.updated_at,
795            },
796        }
797    }
798
799    fn from_proto(proto: proto::RoleAuthValue) -> Result<Self, TryFromProtoError> {
800        Ok(RoleAuthValue {
801            password_hash: proto.password_hash,
802            updated_at: proto.updated_at.into_rust()?,
803        })
804    }
805}
806
807impl RustType<proto::NetworkPolicyKey> for NetworkPolicyKey {
808    fn into_proto(&self) -> proto::NetworkPolicyKey {
809        proto::NetworkPolicyKey {
810            id: self.id.into_proto(),
811        }
812    }
813
814    fn from_proto(proto: proto::NetworkPolicyKey) -> Result<Self, TryFromProtoError> {
815        Ok(NetworkPolicyKey {
816            id: proto.id.into_rust()?,
817        })
818    }
819}
820
821impl RustType<proto::NetworkPolicyValue> for NetworkPolicyValue {
822    fn into_proto(&self) -> proto::NetworkPolicyValue {
823        proto::NetworkPolicyValue {
824            name: self.name.to_string(),
825            rules: self.rules.into_proto(),
826            owner_id: self.owner_id.into_proto(),
827            privileges: self.privileges.into_proto(),
828            oid: self.oid,
829        }
830    }
831
832    fn from_proto(proto: proto::NetworkPolicyValue) -> Result<Self, TryFromProtoError> {
833        Ok(NetworkPolicyValue {
834            name: proto.name,
835            rules: proto.rules.into_rust()?,
836            owner_id: proto.owner_id.into_rust()?,
837            privileges: proto.privileges.into_rust()?,
838            oid: proto.oid,
839        })
840    }
841}
842
843impl RustType<proto::ClusterReplicaSizeKey> for ClusterReplicaSizeKey {
844    fn into_proto(&self) -> proto::ClusterReplicaSizeKey {
845        proto::ClusterReplicaSizeKey {
846            id: self.id.into_proto(),
847        }
848    }
849
850    fn from_proto(proto: proto::ClusterReplicaSizeKey) -> Result<Self, TryFromProtoError> {
851        Ok(ClusterReplicaSizeKey {
852            id: proto.id.into_rust()?,
853        })
854    }
855}
856
857impl RustType<proto::ClusterReplicaSizeValue> for ClusterReplicaSizeValue {
858    fn into_proto(&self) -> proto::ClusterReplicaSizeValue {
859        proto::ClusterReplicaSizeValue {
860            name: self.name.clone(),
861            memory_limit: self.memory_limit,
862            cpu_limit: self.cpu_limit,
863            cpu_request: self.cpu_request,
864            disk_limit: self.disk_limit,
865            scale: self.scale,
866            workers: self.workers,
867            credits_per_hour: self.credits_per_hour.clone(),
868            cpu_exclusive: self.cpu_exclusive,
869            is_cc: self.is_cc,
870            family: self.family.clone(),
871            swap_enabled: self.swap_enabled,
872            disabled: self.disabled,
873            selectors: self.selectors.clone(),
874        }
875    }
876
877    fn from_proto(proto: proto::ClusterReplicaSizeValue) -> Result<Self, TryFromProtoError> {
878        Ok(ClusterReplicaSizeValue {
879            name: proto.name,
880            memory_limit: proto.memory_limit,
881            cpu_limit: proto.cpu_limit,
882            cpu_request: proto.cpu_request,
883            disk_limit: proto.disk_limit,
884            scale: proto.scale,
885            workers: proto.workers,
886            credits_per_hour: proto.credits_per_hour,
887            cpu_exclusive: proto.cpu_exclusive,
888            is_cc: proto.is_cc,
889            family: proto.family,
890            swap_enabled: proto.swap_enabled,
891            disabled: proto.disabled,
892            selectors: proto.selectors,
893        })
894    }
895}
896
897impl RustType<proto::ConfigKey> for ConfigKey {
898    fn into_proto(&self) -> proto::ConfigKey {
899        proto::ConfigKey {
900            key: self.key.to_string(),
901        }
902    }
903
904    fn from_proto(proto: proto::ConfigKey) -> Result<Self, TryFromProtoError> {
905        Ok(ConfigKey { key: proto.key })
906    }
907}
908
909impl RustType<proto::ConfigValue> for ConfigValue {
910    fn into_proto(&self) -> proto::ConfigValue {
911        proto::ConfigValue { value: self.value }
912    }
913
914    fn from_proto(proto: proto::ConfigValue) -> Result<Self, TryFromProtoError> {
915        Ok(ConfigValue { value: proto.value })
916    }
917}
918
919impl RustType<proto::AuditLogKey> for AuditLogKey {
920    fn into_proto(&self) -> proto::AuditLogKey {
921        proto::AuditLogKey {
922            event: self.event.into_proto(),
923        }
924    }
925
926    fn from_proto(proto: proto::AuditLogKey) -> Result<Self, TryFromProtoError> {
927        Ok(AuditLogKey {
928            event: proto.event.into_rust()?,
929        })
930    }
931}
932
933impl RustType<proto::StorageCollectionMetadataKey> for StorageCollectionMetadataKey {
934    fn into_proto(&self) -> proto::StorageCollectionMetadataKey {
935        proto::StorageCollectionMetadataKey {
936            id: self.id.into_proto(),
937        }
938    }
939
940    fn from_proto(proto: proto::StorageCollectionMetadataKey) -> Result<Self, TryFromProtoError> {
941        Ok(StorageCollectionMetadataKey {
942            id: proto.id.into_rust()?,
943        })
944    }
945}
946
947impl RustType<proto::StorageCollectionMetadataValue> for StorageCollectionMetadataValue {
948    fn into_proto(&self) -> proto::StorageCollectionMetadataValue {
949        proto::StorageCollectionMetadataValue {
950            shard: self.shard.to_string(),
951        }
952    }
953
954    fn from_proto(proto: proto::StorageCollectionMetadataValue) -> Result<Self, TryFromProtoError> {
955        Ok(StorageCollectionMetadataValue {
956            shard: proto.shard.into_rust()?,
957        })
958    }
959}
960
961impl RustType<proto::UnfinalizedShardKey> for UnfinalizedShardKey {
962    fn into_proto(&self) -> proto::UnfinalizedShardKey {
963        proto::UnfinalizedShardKey {
964            shard: self.shard.to_string(),
965        }
966    }
967
968    fn from_proto(proto: proto::UnfinalizedShardKey) -> Result<Self, TryFromProtoError> {
969        Ok(UnfinalizedShardKey {
970            shard: proto.shard.into_rust()?,
971        })
972    }
973}
974
975impl RustType<proto::TxnWalShardValue> for TxnWalShardValue {
976    fn into_proto(&self) -> proto::TxnWalShardValue {
977        proto::TxnWalShardValue {
978            shard: self.shard.to_string(),
979        }
980    }
981
982    fn from_proto(proto: proto::TxnWalShardValue) -> Result<Self, TryFromProtoError> {
983        Ok(TxnWalShardValue {
984            shard: proto.shard.into_rust()?,
985        })
986    }
987}
988
989impl RustType<proto::ServerConfigurationKey> for ServerConfigurationKey {
990    fn into_proto(&self) -> proto::ServerConfigurationKey {
991        proto::ServerConfigurationKey {
992            name: self.name.clone(),
993        }
994    }
995
996    fn from_proto(proto: proto::ServerConfigurationKey) -> Result<Self, TryFromProtoError> {
997        Ok(ServerConfigurationKey { name: proto.name })
998    }
999}
1000
1001impl RustType<proto::ServerConfigurationValue> for ServerConfigurationValue {
1002    fn into_proto(&self) -> proto::ServerConfigurationValue {
1003        proto::ServerConfigurationValue {
1004            value: self.value.clone(),
1005        }
1006    }
1007
1008    fn from_proto(proto: proto::ServerConfigurationValue) -> Result<Self, TryFromProtoError> {
1009        Ok(ServerConfigurationValue { value: proto.value })
1010    }
1011}
1012
1013impl RustType<proto::ClusterSystemConfigurationKey> for ClusterSystemConfigurationKey {
1014    fn into_proto(&self) -> proto::ClusterSystemConfigurationKey {
1015        proto::ClusterSystemConfigurationKey {
1016            cluster_id: self.cluster_id.into_proto(),
1017            name: self.name.clone(),
1018        }
1019    }
1020
1021    fn from_proto(proto: proto::ClusterSystemConfigurationKey) -> Result<Self, TryFromProtoError> {
1022        Ok(ClusterSystemConfigurationKey {
1023            cluster_id: proto.cluster_id.into_rust()?,
1024            name: proto.name,
1025        })
1026    }
1027}
1028
1029impl RustType<proto::ClusterSystemConfigurationValue> for ClusterSystemConfigurationValue {
1030    fn into_proto(&self) -> proto::ClusterSystemConfigurationValue {
1031        proto::ClusterSystemConfigurationValue {
1032            value: self.value.clone(),
1033        }
1034    }
1035
1036    fn from_proto(
1037        proto: proto::ClusterSystemConfigurationValue,
1038    ) -> Result<Self, TryFromProtoError> {
1039        Ok(ClusterSystemConfigurationValue { value: proto.value })
1040    }
1041}
1042
1043impl RustType<proto::ReplicaSystemConfigurationKey> for ReplicaSystemConfigurationKey {
1044    fn into_proto(&self) -> proto::ReplicaSystemConfigurationKey {
1045        proto::ReplicaSystemConfigurationKey {
1046            replica_id: self.replica_id.into_proto(),
1047            name: self.name.clone(),
1048        }
1049    }
1050
1051    fn from_proto(proto: proto::ReplicaSystemConfigurationKey) -> Result<Self, TryFromProtoError> {
1052        Ok(ReplicaSystemConfigurationKey {
1053            replica_id: proto.replica_id.into_rust()?,
1054            name: proto.name,
1055        })
1056    }
1057}
1058
1059impl RustType<proto::ReplicaSystemConfigurationValue> for ReplicaSystemConfigurationValue {
1060    fn into_proto(&self) -> proto::ReplicaSystemConfigurationValue {
1061        proto::ReplicaSystemConfigurationValue {
1062            value: self.value.clone(),
1063        }
1064    }
1065
1066    fn from_proto(
1067        proto: proto::ReplicaSystemConfigurationValue,
1068    ) -> Result<Self, TryFromProtoError> {
1069        Ok(ReplicaSystemConfigurationValue { value: proto.value })
1070    }
1071}
1072
1073impl RustType<proto::SourceReferencesKey> for SourceReferencesKey {
1074    fn into_proto(&self) -> proto::SourceReferencesKey {
1075        proto::SourceReferencesKey {
1076            source: self.source_id.into_proto(),
1077        }
1078    }
1079    fn from_proto(proto: proto::SourceReferencesKey) -> Result<Self, TryFromProtoError> {
1080        Ok(SourceReferencesKey {
1081            source_id: proto.source.into_rust()?,
1082        })
1083    }
1084}
1085
1086impl RustType<proto::SourceReferencesValue> for SourceReferencesValue {
1087    fn into_proto(&self) -> proto::SourceReferencesValue {
1088        proto::SourceReferencesValue {
1089            updated_at: proto::EpochMillis {
1090                millis: self.updated_at,
1091            },
1092            references: self
1093                .references
1094                .iter()
1095                .map(|reference| reference.into_proto())
1096                .collect(),
1097        }
1098    }
1099    fn from_proto(proto: proto::SourceReferencesValue) -> Result<Self, TryFromProtoError> {
1100        Ok(SourceReferencesValue {
1101            updated_at: proto.updated_at.into_rust()?,
1102            references: proto
1103                .references
1104                .into_iter()
1105                .map(|reference| reference.into_rust())
1106                .collect::<Result<_, _>>()?,
1107        })
1108    }
1109}
1110
1111impl RustType<proto::SourceReference> for SourceReference {
1112    fn into_proto(&self) -> proto::SourceReference {
1113        proto::SourceReference {
1114            name: self.name.clone(),
1115            namespace: self.namespace.clone(),
1116            columns: self.columns.clone(),
1117        }
1118    }
1119    fn from_proto(proto: proto::SourceReference) -> Result<Self, TryFromProtoError> {
1120        Ok(SourceReference {
1121            name: proto.name,
1122            namespace: proto.namespace,
1123            columns: proto.columns,
1124        })
1125    }
1126}
1127
1128impl RustType<proto::DefaultPrivilegesKey> for DefaultPrivilegesKey {
1129    fn into_proto(&self) -> proto::DefaultPrivilegesKey {
1130        proto::DefaultPrivilegesKey {
1131            role_id: self.role_id.into_proto(),
1132            database_id: self.database_id.map(|database_id| database_id.into_proto()),
1133            schema_id: self.schema_id.map(|schema_id| schema_id.into_proto()),
1134            object_type: self.object_type.into_proto(),
1135            grantee: self.grantee.into_proto(),
1136        }
1137    }
1138
1139    fn from_proto(proto: proto::DefaultPrivilegesKey) -> Result<Self, TryFromProtoError> {
1140        Ok(DefaultPrivilegesKey {
1141            role_id: proto.role_id.into_rust()?,
1142            database_id: proto.database_id.into_rust()?,
1143            schema_id: proto.schema_id.into_rust()?,
1144            object_type: proto.object_type.into_rust()?,
1145            grantee: proto.grantee.into_rust()?,
1146        })
1147    }
1148}
1149
1150impl RustType<proto::DefaultPrivilegesValue> for DefaultPrivilegesValue {
1151    fn into_proto(&self) -> proto::DefaultPrivilegesValue {
1152        proto::DefaultPrivilegesValue {
1153            privileges: self.privileges.into_proto(),
1154        }
1155    }
1156
1157    fn from_proto(proto: proto::DefaultPrivilegesValue) -> Result<Self, TryFromProtoError> {
1158        Ok(DefaultPrivilegesValue {
1159            privileges: proto.privileges.into_rust()?,
1160        })
1161    }
1162}
1163
1164impl RustType<proto::SystemPrivilegesKey> for SystemPrivilegesKey {
1165    fn into_proto(&self) -> proto::SystemPrivilegesKey {
1166        proto::SystemPrivilegesKey {
1167            grantee: self.grantee.into_proto(),
1168            grantor: self.grantor.into_proto(),
1169        }
1170    }
1171
1172    fn from_proto(proto: proto::SystemPrivilegesKey) -> Result<Self, TryFromProtoError> {
1173        Ok(SystemPrivilegesKey {
1174            grantee: proto.grantee.into_rust()?,
1175            grantor: proto.grantor.into_rust()?,
1176        })
1177    }
1178}
1179
1180impl RustType<proto::SystemPrivilegesValue> for SystemPrivilegesValue {
1181    fn into_proto(&self) -> proto::SystemPrivilegesValue {
1182        proto::SystemPrivilegesValue {
1183            acl_mode: self.acl_mode.into_proto(),
1184        }
1185    }
1186
1187    fn from_proto(proto: proto::SystemPrivilegesValue) -> Result<Self, TryFromProtoError> {
1188        Ok(SystemPrivilegesValue {
1189            acl_mode: proto.acl_mode.into_rust()?,
1190        })
1191    }
1192}
1193
1194impl RustType<proto::SystemCatalogItemId> for SystemCatalogItemId {
1195    fn into_proto(&self) -> proto::SystemCatalogItemId {
1196        proto::SystemCatalogItemId(self.0)
1197    }
1198
1199    fn from_proto(proto: proto::SystemCatalogItemId) -> Result<Self, TryFromProtoError> {
1200        Ok(SystemCatalogItemId(proto.0))
1201    }
1202}
1203
1204impl RustType<proto::IntrospectionSourceIndexCatalogItemId>
1205    for IntrospectionSourceIndexCatalogItemId
1206{
1207    fn into_proto(&self) -> proto::IntrospectionSourceIndexCatalogItemId {
1208        proto::IntrospectionSourceIndexCatalogItemId(self.0)
1209    }
1210
1211    fn from_proto(
1212        proto: proto::IntrospectionSourceIndexCatalogItemId,
1213    ) -> Result<Self, TryFromProtoError> {
1214        Ok(IntrospectionSourceIndexCatalogItemId(proto.0))
1215    }
1216}
1217
1218impl RustType<proto::SystemGlobalId> for SystemGlobalId {
1219    fn into_proto(&self) -> proto::SystemGlobalId {
1220        proto::SystemGlobalId(self.0)
1221    }
1222
1223    fn from_proto(proto: proto::SystemGlobalId) -> Result<Self, TryFromProtoError> {
1224        Ok(SystemGlobalId(proto.0))
1225    }
1226}
1227
1228impl RustType<proto::IntrospectionSourceIndexGlobalId> for IntrospectionSourceIndexGlobalId {
1229    fn into_proto(&self) -> proto::IntrospectionSourceIndexGlobalId {
1230        proto::IntrospectionSourceIndexGlobalId(self.0)
1231    }
1232
1233    fn from_proto(
1234        proto: proto::IntrospectionSourceIndexGlobalId,
1235    ) -> Result<Self, TryFromProtoError> {
1236        Ok(IntrospectionSourceIndexGlobalId(proto.0))
1237    }
1238}
1239
1240#[cfg(test)]
1241mod tests {
1242    use crate::durable::objects::serialization::RustType;
1243    use mz_audit_log::VersionedEvent;
1244    use proptest::prelude::*;
1245
1246    proptest! {
1247        #[mz_ore::test]
1248        #[cfg_attr(miri, ignore)] // slow
1249        fn proptest_audit_log_roundtrips(event: VersionedEvent) {
1250            let proto = event.into_proto();
1251            let roundtrip = VersionedEvent::from_proto(proto).expect("valid proto");
1252
1253            prop_assert_eq!(event, roundtrip);
1254        }
1255    }
1256}