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