use std::{env, path::PathBuf};
use cargo_metadata::Package;
use derive_builder::Builder;
use risc0_zkos_v1compat::V1COMPAT_ELF;
use serde::{Deserialize, Serialize};
use crate::DEFAULT_DOCKER_TAG;
#[derive(Clone, Debug, Default, Serialize, Deserialize, Builder)]
#[builder(default)]
#[non_exhaustive]
pub struct DockerOptions {
#[builder(setter(into, strip_option))]
pub root_dir: Option<PathBuf>,
pub env: Vec<(String, String)>,
#[builder(setter(into, strip_option))]
pub docker_container_tag: Option<String>,
}
impl DockerOptions {
pub fn root_dir(&self) -> PathBuf {
self.root_dir
.clone()
.unwrap_or_else(|| env::current_dir().unwrap())
}
pub fn env(&self) -> Vec<(&str, &str)> {
self.env
.iter()
.map(|(key, val)| (key.as_str(), val.as_str()))
.collect()
}
pub fn docker_container_tag(&self) -> String {
if let Ok(tag) = env::var("RISC0_DOCKER_CONTAINER_TAG") {
return tag;
}
self.docker_container_tag
.clone()
.unwrap_or(DEFAULT_DOCKER_TAG.to_string())
}
}
#[derive(Default, Clone, Debug, Builder)]
#[builder(default)]
#[non_exhaustive]
pub struct GuestOptions {
pub features: Vec<String>,
#[builder(setter(strip_option))]
pub use_docker: Option<DockerOptions>,
#[builder(setter(strip_option))]
pub kernel: Option<Vec<u8>>,
}
impl GuestOptions {
pub fn kernel(&self) -> Vec<u8> {
self.kernel.clone().unwrap_or_else(|| V1COMPAT_ELF.to_vec())
}
}
#[derive(Serialize, Deserialize, Clone, Default)]
pub(crate) struct GuestMetadata {
#[serde(rename = "rustc-flags")]
pub(crate) rustc_flags: Option<Vec<String>>,
#[serde(default)]
pub(crate) kernel: bool,
}
impl From<&Package> for GuestMetadata {
fn from(pkg: &Package) -> Self {
let Some(obj) = pkg.metadata.get("risc0") else {
return Default::default();
};
serde_json::from_value(obj.clone()).unwrap()
}
}
#[derive(Default, Clone)]
pub(crate) struct GuestInfo {
pub(crate) options: GuestOptions,
pub(crate) metadata: GuestMetadata,
}