ps_buffer/methods/
from_ffi_init.rs1use crate::{Buffer, BufferError};
2
3impl Buffer {
4 pub fn from_ffi_init<F>(bytes: usize, init_fn: F) -> Result<Self, BufferError>
24 where
25 F: FnOnce(&mut [u8]) -> usize,
26 {
27 let mut buffer = Self::alloc_uninit(bytes)?;
29
30 let initialized_bytes = init_fn(buffer.as_mut());
32
33 debug_assert!(
35 initialized_bytes <= bytes,
36 "Initialized bytes ({initialized_bytes}) cannot exceed allocated bytes ({bytes})."
37 );
38
39 buffer.truncate(initialized_bytes);
41
42 Ok(buffer)
44 }
45}
46
47#[cfg(test)]
48#[allow(clippy::unwrap_used)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn test_from_ffi_init_full_buffer() {
54 let buffer = Buffer::from_ffi_init(10, |slice| {
55 for (i, byte) in slice.iter_mut().enumerate() {
56 *byte = u8::try_from(i).unwrap();
57 }
58 slice.len()
59 })
60 .unwrap();
61
62 assert_eq!(buffer.len(), 10);
64 assert_eq!(&buffer[..], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
65 }
66
67 #[test]
68 fn test_from_ffi_init_partial_buffer() {
69 let buffer = Buffer::from_ffi_init(10, |slice| {
70 for (i, byte) in slice.iter_mut().enumerate() {
71 if i < 5 {
72 *byte = u8::try_from(i).unwrap();
73 }
74 }
75 5 })
77 .unwrap();
78
79 assert_eq!(buffer.len(), 5);
81 assert_eq!(&buffer[..], &[0, 1, 2, 3, 4]);
82 }
83
84 #[test]
85 fn test_from_ffi_init_zero_bytes() {
86 let buffer = Buffer::from_ffi_init(10, |_slice| {
87 0 })
89 .unwrap();
90
91 assert_eq!(buffer.len(), 0);
93 assert_eq!(buffer.capacity(), 10); }
95
96 #[test]
97 fn test_from_ffi_init_allocation_failure() {
98 let result = Buffer::from_ffi_init(usize::MAX, |_slice| 0);
100 assert!(result.is_err());
101 }
102
103 #[test]
104 #[should_panic(expected = "Initialized bytes (11) cannot exceed allocated bytes (10).")]
105 fn test_from_ffi_init_panic_on_over_initialization() {
106 let _ = Buffer::from_ffi_init(10, |slice| {
108 for (i, byte) in slice.iter_mut().enumerate() {
109 *byte = u8::try_from(i).unwrap();
110 }
111 11 })
113 .unwrap();
114 }
115}