use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecFile {
pub name: String,
#[serde(with = "serde_bytes")]
pub content: Vec<u8>,
#[serde(default)]
pub mime_type: Option<String>,
}
mod serde_bytes {
use base64::Engine;
use serde::{Deserialize, Deserializer, Serializer};
pub fn serialize<S: Serializer>(bytes: &[u8], s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(&base64::engine::general_purpose::STANDARD.encode(bytes))
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
use serde::de::Error;
let s: String = String::deserialize(d)?;
base64::engine::general_purpose::STANDARD
.decode(s.as_bytes())
.map_err(D::Error::custom)
}
}
#[derive(Debug, Clone, Default)]
pub struct CodeExecutionInput {
pub code: String,
pub language: String,
pub input_files: Vec<ExecFile>,
pub execution_id: Option<String>,
}
#[derive(Debug, Clone, Default)]
pub struct CodeExecutionResult {
pub stdout: String,
pub stderr: String,
pub output_files: Vec<ExecFile>,
pub exit_code: Option<i32>,
}
impl CodeExecutionResult {
#[must_use]
pub fn combined_output(&self) -> String {
if self.stderr.is_empty() {
self.stdout.clone()
} else if self.stdout.is_empty() {
self.stderr.clone()
} else {
format!("{}\n--- stderr ---\n{}", self.stdout, self.stderr)
}
}
#[must_use]
pub fn is_success(&self) -> bool {
match self.exit_code {
Some(0) => true,
Some(_) => false,
None => self.stderr.is_empty(),
}
}
}