Skip to main content

lightshuttle_export/
lower.rs

1//! Lowering: turn a parsed manifest into the neutral [`ExportModel`].
2
3use lightshuttle_manifest::Manifest;
4use lightshuttle_spec::from_resource;
5
6use crate::error::{ExportError, Result};
7use crate::model::{ExportModel, ExportProject, ExportService};
8
9/// Lower `manifest` into an [`ExportModel`].
10///
11/// Each resource is resolved through `lightshuttle-spec`, so the model
12/// inherits the same image, port, environment and healthcheck defaults
13/// the runtime applies, with no drift between `up` and `export`. The
14/// raw `export:` section is carried through for per-target resolution.
15///
16/// # Errors
17///
18/// Returns [`ExportError::Spec`] if a resource cannot be resolved into a
19/// container specification.
20pub fn lower(manifest: &Manifest) -> Result<ExportModel> {
21    let project = ExportProject {
22        name: manifest.project.name.clone(),
23        version: manifest.project.version.clone(),
24    };
25
26    let mut services = Vec::with_capacity(manifest.resources.len());
27    for (name, kind) in &manifest.resources {
28        let resolved = from_resource(&manifest.project.name, name, kind).map_err(|source| {
29            ExportError::Spec {
30                resource: name.clone(),
31                source,
32            }
33        })?;
34        services.push(ExportService {
35            spec: resolved.spec,
36            depends_on: kind.depends_on().to_vec(),
37        });
38    }
39
40    Ok(ExportModel {
41        project,
42        services,
43        export: manifest.export.clone(),
44    })
45}