1use std::fmt;
11
12use mz_lowertest::MzReflect;
13use mz_proto::{ProtoType, RustType, TryFromProtoError};
14use mz_repr::GlobalId;
15use proptest_derive::Arbitrary;
16use serde::{Deserialize, Serialize};
17
18include!(concat!(env!("OUT_DIR"), "/mz_expr.id.rs"));
19
20#[derive(
23 Arbitrary,
24 Clone,
25 Copy,
26 Debug,
27 Eq,
28 PartialEq,
29 Ord,
30 PartialOrd,
31 Hash,
32 Serialize,
33 Deserialize,
34 MzReflect,
35)]
36pub enum Id {
37 Local(LocalId),
39 #[proptest(value = "Id::Global(GlobalId::System(2))")]
41 Global(GlobalId),
42}
43
44impl fmt::Display for Id {
45 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
46 match self {
47 Id::Local(id) => id.fmt(f),
48 Id::Global(id) => id.fmt(f),
49 }
50 }
51}
52
53impl RustType<ProtoId> for Id {
54 fn into_proto(&self) -> ProtoId {
55 ProtoId {
56 kind: Some(match self {
57 Id::Global(g) => proto_id::Kind::Global(g.into_proto()),
58 Id::Local(l) => proto_id::Kind::Local(l.into_proto()),
59 }),
60 }
61 }
62
63 fn from_proto(proto: ProtoId) -> Result<Self, TryFromProtoError> {
64 match proto.kind {
65 Some(proto_id::Kind::Global(x)) => Ok(Id::Global(x.into_rust()?)),
66 Some(proto_id::Kind::Local(x)) => Ok(Id::Local(x.into_rust()?)),
67 None => Err(TryFromProtoError::missing_field("ProtoId::kind")),
68 }
69 }
70}
71
72#[derive(
74 Arbitrary,
75 Clone,
76 Copy,
77 Debug,
78 Eq,
79 PartialEq,
80 Ord,
81 PartialOrd,
82 Hash,
83 Serialize,
84 Deserialize,
85 MzReflect,
86)]
87pub struct LocalId(pub(crate) u64);
88
89impl LocalId {
90 pub fn new(v: u64) -> LocalId {
93 LocalId(v)
94 }
95}
96
97impl From<&LocalId> for u64 {
98 fn from(id: &LocalId) -> Self {
99 id.0
100 }
101}
102
103impl fmt::Display for LocalId {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 write!(f, "l{}", self.0)
106 }
107}
108
109impl RustType<ProtoLocalId> for LocalId {
110 fn into_proto(&self) -> ProtoLocalId {
111 ProtoLocalId { value: self.0 }
112 }
113
114 fn from_proto(proto: ProtoLocalId) -> Result<Self, TryFromProtoError> {
115 Ok(LocalId::new(proto.value))
116 }
117}
118
119#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
121pub struct SourceInstanceId {
122 pub source_id: GlobalId,
124 pub dataflow_id: usize,
127}
128
129impl fmt::Display for SourceInstanceId {
130 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131 write!(f, "{}/{}", self.source_id, self.dataflow_id)
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use mz_ore::assert_ok;
138 use mz_proto::protobuf_roundtrip;
139 use proptest::prelude::*;
140
141 use super::*;
142
143 proptest! {
144 #[mz_ore::test]
145 fn id_protobuf_roundtrip(expect in any::<Id>()) {
146 let actual = protobuf_roundtrip::<_, ProtoId>(&expect);
147 assert_ok!(actual);
148 assert_eq!(actual.unwrap(), expect);
149 }
150 }
151}