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