///|
pub(all) struct JSONRewrite {
content : String
lineage : @data.Lineage?
}
///|
pub(all) enum Component {
Native((@ir.IRFile) -> @data.Rewrite raise)
JSON((String) -> JSONRewrite raise)
}
///|
priv struct ComponentStep {
name : String
component : Component
policy_name : String
policy : @data.MetadataPolicy
}
///|
pub(all) struct ComponentBoundary {
name : String
transport : String
metadata_policy : String
}
///|
pub fn Engine::register_component(
self : Engine,
name : String,
component : Component,
) -> Unit raise {
if name == "" || self.components.contains(name) {
raise @configuration.Invalid("component.registration_conflict: " + name)
}
self.components[name] = component
}
///|
pub fn Engine::register_metadata_policy(
self : Engine,
name : String,
policy : @data.MetadataPolicy,
) -> Unit raise {
if name == "" || self.metadata_policies.contains(name) {
raise @configuration.Invalid("component.policy_conflict: " + name)
}
self.metadata_policies[name] = policy
}
///|
fn apply_component(
unit : @data.IRUnit,
step : ComponentStep,
) -> @data.IRUnit raise {
let rewrite = match step.component {
Native(run) => run(unit.distribution)
JSON(run) => {
let result = run(@data.semantic_json(unit))
{ distribution: @ir_json.read(result.content), lineage: result.lineage, }
}
}
@data.apply_rewrite(unit, rewrite, step.name, step.policy_name, step.policy)
}
///|
pub fn Plan::component_boundaries(self : Plan) -> Array[ComponentBoundary] {
let result = []
for job in self.jobs {
for step in job.components {
result.push({
name: step.name,
transport: match step.component {
Native(_) => "native-ir"
JSON(_) => "morphir-json"
},
metadata_policy: step.policy_name,
})
}
}
result
}