Skip to main content

mz_catalog/durable/objects/serialization/
foreign.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 objects from crates other than
11//! `mz_catalog` into protobuf.
12
13use std::time::Duration;
14
15use mz_compute_types::config::ComputeReplicaLogging;
16use mz_controller_types::ReplicaId;
17use mz_persist_types::ShardId;
18use mz_proto::TryFromProtoError;
19use mz_repr::adt::mz_acl_item::{AclMode, MzAclItem};
20use mz_repr::cluster_replica_size_id::ClusterReplicaSizeId;
21use mz_repr::network_policy_id::NetworkPolicyId;
22use mz_repr::role_id::RoleId;
23use mz_repr::{CatalogItemId, GlobalId, RelationVersion};
24use mz_sql::catalog::{
25    AutoProvisionSource, CatalogItemType, ObjectType, RoleAttributes, RoleMembership, RoleVars,
26};
27use mz_sql::names::{
28    CommentObjectId, DatabaseId, ResolvedDatabaseSpecifier, SchemaId, SchemaSpecifier,
29};
30use mz_sql::plan::{
31    AutoScalingStrategy, ClusterSchedule, NetworkPolicyRule, NetworkPolicyRuleAction,
32    NetworkPolicyRuleDirection, OnHydration, OnTimeoutAction, PolicyAddress,
33};
34use mz_sql::session::vars::OwnedVarInput;
35use mz_storage_types::instances::StorageInstanceId;
36
37use crate::durable::objects::serialization::{ProtoMapEntry, ProtoType, RustType, proto};
38
39impl RustType<proto::Duration> for Duration {
40    fn into_proto(&self) -> proto::Duration {
41        proto::Duration {
42            secs: self.as_secs(),
43            nanos: self.subsec_nanos(),
44        }
45    }
46
47    fn from_proto(proto: proto::Duration) -> Result<Self, TryFromProtoError> {
48        Ok(Duration::new(proto.secs, proto.nanos))
49    }
50}
51
52impl RustType<proto::RoleId> for RoleId {
53    fn into_proto(&self) -> proto::RoleId {
54        match self {
55            RoleId::User(id) => proto::RoleId::User(*id),
56            RoleId::System(id) => proto::RoleId::System(*id),
57            RoleId::Predefined(id) => proto::RoleId::Predefined(*id),
58            RoleId::Public => proto::RoleId::Public,
59        }
60    }
61
62    fn from_proto(proto: proto::RoleId) -> Result<Self, TryFromProtoError> {
63        let id = match proto {
64            proto::RoleId::User(id) => RoleId::User(id),
65            proto::RoleId::System(id) => RoleId::System(id),
66            proto::RoleId::Predefined(id) => RoleId::Predefined(id),
67            proto::RoleId::Public => RoleId::Public,
68        };
69        Ok(id)
70    }
71}
72
73impl RustType<proto::AclMode> for AclMode {
74    fn into_proto(&self) -> proto::AclMode {
75        proto::AclMode {
76            bitflags: self.bits(),
77        }
78    }
79
80    fn from_proto(proto: proto::AclMode) -> Result<Self, TryFromProtoError> {
81        AclMode::from_bits(proto.bitflags).ok_or_else(|| {
82            TryFromProtoError::InvalidBitFlags(format!("Invalid AclMode from catalog {proto:?}"))
83        })
84    }
85}
86
87impl RustType<proto::MzAclItem> for MzAclItem {
88    fn into_proto(&self) -> proto::MzAclItem {
89        proto::MzAclItem {
90            grantee: self.grantee.into_proto(),
91            grantor: self.grantor.into_proto(),
92            acl_mode: self.acl_mode.into_proto(),
93        }
94    }
95
96    fn from_proto(proto: proto::MzAclItem) -> Result<Self, TryFromProtoError> {
97        Ok(MzAclItem {
98            grantee: proto.grantee.into_rust()?,
99            grantor: proto.grantor.into_rust()?,
100            acl_mode: proto.acl_mode.into_rust()?,
101        })
102    }
103}
104
105impl RustType<proto::AutoProvisionSource> for AutoProvisionSource {
106    fn into_proto(&self) -> proto::AutoProvisionSource {
107        match self {
108            AutoProvisionSource::Oidc => proto::AutoProvisionSource::Oidc,
109            AutoProvisionSource::Frontegg => proto::AutoProvisionSource::Frontegg,
110            AutoProvisionSource::None => proto::AutoProvisionSource::None,
111        }
112    }
113
114    fn from_proto(proto: proto::AutoProvisionSource) -> Result<Self, TryFromProtoError> {
115        Ok(match proto {
116            proto::AutoProvisionSource::Oidc => AutoProvisionSource::Oidc,
117            proto::AutoProvisionSource::Frontegg => AutoProvisionSource::Frontegg,
118            proto::AutoProvisionSource::None => AutoProvisionSource::None,
119        })
120    }
121}
122
123impl RustType<proto::RoleAttributes> for RoleAttributes {
124    fn into_proto(&self) -> proto::RoleAttributes {
125        proto::RoleAttributes {
126            inherit: self.inherit,
127            superuser: self.superuser,
128            login: self.login,
129            auto_provision_source: self.auto_provision_source.into_proto(),
130        }
131    }
132
133    fn from_proto(proto: proto::RoleAttributes) -> Result<Self, TryFromProtoError> {
134        let mut attributes = RoleAttributes::new();
135
136        attributes.inherit = proto.inherit;
137        attributes.superuser = proto.superuser;
138        attributes.login = proto.login;
139        attributes.auto_provision_source = proto.auto_provision_source.into_rust()?;
140
141        Ok(attributes)
142    }
143}
144
145impl RustType<proto::RoleVar> for OwnedVarInput {
146    fn into_proto(&self) -> proto::RoleVar {
147        match self.clone() {
148            OwnedVarInput::Flat(v) => proto::RoleVar::Flat(v),
149            OwnedVarInput::SqlSet(entries) => proto::RoleVar::SqlSet(entries),
150        }
151    }
152
153    fn from_proto(proto: proto::RoleVar) -> Result<Self, TryFromProtoError> {
154        let result = match proto {
155            proto::RoleVar::Flat(v) => OwnedVarInput::Flat(v),
156            proto::RoleVar::SqlSet(entries) => OwnedVarInput::SqlSet(entries),
157        };
158        Ok(result)
159    }
160}
161
162impl RustType<proto::RoleVars> for RoleVars {
163    fn into_proto(&self) -> proto::RoleVars {
164        let entries = self
165            .map
166            .clone()
167            .into_iter()
168            .map(|(key, val)| proto::RoleVarsEntry {
169                key,
170                val: val.into_proto(),
171            })
172            .collect();
173
174        proto::RoleVars { entries }
175    }
176
177    fn from_proto(proto: proto::RoleVars) -> Result<Self, TryFromProtoError> {
178        let map = proto
179            .entries
180            .into_iter()
181            .map(|entry| {
182                let val = entry.val.into_rust()?;
183                Ok::<_, TryFromProtoError>((entry.key, val))
184            })
185            .collect::<Result<_, _>>()?;
186
187        Ok(RoleVars { map })
188    }
189}
190
191impl RustType<proto::NetworkPolicyId> for NetworkPolicyId {
192    fn into_proto(&self) -> proto::NetworkPolicyId {
193        match self {
194            NetworkPolicyId::User(id) => proto::NetworkPolicyId::User(*id),
195            NetworkPolicyId::System(id) => proto::NetworkPolicyId::System(*id),
196        }
197    }
198
199    fn from_proto(proto: proto::NetworkPolicyId) -> Result<Self, TryFromProtoError> {
200        let id = match proto {
201            proto::NetworkPolicyId::User(id) => NetworkPolicyId::User(id),
202            proto::NetworkPolicyId::System(id) => NetworkPolicyId::System(id),
203        };
204        Ok(id)
205    }
206}
207
208impl RustType<proto::ClusterReplicaSizeId> for ClusterReplicaSizeId {
209    fn into_proto(&self) -> proto::ClusterReplicaSizeId {
210        match self {
211            ClusterReplicaSizeId::User(id) => proto::ClusterReplicaSizeId::User(*id),
212            ClusterReplicaSizeId::System(id) => proto::ClusterReplicaSizeId::System(*id),
213        }
214    }
215
216    fn from_proto(proto: proto::ClusterReplicaSizeId) -> Result<Self, TryFromProtoError> {
217        let id = match proto {
218            proto::ClusterReplicaSizeId::User(id) => ClusterReplicaSizeId::User(id),
219            proto::ClusterReplicaSizeId::System(id) => ClusterReplicaSizeId::System(id),
220        };
221        Ok(id)
222    }
223}
224
225impl RustType<proto::CatalogItemType> for CatalogItemType {
226    fn into_proto(&self) -> proto::CatalogItemType {
227        match self {
228            CatalogItemType::Table => proto::CatalogItemType::Table,
229            CatalogItemType::Source => proto::CatalogItemType::Source,
230            CatalogItemType::Sink => proto::CatalogItemType::Sink,
231            CatalogItemType::View => proto::CatalogItemType::View,
232            CatalogItemType::MaterializedView => proto::CatalogItemType::MaterializedView,
233            CatalogItemType::Index => proto::CatalogItemType::Index,
234            CatalogItemType::Type => proto::CatalogItemType::Type,
235            CatalogItemType::Func => proto::CatalogItemType::Func,
236            CatalogItemType::Secret => proto::CatalogItemType::Secret,
237            CatalogItemType::Connection => proto::CatalogItemType::Connection,
238            CatalogItemType::MetricSink => proto::CatalogItemType::MetricSink,
239        }
240    }
241
242    fn from_proto(proto: proto::CatalogItemType) -> Result<Self, TryFromProtoError> {
243        let item_type = match proto {
244            proto::CatalogItemType::Table => CatalogItemType::Table,
245            proto::CatalogItemType::Source => CatalogItemType::Source,
246            proto::CatalogItemType::Sink => CatalogItemType::Sink,
247            proto::CatalogItemType::View => CatalogItemType::View,
248            proto::CatalogItemType::MaterializedView => CatalogItemType::MaterializedView,
249            proto::CatalogItemType::Index => CatalogItemType::Index,
250            proto::CatalogItemType::Type => CatalogItemType::Type,
251            proto::CatalogItemType::Func => CatalogItemType::Func,
252            proto::CatalogItemType::Secret => CatalogItemType::Secret,
253            proto::CatalogItemType::Connection => CatalogItemType::Connection,
254            proto::CatalogItemType::MetricSink => CatalogItemType::MetricSink,
255            proto::CatalogItemType::Unknown => {
256                return Err(TryFromProtoError::unknown_enum_variant("CatalogItemType"));
257            }
258        };
259        Ok(item_type)
260    }
261}
262
263impl RustType<proto::ObjectType> for ObjectType {
264    fn into_proto(&self) -> proto::ObjectType {
265        match self {
266            ObjectType::Table => proto::ObjectType::Table,
267            ObjectType::View => proto::ObjectType::View,
268            ObjectType::MaterializedView => proto::ObjectType::MaterializedView,
269            ObjectType::Source => proto::ObjectType::Source,
270            ObjectType::Sink => proto::ObjectType::Sink,
271            ObjectType::Index => proto::ObjectType::Index,
272            ObjectType::Type => proto::ObjectType::Type,
273            ObjectType::Role => proto::ObjectType::Role,
274            ObjectType::Cluster => proto::ObjectType::Cluster,
275            ObjectType::ClusterReplica => proto::ObjectType::ClusterReplica,
276            ObjectType::Secret => proto::ObjectType::Secret,
277            ObjectType::Connection => proto::ObjectType::Connection,
278            ObjectType::Database => proto::ObjectType::Database,
279            ObjectType::Schema => proto::ObjectType::Schema,
280            ObjectType::Func => proto::ObjectType::Func,
281            ObjectType::NetworkPolicy => proto::ObjectType::NetworkPolicy,
282            ObjectType::MetricSink => proto::ObjectType::MetricSink,
283        }
284    }
285
286    fn from_proto(proto: proto::ObjectType) -> Result<Self, TryFromProtoError> {
287        match proto {
288            proto::ObjectType::Table => Ok(ObjectType::Table),
289            proto::ObjectType::View => Ok(ObjectType::View),
290            proto::ObjectType::MaterializedView => Ok(ObjectType::MaterializedView),
291            proto::ObjectType::Source => Ok(ObjectType::Source),
292            proto::ObjectType::Sink => Ok(ObjectType::Sink),
293            proto::ObjectType::Index => Ok(ObjectType::Index),
294            proto::ObjectType::Type => Ok(ObjectType::Type),
295            proto::ObjectType::Role => Ok(ObjectType::Role),
296            proto::ObjectType::Cluster => Ok(ObjectType::Cluster),
297            proto::ObjectType::ClusterReplica => Ok(ObjectType::ClusterReplica),
298            proto::ObjectType::Secret => Ok(ObjectType::Secret),
299            proto::ObjectType::Connection => Ok(ObjectType::Connection),
300            proto::ObjectType::Database => Ok(ObjectType::Database),
301            proto::ObjectType::Schema => Ok(ObjectType::Schema),
302            proto::ObjectType::Func => Ok(ObjectType::Func),
303            proto::ObjectType::NetworkPolicy => Ok(ObjectType::NetworkPolicy),
304            proto::ObjectType::MetricSink => Ok(ObjectType::MetricSink),
305            proto::ObjectType::Unknown => Err(TryFromProtoError::unknown_enum_variant(
306                "ObjectType::Unknown",
307            )),
308        }
309    }
310}
311
312impl RustType<proto::RoleMembership> for RoleMembership {
313    fn into_proto(&self) -> proto::RoleMembership {
314        proto::RoleMembership {
315            map: self
316                .map
317                .iter()
318                .map(|(key, val)| proto::RoleMembershipEntry {
319                    key: key.into_proto(),
320                    value: val.into_proto(),
321                })
322                .collect(),
323        }
324    }
325
326    fn from_proto(proto: proto::RoleMembership) -> Result<Self, TryFromProtoError> {
327        Ok(RoleMembership {
328            map: proto
329                .map
330                .into_iter()
331                .map(|e| {
332                    let key = e.key.into_rust()?;
333                    let val = e.value.into_rust()?;
334
335                    Ok((key, val))
336                })
337                .collect::<Result<_, TryFromProtoError>>()?,
338        })
339    }
340}
341
342impl RustType<proto::ResolvedDatabaseSpecifier> for ResolvedDatabaseSpecifier {
343    fn into_proto(&self) -> proto::ResolvedDatabaseSpecifier {
344        match self {
345            ResolvedDatabaseSpecifier::Ambient => proto::ResolvedDatabaseSpecifier::Ambient,
346            ResolvedDatabaseSpecifier::Id(database_id) => {
347                proto::ResolvedDatabaseSpecifier::Id(database_id.into_proto())
348            }
349        }
350    }
351
352    fn from_proto(proto: proto::ResolvedDatabaseSpecifier) -> Result<Self, TryFromProtoError> {
353        let spec = match proto {
354            proto::ResolvedDatabaseSpecifier::Ambient => ResolvedDatabaseSpecifier::Ambient,
355            proto::ResolvedDatabaseSpecifier::Id(database_id) => {
356                ResolvedDatabaseSpecifier::Id(database_id.into_rust()?)
357            }
358        };
359        Ok(spec)
360    }
361}
362
363impl RustType<proto::SchemaSpecifier> for SchemaSpecifier {
364    fn into_proto(&self) -> proto::SchemaSpecifier {
365        match self {
366            SchemaSpecifier::Temporary => proto::SchemaSpecifier::Temporary,
367            SchemaSpecifier::Id(schema_id) => proto::SchemaSpecifier::Id(schema_id.into_proto()),
368        }
369    }
370
371    fn from_proto(proto: proto::SchemaSpecifier) -> Result<Self, TryFromProtoError> {
372        let spec = match proto {
373            proto::SchemaSpecifier::Temporary => SchemaSpecifier::Temporary,
374            proto::SchemaSpecifier::Id(schema_id) => SchemaSpecifier::Id(schema_id.into_rust()?),
375        };
376        Ok(spec)
377    }
378}
379
380impl RustType<proto::SchemaId> for SchemaId {
381    fn into_proto(&self) -> proto::SchemaId {
382        match self {
383            SchemaId::User(id) => proto::SchemaId::User(*id),
384            SchemaId::System(id) => proto::SchemaId::System(*id),
385        }
386    }
387
388    fn from_proto(proto: proto::SchemaId) -> Result<Self, TryFromProtoError> {
389        let id = match proto {
390            proto::SchemaId::User(id) => SchemaId::User(id),
391            proto::SchemaId::System(id) => SchemaId::System(id),
392        };
393        Ok(id)
394    }
395}
396
397impl RustType<proto::DatabaseId> for DatabaseId {
398    fn into_proto(&self) -> proto::DatabaseId {
399        match self {
400            DatabaseId::User(id) => proto::DatabaseId::User(*id),
401            DatabaseId::System(id) => proto::DatabaseId::System(*id),
402        }
403    }
404
405    fn from_proto(proto: proto::DatabaseId) -> Result<Self, TryFromProtoError> {
406        match proto {
407            proto::DatabaseId::User(id) => Ok(DatabaseId::User(id)),
408            proto::DatabaseId::System(id) => Ok(DatabaseId::System(id)),
409        }
410    }
411}
412
413impl RustType<proto::CommentObject> for CommentObjectId {
414    fn into_proto(&self) -> proto::CommentObject {
415        match self {
416            CommentObjectId::Table(global_id) => {
417                proto::CommentObject::Table(global_id.into_proto())
418            }
419            CommentObjectId::View(global_id) => proto::CommentObject::View(global_id.into_proto()),
420            CommentObjectId::MaterializedView(global_id) => {
421                proto::CommentObject::MaterializedView(global_id.into_proto())
422            }
423            CommentObjectId::Source(global_id) => {
424                proto::CommentObject::Source(global_id.into_proto())
425            }
426            CommentObjectId::Sink(global_id) => proto::CommentObject::Sink(global_id.into_proto()),
427            CommentObjectId::MetricSink(global_id) => {
428                proto::CommentObject::MetricSink(global_id.into_proto())
429            }
430            CommentObjectId::Index(global_id) => {
431                proto::CommentObject::Index(global_id.into_proto())
432            }
433            CommentObjectId::Func(global_id) => proto::CommentObject::Func(global_id.into_proto()),
434            CommentObjectId::Connection(global_id) => {
435                proto::CommentObject::Connection(global_id.into_proto())
436            }
437            CommentObjectId::Type(global_id) => proto::CommentObject::Type(global_id.into_proto()),
438            CommentObjectId::Secret(global_id) => {
439                proto::CommentObject::Secret(global_id.into_proto())
440            }
441            CommentObjectId::Role(role_id) => proto::CommentObject::Role(role_id.into_proto()),
442            CommentObjectId::Database(database_id) => {
443                proto::CommentObject::Database(database_id.into_proto())
444            }
445            CommentObjectId::NetworkPolicy(network_policy_id) => {
446                proto::CommentObject::NetworkPolicy(network_policy_id.into_proto())
447            }
448            CommentObjectId::Schema((database, schema)) => {
449                proto::CommentObject::Schema(proto::ResolvedSchema {
450                    database: database.into_proto(),
451                    schema: schema.into_proto(),
452                })
453            }
454            CommentObjectId::Cluster(cluster_id) => {
455                proto::CommentObject::Cluster(cluster_id.into_proto())
456            }
457            CommentObjectId::ClusterReplica((cluster_id, replica_id)) => {
458                let cluster_replica_id = proto::ClusterReplicaId {
459                    cluster_id: cluster_id.into_proto(),
460                    replica_id: replica_id.into_proto(),
461                };
462                proto::CommentObject::ClusterReplica(cluster_replica_id)
463            }
464        }
465    }
466
467    fn from_proto(proto: proto::CommentObject) -> Result<Self, TryFromProtoError> {
468        let id = match proto {
469            proto::CommentObject::Table(item_id) => CommentObjectId::Table(item_id.into_rust()?),
470            proto::CommentObject::View(item_id) => CommentObjectId::View(item_id.into_rust()?),
471            proto::CommentObject::MaterializedView(item_id) => {
472                CommentObjectId::MaterializedView(item_id.into_rust()?)
473            }
474            proto::CommentObject::Source(item_id) => CommentObjectId::Source(item_id.into_rust()?),
475            proto::CommentObject::Sink(item_id) => CommentObjectId::Sink(item_id.into_rust()?),
476            proto::CommentObject::MetricSink(item_id) => {
477                CommentObjectId::MetricSink(item_id.into_rust()?)
478            }
479            proto::CommentObject::Index(item_id) => CommentObjectId::Index(item_id.into_rust()?),
480            proto::CommentObject::Func(item_id) => CommentObjectId::Func(item_id.into_rust()?),
481            proto::CommentObject::Connection(item_id) => {
482                CommentObjectId::Connection(item_id.into_rust()?)
483            }
484            proto::CommentObject::Type(item_id) => CommentObjectId::Type(item_id.into_rust()?),
485            proto::CommentObject::Secret(item_id) => CommentObjectId::Secret(item_id.into_rust()?),
486            proto::CommentObject::NetworkPolicy(global_id) => {
487                CommentObjectId::NetworkPolicy(global_id.into_rust()?)
488            }
489            proto::CommentObject::Role(role_id) => CommentObjectId::Role(role_id.into_rust()?),
490            proto::CommentObject::Database(database_id) => {
491                CommentObjectId::Database(database_id.into_rust()?)
492            }
493            proto::CommentObject::Schema(resolved_schema) => {
494                let database = resolved_schema.database.into_rust()?;
495                let schema = resolved_schema.schema.into_rust()?;
496                CommentObjectId::Schema((database, schema))
497            }
498            proto::CommentObject::Cluster(cluster_id) => {
499                CommentObjectId::Cluster(cluster_id.into_rust()?)
500            }
501            proto::CommentObject::ClusterReplica(cluster_replica_id) => {
502                let cluster_id = cluster_replica_id.cluster_id.into_rust()?;
503                let replica_id = cluster_replica_id.replica_id.into_rust()?;
504                CommentObjectId::ClusterReplica((cluster_id, replica_id))
505            }
506        };
507        Ok(id)
508    }
509}
510
511impl RustType<proto::EpochMillis> for u64 {
512    fn into_proto(&self) -> proto::EpochMillis {
513        proto::EpochMillis { millis: *self }
514    }
515
516    fn from_proto(proto: proto::EpochMillis) -> Result<Self, TryFromProtoError> {
517        Ok(proto.millis)
518    }
519}
520
521impl RustType<proto::CatalogItemId> for CatalogItemId {
522    fn into_proto(&self) -> proto::CatalogItemId {
523        match self {
524            CatalogItemId::System(x) => proto::CatalogItemId::System(*x),
525            CatalogItemId::IntrospectionSourceIndex(x) => {
526                proto::CatalogItemId::IntrospectionSourceIndex(*x)
527            }
528            CatalogItemId::User(x) => proto::CatalogItemId::User(*x),
529            CatalogItemId::Transient(x) => proto::CatalogItemId::Transient(*x),
530        }
531    }
532
533    fn from_proto(proto: proto::CatalogItemId) -> Result<Self, TryFromProtoError> {
534        match proto {
535            proto::CatalogItemId::System(x) => Ok(CatalogItemId::System(x)),
536            proto::CatalogItemId::IntrospectionSourceIndex(x) => {
537                Ok(CatalogItemId::IntrospectionSourceIndex(x))
538            }
539            proto::CatalogItemId::User(x) => Ok(CatalogItemId::User(x)),
540            proto::CatalogItemId::Transient(x) => Ok(CatalogItemId::Transient(x)),
541        }
542    }
543}
544
545impl RustType<proto::GlobalId> for GlobalId {
546    fn into_proto(&self) -> proto::GlobalId {
547        match self {
548            GlobalId::System(x) => proto::GlobalId::System(*x),
549            GlobalId::IntrospectionSourceIndex(x) => proto::GlobalId::IntrospectionSourceIndex(*x),
550            GlobalId::User(x) => proto::GlobalId::User(*x),
551            GlobalId::Transient(x) => proto::GlobalId::Transient(*x),
552            GlobalId::Explain => proto::GlobalId::Explain,
553        }
554    }
555
556    fn from_proto(proto: proto::GlobalId) -> Result<Self, TryFromProtoError> {
557        match proto {
558            proto::GlobalId::System(x) => Ok(GlobalId::System(x)),
559            proto::GlobalId::IntrospectionSourceIndex(x) => {
560                Ok(GlobalId::IntrospectionSourceIndex(x))
561            }
562            proto::GlobalId::User(x) => Ok(GlobalId::User(x)),
563            proto::GlobalId::Transient(x) => Ok(GlobalId::Transient(x)),
564            proto::GlobalId::Explain => Ok(GlobalId::Explain),
565        }
566    }
567}
568
569impl RustType<proto::ClusterId> for StorageInstanceId {
570    fn into_proto(&self) -> proto::ClusterId {
571        match self {
572            StorageInstanceId::User(id) => proto::ClusterId::User(*id),
573            StorageInstanceId::System(id) => proto::ClusterId::System(*id),
574        }
575    }
576
577    fn from_proto(proto: proto::ClusterId) -> Result<Self, TryFromProtoError> {
578        let id = match proto {
579            proto::ClusterId::User(id) => StorageInstanceId::user(id).ok_or_else(|| {
580                TryFromProtoError::InvalidPersistState(format!(
581                    "{id} is not a valid StorageInstanceId"
582                ))
583            })?,
584            proto::ClusterId::System(id) => StorageInstanceId::system(id).ok_or_else(|| {
585                TryFromProtoError::InvalidPersistState(format!(
586                    "{id} is not a valid StorageInstanceId"
587                ))
588            })?,
589        };
590        Ok(id)
591    }
592}
593
594impl RustType<proto::ReplicaId> for ReplicaId {
595    fn into_proto(&self) -> proto::ReplicaId {
596        match self {
597            Self::System(id) => proto::ReplicaId::System(*id),
598            Self::User(id) => proto::ReplicaId::User(*id),
599        }
600    }
601
602    fn from_proto(proto: proto::ReplicaId) -> Result<Self, TryFromProtoError> {
603        match proto {
604            proto::ReplicaId::System(id) => Ok(Self::System(id)),
605            proto::ReplicaId::User(id) => Ok(Self::User(id)),
606        }
607    }
608}
609
610impl ProtoMapEntry<String, String> for proto::OptimizerFeatureOverride {
611    fn from_rust<'a>(entry: (&'a String, &'a String)) -> Self {
612        proto::OptimizerFeatureOverride {
613            name: entry.0.into_proto(),
614            value: entry.1.into_proto(),
615        }
616    }
617
618    fn into_rust(self) -> Result<(String, String), TryFromProtoError> {
619        Ok((self.name.into_rust()?, self.value.into_rust()?))
620    }
621}
622
623impl RustType<proto::ClusterSchedule> for ClusterSchedule {
624    fn into_proto(&self) -> proto::ClusterSchedule {
625        match self {
626            ClusterSchedule::Manual => proto::ClusterSchedule::Manual,
627            ClusterSchedule::Refresh {
628                hydration_time_estimate,
629            } => proto::ClusterSchedule::Refresh(proto::ClusterScheduleRefreshOptions {
630                rehydration_time_estimate: hydration_time_estimate.into_proto(),
631            }),
632        }
633    }
634
635    fn from_proto(proto: proto::ClusterSchedule) -> Result<Self, TryFromProtoError> {
636        match proto {
637            proto::ClusterSchedule::Manual => Ok(ClusterSchedule::Manual),
638            proto::ClusterSchedule::Refresh(csro) => Ok(ClusterSchedule::Refresh {
639                hydration_time_estimate: csro.rehydration_time_estimate.into_rust()?,
640            }),
641        }
642    }
643}
644
645impl RustType<proto::AutoScalingStrategy> for AutoScalingStrategy {
646    fn into_proto(&self) -> proto::AutoScalingStrategy {
647        proto::AutoScalingStrategy {
648            on_hydration: self.on_hydration.into_proto(),
649        }
650    }
651
652    fn from_proto(proto: proto::AutoScalingStrategy) -> Result<Self, TryFromProtoError> {
653        Ok(Self {
654            on_hydration: proto.on_hydration.into_rust()?,
655        })
656    }
657}
658
659impl RustType<proto::OnHydration> for OnHydration {
660    fn into_proto(&self) -> proto::OnHydration {
661        proto::OnHydration {
662            hydration_size: self.hydration_size.clone(),
663            linger_duration: self.linger_duration.into_proto(),
664        }
665    }
666
667    fn from_proto(proto: proto::OnHydration) -> Result<Self, TryFromProtoError> {
668        Ok(Self {
669            hydration_size: proto.hydration_size,
670            linger_duration: proto.linger_duration.into_rust()?,
671        })
672    }
673}
674
675impl RustType<proto::OnTimeoutAction> for OnTimeoutAction {
676    fn into_proto(&self) -> proto::OnTimeoutAction {
677        match self {
678            OnTimeoutAction::Commit => proto::OnTimeoutAction::Commit,
679            OnTimeoutAction::Rollback => proto::OnTimeoutAction::Rollback,
680        }
681    }
682
683    fn from_proto(proto: proto::OnTimeoutAction) -> Result<Self, TryFromProtoError> {
684        Ok(match proto {
685            proto::OnTimeoutAction::Commit => OnTimeoutAction::Commit,
686            proto::OnTimeoutAction::Rollback => OnTimeoutAction::Rollback,
687        })
688    }
689}
690
691impl RustType<proto::ReplicaLogging> for ComputeReplicaLogging {
692    fn into_proto(&self) -> proto::ReplicaLogging {
693        proto::ReplicaLogging {
694            log_logging: self.log_logging,
695            interval: self.interval.into_proto(),
696        }
697    }
698
699    fn from_proto(proto: proto::ReplicaLogging) -> Result<Self, TryFromProtoError> {
700        Ok(ComputeReplicaLogging {
701            log_logging: proto.log_logging,
702            interval: proto.interval.into_rust()?,
703        })
704    }
705}
706
707impl RustType<proto::Version> for RelationVersion {
708    fn into_proto(&self) -> proto::Version {
709        proto::Version {
710            value: self.into_raw(),
711        }
712    }
713
714    fn from_proto(proto: proto::Version) -> Result<Self, TryFromProtoError> {
715        Ok(RelationVersion::from_raw(proto.value))
716    }
717}
718
719impl RustType<proto::NetworkPolicyRule> for NetworkPolicyRule {
720    fn into_proto(&self) -> proto::NetworkPolicyRule {
721        proto::NetworkPolicyRule {
722            name: self.name.clone(),
723            action: match self.action {
724                NetworkPolicyRuleAction::Allow => proto::NetworkPolicyRuleAction::Allow,
725            },
726            direction: match self.direction {
727                NetworkPolicyRuleDirection::Ingress => proto::NetworkPolicyRuleDirection::Ingress,
728            },
729            address: self.address.clone().to_string(),
730        }
731    }
732
733    fn from_proto(proto: proto::NetworkPolicyRule) -> Result<Self, TryFromProtoError> {
734        Ok(NetworkPolicyRule {
735            name: proto.name,
736            action: match proto.action {
737                proto::NetworkPolicyRuleAction::Allow => NetworkPolicyRuleAction::Allow,
738            },
739            address: PolicyAddress::from(proto.address),
740            direction: match proto.direction {
741                proto::NetworkPolicyRuleDirection::Ingress => NetworkPolicyRuleDirection::Ingress,
742            },
743        })
744    }
745}
746
747impl RustType<String> for ShardId {
748    // Delegates to the `mz_proto` encoding, so that both stay identical.
749    fn into_proto(&self) -> String {
750        mz_proto::RustType::into_proto(self)
751    }
752
753    fn from_proto(proto: String) -> Result<Self, TryFromProtoError> {
754        mz_proto::RustType::from_proto(proto)
755    }
756}