use std::boxed::Box;
use std::collections::HashMap;
use async_trait::async_trait;
use serde::Serialize;
use tokio::io::AsyncRead;
use crate::image::{
docker::reference::types::DockerImageReference, oci::digest::Digest,
oci::spec_v1::Image as OCIv1Image,
};
pub type ImageResult<T> = Result<T, errors::ImageError>;
pub trait ImageTransport: std::fmt::Debug {
fn name(&self) -> String;
fn parse_reference<'s>(&self, reference: &'s str) -> ImageResult<Box<dyn ImageReference + 's>>;
#[doc(hidden)]
fn cloned(&self) -> Box<dyn ImageTransport + Send + Sync>;
}
impl Clone for Box<dyn ImageTransport + Send + Sync> {
fn clone(&self) -> Self {
self.cloned()
}
}
pub trait ImageReference: std::fmt::Debug {
fn transport(&self) -> Box<dyn ImageTransport + Send + Sync>;
fn string_within_transport(&self) -> String;
fn new_image_source(&self) -> ImageResult<Box<dyn ImageSource + Send + Sync>>;
fn new_image(&self) -> ImageResult<Box<dyn Image + Send + Sync>>;
fn docker_reference(&self) -> Option<Box<dyn DockerImageReference>> {
None
}
}
#[async_trait]
pub trait ImageSource: std::fmt::Debug {
fn reference(&self) -> Box<dyn ImageReference>;
async fn get_manifest(&mut self, digest: Option<&Digest>) -> ImageResult<ImageManifest>;
async fn get_blob(
&self,
digest: &Digest,
) -> ImageResult<Box<dyn AsyncRead + Unpin + Send + Sync>>;
async fn get_repo_tags(&self) -> ImageResult<Vec<String>>;
}
#[async_trait]
pub trait Image: std::fmt::Debug {
fn source_ref(&self) -> &(dyn ImageSource + Send + Sync);
fn reference(&self) -> Box<dyn ImageReference>;
async fn manifest(&mut self) -> ImageResult<ImageManifest>;
async fn resolved_manifest(&mut self) -> ImageResult<ImageManifest>;
async fn config_blob(&mut self) -> ImageResult<Vec<u8>>;
async fn oci_config(&mut self) -> ImageResult<OCIv1Image>;
async fn inspect(&mut self) -> ImageResult<ImageInspect>;
}
#[derive(Debug, Clone)]
pub struct ImageManifest {
pub manifest: Vec<u8>,
pub mime_type: String,
}
#[derive(Debug, Serialize)]
pub struct ImageInspect {
#[serde(rename = "Created")]
pub created: String,
#[serde(rename = "DockerVersion")]
pub docker_version: String,
#[serde(rename = "Labels")]
pub labels: HashMap<String, String>,
#[serde(rename = "Architecture")]
pub architecture: String,
#[serde(rename = "Os")]
pub os: String,
#[serde(rename = "Layers")]
pub layers: Vec<String>,
#[serde(rename = "Env")]
pub env: Vec<String>,
}
pub mod errors;