k8_types/
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, Eq, 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> From<MetaItem<S>> for (S::Key, S, S::Status)
122where
123    S: StoreSpec,
124{
125    fn from(val: MetaItem<S>) -> Self {
126        (val.key, val.spec, val.status)
127    }
128}
129
130#[derive(Default, Debug, Eq, 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
156/// define default store spec assuming key is string
157#[macro_export]
158macro_rules! default_store_spec {
159    ($spec:ident,$status:ident,$name:expr) => {
160        impl $crate::store::StoreSpec for $spec {
161            const LABEL: &'static str = $name;
162
163            type K8Spec = Self;
164            type Status = $status;
165            type Key = String;
166            type Owner = Self;
167
168            fn convert_from_k8(
169                k8_obj: $crate::K8Obj<Self::K8Spec>,
170            ) -> Result<Option<$crate::store::MetaItem<Self>>, std::io::Error> {
171                let ctx =
172                    $crate::store::MetaItemContext::default().with_ctx(k8_obj.metadata.clone());
173                Ok(Some($crate::store::MetaItem::new(
174                    k8_obj.metadata.name,
175                    k8_obj.spec,
176                    k8_obj.status,
177                    ctx,
178                )))
179            }
180        }
181    };
182}