use crate::actors::document::DocActorResult;

/// Result of a document operation that includes both the closure result and any side effects.
///
/// When modifying a document via `with_document`, the operation may generate side effects
/// like storage operations (saving changes) or messages to be sent to connected peers.
/// This type encapsulates both the result of the user's closure and the side effects
/// that need to be executed.
///
/// # Type Parameters
///
/// * `T` - The type returned by the closure passed to `with_document`
///
/// # Example
///
/// ```text
/// let result = actor.with_document(|doc| {
///     // Modify document and return some value
///     doc.put_object(automerge::ROOT, "key", "value").unwrap()
/// })?;
///
/// // Access the closure result
/// let object_id = result.value;
///
/// // Execute any side effects
/// for io_task in result.actor_result.io_tasks {
///     // Execute storage operations
/// }
/// for message in result.actor_result.outgoing_messages {
///     // Send messages to main Samod
/// }
/// ```
#[derive(Debug)]
pub struct WithDocResult<T> {
    /// The result returned by the closure passed to `with_document`
    pub value: T,

    /// Any side effects generated by the document operation (IO tasks, messages, etc.)
    pub actor_result: DocActorResult,
}

impl<T> WithDocResult<T> {
    /// Creates a new result with the given value and empty side effects
    pub fn new(value: T) -> Self {
        Self {
            value,
            actor_result: DocActorResult::new(),
        }
    }

    /// Creates a new result with the given value and actor result
    pub fn with_side_effects(value: T, actor_result: DocActorResult) -> Self {
        Self {
            value,
            actor_result,
        }
    }
}
