use crate::SubmissionId;
use alloy::primitives::{Bytes, B256};
use newton_core::newton_prover_task_manager::INewtonProverTaskManager::{Task, TaskResponse};
use serde::{Deserialize, Serialize};
use std::fmt::{self, Write as _};
#[derive(Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BatchIntentItem {
pub submission_id: SubmissionId,
pub task: Task,
pub response: TaskResponse,
pub signature_data: Bytes,
pub attestation_data: Bytes,
pub expected_task_hash: B256,
pub expected_response_hash: B256,
}
impl fmt::Debug for BatchIntentItem {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("BatchIntentItem")
.field("submission_id", &self.submission_id)
.field("task_id", &self.task.taskId)
.field("signature_data_len", &self.signature_data.len())
.field("attestation_data_len", &self.attestation_data.len())
.field("expected_task_hash", &self.expected_task_hash)
.field("expected_response_hash", &self.expected_response_hash)
.finish()
}
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum TaskExecutionIntent {
#[serde(alias = "batch_create_and_respond")]
CreateAndRespond {
contract_role: String,
items: Vec<BatchIntentItem>,
},
#[serde(alias = "batch_respond")]
Respond {
contract_role: String,
items: Vec<BatchIntentItem>,
},
}
impl TaskExecutionIntent {
pub fn contract_role(&self) -> &str {
match self {
Self::CreateAndRespond { contract_role, .. } | Self::Respond { contract_role, .. } => contract_role,
}
}
pub fn items(&self) -> &[BatchIntentItem] {
match self {
Self::CreateAndRespond { items, .. } | Self::Respond { items, .. } => items,
}
}
}
impl fmt::Debug for TaskExecutionIntent {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::CreateAndRespond { contract_role, items } => formatter
.debug_struct("CreateAndRespond")
.field("contract_role", contract_role)
.field("items", items)
.finish(),
Self::Respond { contract_role, items } => formatter
.debug_struct("Respond")
.field("contract_role", contract_role)
.field("items", items)
.finish(),
}
}
}
pub fn task_ids_field(items: &[BatchIntentItem]) -> String {
join_ids(items.iter().map(|item| item.task.taskId))
}
pub fn submission_ids_field(items: &[BatchIntentItem]) -> String {
join_ids(items.iter().map(|item| item.submission_id))
}
fn join_ids<T: fmt::Display>(ids: impl Iterator<Item = T>) -> String {
let mut joined = String::new();
for id in ids {
if !joined.is_empty() {
joined.push(',');
}
let _ = write!(joined, "{id}");
}
joined
}