pub(crate) mod handling;
use crate::Buildpack;
#[allow(unused)]
use crate::build::BuildContext;
use crate::layer::shared::{WriteLayerError, replace_layer_exec_d_programs, replace_layer_sboms};
use crate::layer::{LayerError, ReadLayerError};
use crate::layer_env::LayerEnv;
use crate::sbom::Sbom;
use libcnb_data::generic::GenericMetadata;
use libcnb_data::layer::LayerName;
use serde::Serialize;
use std::borrow::Borrow;
use std::collections::HashMap;
use std::marker::PhantomData;
use std::path::{Path, PathBuf};
pub struct CachedLayerDefinition<'a, M, MA, RA> {
pub build: bool,
pub launch: bool,
pub invalid_metadata_action: &'a dyn Fn(&GenericMetadata) -> MA,
pub restored_layer_action: &'a dyn Fn(&M, &Path) -> RA,
}
pub struct UncachedLayerDefinition {
pub build: bool,
pub launch: bool,
}
#[derive(Copy, Clone, Debug)]
pub enum InvalidMetadataAction<M> {
DeleteLayer,
ReplaceMetadata(M),
}
#[derive(Copy, Clone, Debug)]
pub enum RestoredLayerAction {
DeleteLayer,
KeepLayer,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum LayerState<MAC, RAC> {
Restored { cause: RAC },
Empty { cause: EmptyLayerCause<MAC, RAC> },
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum EmptyLayerCause<MAC, RAC> {
NewlyCreated,
InvalidMetadataAction { cause: MAC },
RestoredLayerAction { cause: RAC },
}
pub trait IntoAction<T, C, E> {
fn into_action(self) -> Result<(T, C), E>;
}
impl<T, E> IntoAction<T, (), E> for T {
fn into_action(self) -> Result<(T, ()), E> {
Ok((self, ()))
}
}
impl<T, E> IntoAction<T, (), E> for Result<T, E> {
fn into_action(self) -> Result<(T, ()), E> {
self.map(|value| (value, ()))
}
}
impl<T, C, E> IntoAction<T, C, E> for (T, C) {
fn into_action(self) -> Result<(T, C), E> {
Ok(self)
}
}
impl<T, C, E> IntoAction<T, C, E> for Result<(T, C), E> {
fn into_action(self) -> Result<(T, C), E> {
self
}
}
pub struct LayerRef<B, MAC, RAC>
where
B: Buildpack + ?Sized,
{
name: LayerName,
layers_dir: PathBuf,
buildpack: PhantomData<B>,
pub state: LayerState<MAC, RAC>,
}
impl<B, MAC, RAC> LayerRef<B, MAC, RAC>
where
B: Buildpack,
{
pub fn path(&self) -> PathBuf {
self.layers_dir.join(self.name.as_str())
}
pub fn write_metadata<M>(&self, metadata: M) -> crate::Result<(), B::Error>
where
M: Serialize,
{
crate::layer::shared::replace_layer_metadata(&self.layers_dir, &self.name, metadata)
.map_err(|error| {
crate::Error::LayerError(LayerError::WriteLayerError(
WriteLayerError::WriteLayerMetadataError(error),
))
})
}
pub fn write_env(&self, env: impl Borrow<LayerEnv>) -> crate::Result<(), B::Error> {
env.borrow()
.write_to_layer_dir(self.path())
.map_err(|error| {
crate::Error::LayerError(LayerError::WriteLayerError(WriteLayerError::IoError(
error,
)))
})
}
pub fn read_env(&self) -> crate::Result<LayerEnv, B::Error> {
LayerEnv::read_from_layer_dir(self.path()).map_err(|error| {
crate::Error::LayerError(LayerError::ReadLayerError(ReadLayerError::IoError(error)))
})
}
pub fn write_sboms(&self, sboms: &[Sbom]) -> crate::Result<(), B::Error> {
replace_layer_sboms(&self.layers_dir, &self.name, sboms).map_err(|error| {
crate::Error::LayerError(LayerError::WriteLayerError(
WriteLayerError::ReplaceLayerSbomsError(error),
))
})
}
pub fn write_exec_d_programs<P, S>(&self, programs: P) -> crate::Result<(), B::Error>
where
S: Into<String>,
P: IntoIterator<Item = (S, PathBuf)>,
{
let programs = programs
.into_iter()
.map(|(k, v)| (k.into(), v))
.collect::<HashMap<_, _>>();
replace_layer_exec_d_programs(&self.layers_dir, &self.name, &programs).map_err(|error| {
crate::Error::LayerError(LayerError::WriteLayerError(
WriteLayerError::ReplaceLayerExecdProgramsError(error),
))
})
}
}