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
10pub 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 fn convert_from_k8(k8_obj: K8Obj<Self::K8Spec>) -> Result<Option<MetaItem<Self>>, IoError>;
21}
22
23#[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#[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}