1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use derivative::Derivative;
use k8s_openapi::{apimachinery::pkg::apis::meta::v1::OwnerReference, Resource};
use kube::api::Meta;
use std::{fmt::Debug, hash::Hash};
#[derive(Derivative)]
#[derivative(Debug, PartialEq, Eq, Hash, Clone)]
pub struct ObjectRef<K: RuntimeResource> {
kind: K::State,
pub name: String,
pub namespace: Option<String>,
}
impl<K: Meta> ObjectRef<K> {
#[must_use]
pub fn new(name: &str) -> Self {
Self {
kind: (),
name: name.into(),
namespace: None,
}
}
pub fn within(mut self, namespace: &str) -> Self {
self.namespace = Some(namespace.to_string());
self
}
#[must_use]
pub fn from_obj(obj: &K) -> Self {
Self {
kind: (),
name: obj.name(),
namespace: obj.namespace(),
}
}
#[must_use]
pub fn from_owner_ref(namespace: Option<&str>, owner: &OwnerReference) -> Option<Self> {
if owner.api_version == K::API_VERSION && owner.kind == K::KIND {
Some(Self {
kind: (),
name: owner.name.clone(),
namespace: namespace.map(String::from),
})
} else {
None
}
}
}
pub trait RuntimeResource {
type State: Debug + PartialEq + Eq + Hash + Clone;
fn group(state: &Self::State) -> &str;
fn version(state: &Self::State) -> &str;
fn kind(state: &Self::State) -> &str;
}
impl<K: Resource> RuntimeResource for K {
type State = ();
fn group(_state: &Self::State) -> &str {
K::GROUP
}
fn version(_state: &Self::State) -> &str {
K::VERSION
}
fn kind(_state: &Self::State) -> &str {
K::KIND
}
}
#[allow(clippy::empty_enum)]
pub enum ErasedResource {}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct ErasedResourceState {
group: &'static str,
version: &'static str,
kind: &'static str,
}
impl RuntimeResource for ErasedResource {
type State = ErasedResourceState;
fn group(state: &Self::State) -> &str {
&state.group
}
fn version(state: &Self::State) -> &str {
&state.version
}
fn kind(state: &Self::State) -> &str {
&state.kind
}
}
impl ErasedResource {
fn erase<K: Resource>() -> ErasedResourceState {
ErasedResourceState {
group: K::GROUP,
version: K::VERSION,
kind: K::KIND,
}
}
}
impl<K: Resource> From<ObjectRef<K>> for ObjectRef<ErasedResource> {
fn from(old: ObjectRef<K>) -> Self {
ObjectRef {
kind: ErasedResource::erase::<K>(),
name: old.name,
namespace: old.namespace,
}
}
}