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}