use async_trait::async_trait;

/// Trait that all executable jobs must implement
#[async_trait]
pub trait Executable: Send + Sync + Clone {
    /// The output type returned by the job execution
    type Output: Send;

    /// Execute the job
    async fn execute(&mut self) -> Self::Output;

    /// Hook called before job execution
    async fn pre_execute(&mut self) {
        // Default implementation does nothing
    }

    /// Hook called after job execution
    async fn post_execute(&mut self, output: Self::Output) -> Self::Output {
        output
    }

    /// Determine if the output represents a failure
    async fn is_failed_output(&self, _output: &Self::Output) -> bool {
        false
    }
}
