fluvio_stream_model/store/
metadata.rs

1use std::fmt::{Debug, Display};
2
3use tracing::trace;
4
5use crate::core::{Spec, MetadataContext, MetadataItem, MetadataRevExtension};
6use crate::store::LocalStore;
7
8pub type DefaultMetadataObject<S> = MetadataStoreObject<S, u32>;
9
10use super::DualDiff;
11use super::ChangeFlag;
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct MetadataStoreObject<S, C>
15where
16    S: Spec,
17    C: MetadataItem,
18{
19    pub spec: S,
20    pub status: S::Status,
21    pub key: S::IndexKey,
22    pub ctx: MetadataContext<C>,
23}
24
25#[derive(Debug, Clone, PartialEq)]
26pub struct MetadataStoreList<S, C>
27where
28    S: Spec,
29    C: MetadataItem,
30{
31    pub version: String,
32    pub items: Vec<MetadataStoreObject<S, C>>,
33}
34
35#[derive(Debug, Clone, PartialEq)]
36pub enum NameSpace {
37    All,
38    Named(String),
39}
40
41impl<S, C> MetadataStoreObject<S, C>
42where
43    S: Spec,
44    C: MetadataItem,
45    S::Status: Default,
46{
47    pub fn new(key: impl Into<S::IndexKey>, spec: S, status: S::Status) -> Self {
48        Self {
49            key: key.into(),
50            spec,
51            status,
52            ctx: MetadataContext::default(),
53        }
54    }
55
56    pub fn new_with_context(key: impl Into<S::IndexKey>, spec: S, ctx: MetadataContext<C>) -> Self {
57        Self {
58            key: key.into(),
59            spec,
60            status: S::Status::default(),
61            ctx,
62        }
63    }
64
65    pub fn with_spec(key: impl Into<S::IndexKey>, spec: S) -> Self
66    where
67        C: Default,
68    {
69        Self::new(key.into(), spec, S::Status::default())
70    }
71
72    pub fn with_key(key: impl Into<S::IndexKey>) -> Self {
73        Self::with_spec(key.into(), S::default())
74    }
75
76    pub fn with_context(mut self, ctx: impl Into<MetadataContext<C>>) -> Self {
77        self.ctx = ctx.into();
78        self
79    }
80
81    pub fn key(&self) -> &S::IndexKey {
82        &self.key
83    }
84
85    pub fn key_owned(&self) -> S::IndexKey {
86        self.key.clone()
87    }
88
89    pub fn my_key(self) -> S::IndexKey {
90        self.key
91    }
92
93    pub fn spec(&self) -> &S {
94        &self.spec
95    }
96
97    // set spec
98    pub fn set_spec(&mut self, spec: S) {
99        self.spec = spec;
100    }
101
102    pub fn status(&self) -> &S::Status {
103        &self.status
104    }
105
106    pub fn set_status(&mut self, status: S::Status) {
107        self.status = status;
108    }
109
110    pub fn ctx(&self) -> &MetadataContext<C> {
111        &self.ctx
112    }
113
114    pub fn ctx_mut(&mut self) -> &mut MetadataContext<C> {
115        &mut self.ctx
116    }
117
118    pub fn ctx_owned(&self) -> MetadataContext<C> {
119        self.ctx.clone()
120    }
121
122    pub fn set_ctx(&mut self, ctx: MetadataContext<C>) {
123        self.ctx = ctx;
124    }
125
126    pub fn parts(self) -> (S::IndexKey, S, S::Status, MetadataContext<C>) {
127        (self.key, self.spec, self.status, self.ctx)
128    }
129
130    /// check if metadata is owned by other
131    pub fn is_owned(&self, uid: &C::UId) -> bool {
132        match self.ctx().item().owner() {
133            Some(parent) => parent.uid() == uid,
134            None => false,
135        }
136    }
137
138    /// find children of this object
139    pub async fn childrens<T: Spec>(
140        &self,
141        child_stores: &LocalStore<T, C>,
142    ) -> Vec<MetadataStoreObject<T, C>> {
143        let my_uid = self.ctx().item().uid();
144        child_stores
145            .read()
146            .await
147            .values()
148            .filter(|child| child.is_owned(my_uid))
149            .map(|child| child.inner().clone())
150            .collect()
151    }
152
153    pub fn is_newer(&self, another: &Self) -> bool {
154        self.ctx.item().is_newer(another.ctx().item())
155    }
156}
157
158impl<S, C> DualDiff for MetadataStoreObject<S, C>
159where
160    S: Spec,
161    C: MetadataItem + PartialEq,
162{
163    /// compute difference, in our case we take account of version as well
164    fn diff(&self, new_value: &Self) -> ChangeFlag {
165        if self.is_newer(new_value) {
166            trace!("not newer");
167            ChangeFlag::no_change()
168        } else {
169            ChangeFlag {
170                spec: self.spec != new_value.spec,
171                status: self.status != new_value.status,
172                meta: self.ctx.item() != new_value.ctx.item(),
173            }
174        }
175    }
176}
177
178impl<S, C> MetadataStoreObject<S, C>
179where
180    S: Spec,
181    C: MetadataRevExtension,
182{
183    // create clone of my self with next rev, useful for testing and other
184    #[allow(unused)]
185    pub fn next_rev(&self) -> Self {
186        self.clone().with_context(self.ctx.next_rev())
187    }
188}
189
190impl<S, C> From<MetadataStoreObject<S, C>> for (S::IndexKey, S, S::Status)
191where
192    S: Spec,
193    C: MetadataItem,
194{
195    fn from(it: MetadataStoreObject<S, C>) -> Self {
196        (it.key, it.spec, it.status)
197    }
198}
199
200impl NameSpace {
201    pub fn as_str(&self) -> &str {
202        match self {
203            NameSpace::All => "all",
204            NameSpace::Named(s) => s.as_str(),
205        }
206    }
207}
208
209impl Display for NameSpace {
210    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
211        write!(f, "{}", self.as_str())
212    }
213}
214
215impl From<String> for NameSpace {
216    fn from(namespace: String) -> Self {
217        NameSpace::Named(namespace)
218    }
219}
220
221impl From<&str> for NameSpace {
222    fn from(namespace: &str) -> Self {
223        NameSpace::Named(namespace.to_owned())
224    }
225}