Skip to main content

soma_infra/
mutation.rs

1use serde::{Deserialize, Serialize};
2use soma_ops::MutationSendState;
3
4use crate::InfraError;
5
6/// Infrastructure mutation failure with explicit backend send state.
7#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
8#[error("infrastructure mutation failed after send state {send_state:?}: {error}")]
9pub struct MutationFailure {
10    send_state: MutationSendState,
11    error: InfraError,
12}
13
14impl MutationFailure {
15    /// Creates a mutation failure without discarding send uncertainty.
16    #[must_use]
17    pub const fn new(send_state: MutationSendState, error: InfraError) -> Self {
18        Self { send_state, error }
19    }
20
21    /// Returns whether the mutation may have reached the backend.
22    #[must_use]
23    pub const fn send_state(&self) -> MutationSendState {
24        self.send_state
25    }
26
27    /// Returns the underlying infrastructure failure.
28    #[must_use]
29    pub const fn error(&self) -> &InfraError {
30        &self.error
31    }
32
33    /// Consumes the wrapper and returns the infrastructure failure.
34    #[must_use]
35    pub fn into_error(self) -> InfraError {
36        self.error
37    }
38}
39
40/// Result type for infrastructure mutations.
41pub type MutationResult<T> = Result<T, MutationFailure>;
42
43pub(crate) fn sha256_hex(bytes: &[u8]) -> String {
44    use sha2::{Digest, Sha256};
45    Sha256::digest(bytes)
46        .iter()
47        .map(|byte| format!("{byte:02x}"))
48        .collect()
49}
50
51/// Stable verification detail for a mutation outcome.
52#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
53pub struct MutationVerification {
54    /// Verification status text suitable for canonical result details.
55    pub status: String,
56    /// Bounded verification explanation.
57    pub summary: String,
58}
59
60#[cfg(test)]
61#[path = "mutation_tests.rs"]
62mod tests;