k8_obj_metadata/
store.rs

1use std::fmt;
2use std::fmt::Debug;
3use std::fmt::Display;
4use std::io::Error as IoError;
5
6use crate::K8Obj;
7use crate::ObjectMeta;
8use crate::Spec;
9
10// Spec that can store in meta store
11pub trait StoreSpec: Sized + Default + Debug + Clone {
12    type K8Spec: Spec;
13    type Status: Sized + Clone + Default + Debug;
14    type Key: Ord + Clone + Debug + ToString;
15    type Owner: StoreSpec;
16
17    const LABEL: &'static str;
18
19    // convert kubernetes objects into KV value
20    fn convert_from_k8(k8_obj: K8Obj<Self::K8Spec>) -> Result<Option<MetaItem<Self>>, IoError>;
21}
22
23/// Metadata object. Used to be KVObject int sc-core
24#[derive(Debug, Clone, PartialEq)]
25pub struct MetaItem<S>
26where
27    S: StoreSpec,
28{
29    pub spec: S,
30    pub status: S::Status,
31    pub key: S::Key,
32    pub ctx: MetaItemContext,
33}
34
35impl<S> MetaItem<S>
36where
37    S: StoreSpec,
38{
39    pub fn new<J>(key: J, spec: S, status: S::Status, ctx: MetaItemContext) -> Self
40    where
41        J: Into<S::Key>,
42    {
43        Self {
44            key: key.into(),
45            spec,
46            status,
47            ctx,
48        }
49    }
50
51    pub fn with_ctx(mut self, ctx: MetaItemContext) -> Self {
52        self.ctx = ctx;
53        self
54    }
55
56    pub fn key(&self) -> &S::Key {
57        &self.key
58    }
59
60    pub fn key_owned(&self) -> S::Key {
61        self.key.clone()
62    }
63
64    pub fn my_key(self) -> S::Key {
65        self.key
66    }
67
68    pub fn spec(&self) -> &S {
69        &self.spec
70    }
71    pub fn status(&self) -> &S::Status {
72        &self.status
73    }
74
75    pub fn set_status(&mut self, status: S::Status) {
76        self.status = status;
77    }
78
79    pub fn ctx(&self) -> &MetaItemContext {
80        &self.ctx
81    }
82
83    pub fn set_ctx(&mut self, ctx: MetaItemContext) {
84        self.ctx = ctx;
85    }
86
87    pub fn parts(self) -> (S::Key, S, MetaItemContext) {
88        (self.key, self.spec, self.ctx)
89    }
90
91    pub fn is_owned(&self, uid: &str) -> bool {
92        match &self.ctx.parent_ctx {
93            Some(parent) => parent.uid == uid,
94            None => false,
95        }
96    }
97
98    pub fn with_spec<J>(key: J, spec: S) -> Self
99    where
100        J: Into<S::Key>,
101    {
102        Self::new(
103            key.into(),
104            spec,
105            S::Status::default(),
106            MetaItemContext::default(),
107        )
108    }
109}
110
111impl<S> fmt::Display for MetaItem<S>
112where
113    S: StoreSpec,
114    S::Key: Display,
115{
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        write!(f, "MetaItem {} key: {}", S::LABEL, self.key())
118    }
119}
120
121impl<S> Into<(S::Key, S, S::Status)> for MetaItem<S>
122where
123    S: StoreSpec,
124{
125    fn into(self) -> (S::Key, S, S::Status) {
126        (self.key, self.spec, self.status)
127    }
128}
129
130#[derive(Debug, PartialEq, Clone)]
131pub struct MetaItemContext {
132    pub item_ctx: Option<ObjectMeta>,
133    pub parent_ctx: Option<ObjectMeta>,
134}
135
136impl MetaItemContext {
137    pub fn with_ctx(mut self, ctx: ObjectMeta) -> Self {
138        self.item_ctx = Some(ctx);
139        self
140    }
141
142    pub fn with_parent_ctx(mut self, ctx: ObjectMeta) -> Self {
143        self.parent_ctx = Some(ctx);
144        self
145    }
146
147    pub fn make_parent_ctx(&self) -> Self {
148        if self.item_ctx.is_some() {
149            Self::default().with_parent_ctx(self.item_ctx.as_ref().unwrap().clone())
150        } else {
151            Self::default()
152        }
153    }
154}
155
156impl ::std::default::Default for MetaItemContext {
157    fn default() -> Self {
158        Self {
159            item_ctx: None,
160            parent_ctx: None,
161        }
162    }
163}
164
165/// define default store spec assuming key is string
166#[macro_export]
167macro_rules! default_store_spec {
168    ($spec:ident,$status:ident,$name:expr) => {
169        impl k8_obj_metadata::store::StoreSpec for $spec {
170            const LABEL: &'static str = $name;
171
172            type K8Spec = Self;
173            type Status = $status;
174            type Key = String;
175            type Owner = Self;
176
177            fn convert_from_k8(
178                k8_obj: k8_obj_metadata::K8Obj<Self::K8Spec>,
179            ) -> Result<Option<k8_obj_metadata::store::MetaItem<Self>>, std::io::Error> {
180                let ctx = k8_obj_metadata::store::MetaItemContext::default()
181                    .with_ctx(k8_obj.metadata.clone());
182                Ok(Some(k8_obj_metadata::store::MetaItem::new(
183                    k8_obj.metadata.name,
184                    k8_obj.spec,
185                    k8_obj.status,
186                    ctx,
187                )))
188            }
189        }
190    };
191}