lenso_app_plan/authoring/plugin_root/
release.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use super::{PluginDescriptor, empty_configuration};
5use crate::{
6 CapabilityEndpointPlan, CapabilityRequirementPlan, ExecutionClassId, PluginCriticality,
7 RestartPolicy,
8};
9
10#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
12#[serde(deny_unknown_fields)]
13pub struct PluginContract {
14 #[serde(default = "crate::schema::old_authoring_version")]
15 authoring_version: u32,
16 plugin_id: String,
17 release_version: String,
18 root_slot: String,
19 #[serde(default, skip_serializing_if = "Option::is_none")]
20 configuration_schema: Option<Value>,
21 #[serde(
22 default = "empty_configuration",
23 skip_serializing_if = "super::is_empty_configuration"
24 )]
25 configuration_defaults: Value,
26 provided_capabilities: Vec<CapabilityEndpointPlan>,
27 required_capabilities: Vec<CapabilityRequirementPlan>,
28 restart_policy: RestartPolicy,
29 criticality: PluginCriticality,
30}
31
32impl PluginContract {
33 pub fn new(
34 plugin_id: impl Into<String>,
35 release_version: impl Into<String>,
36 root_slot: impl Into<String>,
37 ) -> Self {
38 Self {
39 authoring_version: 1,
40 plugin_id: plugin_id.into(),
41 release_version: release_version.into(),
42 root_slot: root_slot.into(),
43 configuration_schema: None,
44 configuration_defaults: empty_configuration(),
45 provided_capabilities: Vec::new(),
46 required_capabilities: Vec::new(),
47 restart_policy: RestartPolicy::default(),
48 criticality: PluginCriticality::default(),
49 }
50 }
51
52 #[must_use]
53 pub fn with_configuration_schema(mut self, schema: Value) -> Self {
54 self.configuration_schema = Some(schema);
55 self
56 }
57
58 #[must_use]
59 pub const fn with_authoring_version(mut self, version: u32) -> Self {
60 self.authoring_version = version;
61 self
62 }
63
64 pub const fn authoring_version(&self) -> u32 {
65 self.authoring_version
66 }
67
68 #[must_use]
69 pub fn with_configuration_defaults(mut self, defaults: Value) -> Self {
70 self.configuration_defaults = defaults;
71 self
72 }
73
74 #[must_use]
75 pub fn with_capability(mut self, capability: CapabilityEndpointPlan) -> Self {
76 self.provided_capabilities.push(capability);
77 self
78 }
79
80 #[must_use]
81 pub fn with_requirement(mut self, requirement: CapabilityRequirementPlan) -> Self {
82 self.required_capabilities.push(requirement);
83 self
84 }
85
86 #[must_use]
87 pub const fn with_restart_policy(mut self, restart_policy: RestartPolicy) -> Self {
88 self.restart_policy = restart_policy;
89 self
90 }
91
92 #[must_use]
93 pub const fn with_criticality(mut self, criticality: PluginCriticality) -> Self {
94 self.criticality = criticality;
95 self
96 }
97
98 pub fn plugin_id(&self) -> &str {
99 &self.plugin_id
100 }
101
102 pub fn release_version(&self) -> &str {
103 &self.release_version
104 }
105
106 pub fn root_slot(&self) -> &str {
107 &self.root_slot
108 }
109
110 pub const fn configuration_schema(&self) -> Option<&Value> {
111 self.configuration_schema.as_ref()
112 }
113
114 pub const fn configuration_defaults(&self) -> &Value {
115 &self.configuration_defaults
116 }
117
118 pub fn provided_capabilities(&self) -> &[CapabilityEndpointPlan] {
119 &self.provided_capabilities
120 }
121
122 pub fn required_capabilities(&self) -> &[CapabilityRequirementPlan] {
123 &self.required_capabilities
124 }
125
126 pub const fn restart_policy(&self) -> RestartPolicy {
127 self.restart_policy
128 }
129
130 pub const fn criticality(&self) -> PluginCriticality {
131 self.criticality
132 }
133
134 pub fn resolve(&self, implementation: &PluginImplementation) -> PluginDescriptor {
136 let mut descriptor =
137 PluginDescriptor::new(&self.plugin_id, &self.release_version, &self.root_slot)
138 .with_authoring(self.authoring_version, implementation.runtime_profile())
139 .with_runtime_package(
140 &implementation.runtime_package_id,
141 &implementation.runtime_package_revision,
142 )
143 .with_entrypoint(&implementation.entrypoint)
144 .with_configuration_defaults(self.configuration_defaults.clone())
145 .with_execution_class(implementation.execution_class.clone())
146 .with_restart_policy(self.restart_policy)
147 .with_criticality(self.criticality);
148 if let Some(schema) = &self.configuration_schema {
149 descriptor = descriptor.with_configuration_schema(schema.clone());
150 }
151 for capability in &self.provided_capabilities {
152 descriptor = descriptor.with_capability(capability.clone());
153 }
154 for requirement in &self.required_capabilities {
155 descriptor = descriptor.with_requirement(requirement.clone());
156 }
157 descriptor
158 }
159}
160
161#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
163#[serde(deny_unknown_fields)]
164pub struct PluginImplementation {
165 #[serde(default)]
166 runtime_profile: String,
167 runtime_package_id: String,
168 runtime_package_revision: String,
169 entrypoint: String,
170 execution_class: ExecutionClassId,
171}
172
173impl PluginImplementation {
174 pub fn new(
175 runtime_package_id: impl Into<String>,
176 runtime_package_revision: impl Into<String>,
177 entrypoint: impl Into<String>,
178 execution_class: ExecutionClassId,
179 ) -> Self {
180 Self {
181 runtime_profile: crate::schema::old_runtime_profile(&execution_class),
182 runtime_package_id: runtime_package_id.into(),
183 runtime_package_revision: runtime_package_revision.into(),
184 entrypoint: entrypoint.into(),
185 execution_class,
186 }
187 }
188
189 pub fn runtime_package_id(&self) -> &str {
190 &self.runtime_package_id
191 }
192
193 #[must_use]
194 pub fn with_runtime_profile(mut self, profile: impl Into<String>) -> Self {
195 self.runtime_profile = profile.into();
196 self
197 }
198
199 pub fn runtime_profile(&self) -> &str {
200 if self.runtime_profile.is_empty() {
201 self.execution_class.as_str()
202 } else {
203 &self.runtime_profile
204 }
205 }
206
207 pub fn runtime_package_revision(&self) -> &str {
208 &self.runtime_package_revision
209 }
210
211 pub fn entrypoint(&self) -> &str {
212 &self.entrypoint
213 }
214
215 pub const fn execution_class(&self) -> &ExecutionClassId {
216 &self.execution_class
217 }
218}
219
220impl PluginDescriptor {
221 pub fn contract(&self) -> PluginContract {
223 PluginContract {
224 authoring_version: self.authoring_version,
225 plugin_id: self.plugin_id.clone(),
226 release_version: self.release_version.clone(),
227 root_slot: self.root_slot.clone(),
228 configuration_schema: self.configuration_schema.clone(),
229 configuration_defaults: self.configuration_defaults.clone(),
230 provided_capabilities: self.provided_capabilities.clone(),
231 required_capabilities: self.required_capabilities.clone(),
232 restart_policy: self.restart_policy,
233 criticality: self.criticality,
234 }
235 }
236
237 pub fn implementation(&self) -> PluginImplementation {
239 PluginImplementation {
240 runtime_profile: self.runtime_profile().to_owned(),
241 runtime_package_id: self.runtime_package_id.clone(),
242 runtime_package_revision: self.runtime_package_revision.clone(),
243 entrypoint: self.entrypoint.clone(),
244 execution_class: self.execution_class.clone(),
245 }
246 }
247}