1use crate::{Attribute, AttributeIndex, AttributeMap, Channel, ChannelMap, Stream};
10
11#[derive(Clone, Debug, Default, Eq, PartialEq)]
12pub struct PersistenceSchema {
27 definitions: Vec<PersistenceDefinition>,
28}
29
30#[derive(Clone, Debug, Eq, PartialEq)]
31pub(crate) struct PersistenceDefinition {
32 pub(crate) name: String,
33 pub(crate) kind: PersistenceKind,
34 pub(crate) index: Option<AttributeIndex>,
35 pub(crate) sync_to_attribute_store: bool,
36 pub(crate) stream_identity: Option<usize>,
37 pub(crate) max_estimated_bytes: Option<i64>,
38}
39
40#[derive(Clone, Copy, Debug, Eq, PartialEq)]
41pub(crate) enum PersistenceKind {
42 Attribute,
43 AttributeMap,
44 Channel,
45 ChannelMap,
46 Stream,
47}
48
49impl PersistenceSchema {
50 pub fn new() -> Self {
52 Self::default()
53 }
54
55 pub fn attribute<T>(mut self, attribute: &Attribute<T>) -> Self {
57 self.add(
58 attribute.name(),
59 PersistenceKind::Attribute,
60 attribute.index().cloned(),
61 attribute.is_sync_to_attribute_store(),
62 None,
63 None,
64 );
65 self
66 }
67
68 pub fn attribute_map<T>(mut self, attribute: &AttributeMap<T>) -> Self {
70 self.add(
71 attribute.name(),
72 PersistenceKind::AttributeMap,
73 attribute.index().cloned(),
74 attribute.is_sync_to_attribute_store(),
75 None,
76 None,
77 );
78 self
79 }
80
81 pub fn channel<T>(mut self, channel: &Channel<T>) -> Self {
83 self.add(
84 channel.name(),
85 PersistenceKind::Channel,
86 None,
87 false,
88 None,
89 None,
90 );
91 self
92 }
93
94 pub fn channel_map<T>(mut self, channel: &ChannelMap<T>) -> Self {
96 self.add(
97 channel.name(),
98 PersistenceKind::ChannelMap,
99 None,
100 false,
101 None,
102 None,
103 );
104 self
105 }
106
107 pub fn stream<T>(mut self, stream: &Stream<T>) -> Self {
109 self.add(
110 stream.name(),
111 PersistenceKind::Stream,
112 None,
113 false,
114 Some(stream.identity()),
115 Some(stream.max_estimated_bytes()),
116 );
117 self
118 }
119
120 pub(crate) fn definitions(&self) -> &[PersistenceDefinition] {
121 &self.definitions
122 }
123
124 fn add(
125 &mut self,
126 name: &str,
127 kind: PersistenceKind,
128 index: Option<AttributeIndex>,
129 sync_to_attribute_store: bool,
130 stream_identity: Option<usize>,
131 max_estimated_bytes: Option<i64>,
132 ) {
133 self.definitions.push(PersistenceDefinition {
134 name: name.to_string(),
135 kind,
136 index,
137 sync_to_attribute_store,
138 stream_identity,
139 max_estimated_bytes,
140 });
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::PersistenceSchema;
147 use crate::{Attribute, AttributeMap, Stream};
148
149 #[test]
150 fn registration_metadata_retains_sync_configuration() {
151 let attribute = Attribute::<String>::new("plain");
152 let attribute_map = AttributeMap::<String>::new("map").sync_to_attribute_store();
153 let schema = PersistenceSchema::new()
154 .attribute(&attribute)
155 .attribute_map(&attribute_map);
156
157 assert!(!schema.definitions[0].sync_to_attribute_store);
158 assert!(schema.definitions[1].sync_to_attribute_store);
159 }
160
161 #[test]
162 fn registration_metadata_retains_stream_identity_and_capacity() {
163 let stream = Stream::<String>::new("thinking", 1_048_576);
164 let schema = PersistenceSchema::new().stream(&stream);
165
166 assert_eq!(
167 schema.definitions[0].stream_identity,
168 Some(stream.identity())
169 );
170 assert_eq!(schema.definitions[0].max_estimated_bytes, Some(1_048_576));
171 }
172}