safer_ring/operation/
completed.rs

1//! Completed state implementation for finished operations.
2//!
3//! This module contains functionality for operations that have completed
4//! and contain their results.
5
6use std::os::unix::io::RawFd;
7use std::pin::Pin;
8
9use super::core::{BufferType, FdType, Operation};
10use crate::operation::{Completed, OperationType};
11
12impl<'ring, 'buf, T> Operation<'ring, 'buf, Completed<T>> {
13    /// Extract the result from the completed operation.
14    ///
15    /// This consumes the operation and returns both the result and the buffer
16    /// ownership, ensuring no resource leaks. This is the primary way to
17    /// retrieve results from completed operations.
18    ///
19    /// # Returns
20    ///
21    /// A tuple containing:
22    /// - The operation result
23    /// - The buffer (if one was used), returned to the caller for reuse
24    ///
25    /// # Example
26    ///
27    /// ```rust,no_run
28    /// # use safer_ring::operation::Operation;
29    /// # let completed_op: Operation<'_, '_, safer_ring::operation::Completed<i32>> = todo!();
30    /// let (bytes_read, buffer) = completed_op.into_result();
31    /// println!("Read {} bytes", bytes_read);
32    /// // Buffer can now be reused for another operation
33    /// ```
34    pub fn into_result(self) -> (T, BufferType<'buf>) {
35        (self.state.result, self.buffer)
36    }
37
38    /// Extract the result and return a pinned buffer if available.
39    ///
40    /// This is a convenience method for operations that use regular pinned buffers.
41    /// For other buffer types, use `into_result()` instead.
42    pub fn into_result_with_buffer(self) -> (T, Option<Pin<&'buf mut [u8]>>) {
43        let (result, buffer_type) = self.into_result();
44        let buffer = match buffer_type {
45            BufferType::Pinned(buf) => Some(buf),
46            _ => None,
47        };
48        (result, buffer)
49    }
50
51    /// Extract the result and return vectored buffers if available.
52    ///
53    /// This is a convenience method for vectored operations.
54    pub fn into_result_with_vectored_buffers(self) -> (T, Option<Vec<Pin<&'buf mut [u8]>>>) {
55        let (result, buffer_type) = self.into_result();
56        let buffers = match buffer_type {
57            BufferType::Vectored(bufs) => Some(bufs),
58            _ => None,
59        };
60        (result, buffers)
61    }
62
63    /// Get a reference to the result without consuming the operation.
64    ///
65    /// This allows inspecting the result while keeping the operation intact.
66    #[inline]
67    pub fn result(&self) -> &T {
68        &self.state.result
69    }
70
71    /// Get the file descriptor for this operation.
72    #[inline]
73    pub fn fd(&self) -> RawFd {
74        match &self.fd {
75            FdType::Raw(fd) => *fd,
76            FdType::Registered(reg_fd) => reg_fd.raw_fd(),
77            FdType::Fixed(fixed_file) => fixed_file.raw_fd(),
78        }
79    }
80
81    /// Get the offset for this operation.
82    #[inline]
83    pub fn offset(&self) -> u64 {
84        self.offset
85    }
86
87    /// Get the operation type.
88    #[inline]
89    pub fn op_type(&self) -> OperationType {
90        self.op_type
91    }
92}