1use crate::{filelike, Advice};
2#[cfg(not(any(target_os = "android", target_os = "linux")))]
3use io_lifetimes::OwnedFilelike;
4#[cfg(not(windows))]
5use io_lifetimes::{AsFd, BorrowedFd};
6use io_lifetimes::{FromFilelike, IntoFilelike};
7#[cfg(feature = "io-streams")]
8use io_streams::StreamReader;
9use std::fs;
10use std::io::{self, IoSlice, IoSliceMut, Read, Seek, Write};
11#[cfg(unix)]
12use std::os::unix::io::{AsRawFd, RawFd};
13#[cfg(target_os = "wasi")]
14use std::os::wasi::io::{AsRawFd, RawFd};
15#[cfg(windows)]
19use {
20 io_extras::os::windows::{AsRawHandleOrSocket, RawHandleOrSocket},
21 io_lifetimes::{AsHandle, BorrowedHandle},
22 std::os::windows::io::{AsRawHandle, RawHandle},
23};
24
25pub struct Metadata {
30 pub(crate) len: u64,
31 pub(crate) blksize: u64,
32}
33
34#[allow(clippy::len_without_is_empty)]
35impl Metadata {
36 #[inline]
38 #[must_use]
39 pub const fn len(&self) -> u64 {
40 self.len
41 }
42
43 #[inline]
45 #[must_use]
46 pub const fn blksize(&self) -> u64 {
47 self.blksize
48 }
49}
50
51pub trait Array {
58 fn metadata(&self) -> io::Result<Metadata>;
62
63 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()>;
67}
68
69pub trait ReadAt: Array {
77 fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
85
86 fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()>;
96
97 fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize>;
99
100 fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()>;
102
103 fn is_read_vectored_at(&self) -> bool;
106
107 #[cfg(feature = "io-streams")]
109 fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader>;
110}
111
112pub trait WriteAt: Array {
117 fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize>;
125
126 fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()>;
134
135 fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize>;
137
138 fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()>;
140
141 fn is_write_vectored_at(&self) -> bool;
144
145 fn copy_from<R: ReadAt>(
147 &mut self,
148 offset: u64,
149 input: &R,
150 input_offset: u64,
151 len: u64,
152 ) -> io::Result<u64>;
153
154 fn set_len(&mut self, size: u64) -> io::Result<()>;
157}
158
159pub trait EditAt: ReadAt + WriteAt {}
164
165impl<T: ReadAt + WriteAt> EditAt for T {}
166
167#[derive(Debug)]
169pub struct ArrayReader {
170 file: fs::File,
171}
172
173#[derive(Debug)]
175pub struct ArrayWriter {
176 file: fs::File,
177}
178
179#[derive(Debug)]
181pub struct ArrayEditor {
182 file: fs::File,
183}
184
185impl ArrayReader {
186 #[inline]
188 #[must_use]
189 pub fn file<Filelike: IntoFilelike + Read + Seek>(filelike: Filelike) -> Self {
190 Self {
191 file: fs::File::from_into_filelike(filelike),
192 }
193 }
194
195 #[inline]
198 pub fn bytes(bytes: &[u8]) -> io::Result<Self> {
199 let owned = create_anonymous()?;
200 let mut file = fs::File::from_into_filelike(owned);
201 file.write_all(bytes)?;
202 Ok(Self { file })
203 }
204}
205
206impl ArrayWriter {
207 #[inline]
213 #[must_use]
214 pub fn file<Filelike: IntoFilelike + Write + Seek>(filelike: Filelike) -> Self {
215 Self::_file(fs::File::from_into_filelike(filelike))
216 }
217
218 #[inline]
219 fn _file(file: fs::File) -> Self {
220 #[cfg(not(windows))]
223 {
224 assert!(
225 !rustix::fs::fcntl_getfl(&file)
226 .unwrap()
227 .contains(rustix::fs::OFlags::APPEND),
228 "ArrayWriter doesn't support files opened with O_APPEND"
229 );
230 }
231 #[cfg(windows)]
232 {
233 assert!(
234 (winx::file::query_access_information(file.as_handle()).unwrap()
235 & winx::file::AccessMode::FILE_APPEND_DATA)
236 == winx::file::AccessMode::FILE_APPEND_DATA,
237 "ArrayWriter doesn't support files opened with FILE_APPEND_DATA"
238 );
239 }
240
241 Self { file }
242 }
243}
244
245impl ArrayEditor {
246 #[inline]
248 #[must_use]
249 pub fn file<Filelike: IntoFilelike + Read + Write + Seek>(filelike: Filelike) -> Self {
250 Self {
251 file: fs::File::from_into_filelike(filelike),
252 }
253 }
254
255 #[inline]
258 pub fn anonymous() -> io::Result<Self> {
259 let owned = create_anonymous()?;
260 Ok(Self {
261 file: fs::File::from_into_filelike(owned),
262 })
263 }
264}
265
266impl Array for ArrayReader {
267 #[inline]
268 fn metadata(&self) -> io::Result<Metadata> {
269 filelike::metadata(self)
270 }
271
272 #[inline]
273 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
274 filelike::advise(self, offset, len, advice)
275 }
276}
277
278impl Array for &ArrayReader {
279 #[inline]
280 fn metadata(&self) -> io::Result<Metadata> {
281 filelike::metadata(self)
282 }
283
284 #[inline]
285 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
286 filelike::advise(self, offset, len, advice)
287 }
288}
289
290impl Array for ArrayWriter {
291 #[inline]
292 fn metadata(&self) -> io::Result<Metadata> {
293 filelike::metadata(self)
294 }
295
296 #[inline]
297 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
298 filelike::advise(self, offset, len, advice)
299 }
300}
301
302impl Array for &ArrayWriter {
303 #[inline]
304 fn metadata(&self) -> io::Result<Metadata> {
305 filelike::metadata(self)
306 }
307
308 #[inline]
309 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
310 filelike::advise(self, offset, len, advice)
311 }
312}
313
314impl Array for ArrayEditor {
315 #[inline]
316 fn metadata(&self) -> io::Result<Metadata> {
317 filelike::metadata(self)
318 }
319
320 #[inline]
321 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
322 filelike::advise(self, offset, len, advice)
323 }
324}
325
326impl Array for &ArrayEditor {
327 #[inline]
328 fn metadata(&self) -> io::Result<Metadata> {
329 filelike::metadata(self)
330 }
331
332 #[inline]
333 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
334 filelike::advise(self, offset, len, advice)
335 }
336}
337
338impl ReadAt for ArrayReader {
339 #[inline]
340 fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
341 filelike::read_at(self, buf, offset)
342 }
343
344 #[inline]
345 fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
346 filelike::read_exact_at(self, buf, offset)
347 }
348
349 #[inline]
350 fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize> {
351 filelike::read_vectored_at(self, bufs, offset)
352 }
353
354 #[inline]
355 fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()> {
356 filelike::read_exact_vectored_at(self, bufs, offset)
357 }
358
359 #[inline]
360 fn is_read_vectored_at(&self) -> bool {
361 filelike::is_read_vectored_at(self)
362 }
363
364 #[cfg(feature = "io-streams")]
365 #[inline]
366 fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader> {
367 filelike::read_via_stream_at(self, offset)
368 }
369}
370
371impl ReadAt for ArrayEditor {
372 #[inline]
373 fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
374 filelike::read_at(self, buf, offset)
375 }
376
377 #[inline]
378 fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
379 filelike::read_exact_at(self, buf, offset)
380 }
381
382 #[inline]
383 fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize> {
384 filelike::read_vectored_at(self, bufs, offset)
385 }
386
387 #[inline]
388 fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()> {
389 filelike::read_exact_vectored_at(self, bufs, offset)
390 }
391
392 #[inline]
393 fn is_read_vectored_at(&self) -> bool {
394 filelike::is_read_vectored_at(self)
395 }
396
397 #[cfg(feature = "io-streams")]
398 #[inline]
399 fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader> {
400 filelike::read_via_stream_at(self, offset)
401 }
402}
403
404impl WriteAt for ArrayWriter {
405 #[inline]
406 fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
407 filelike::write_at(&*self, buf, offset)
408 }
409
410 #[inline]
411 fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
412 filelike::write_all_at(&*self, buf, offset)
413 }
414
415 #[inline]
416 fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
417 filelike::write_vectored_at(&*self, bufs, offset)
418 }
419
420 #[inline]
421 fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
422 filelike::write_all_vectored_at(&*self, bufs, offset)
423 }
424
425 #[inline]
426 fn is_write_vectored_at(&self) -> bool {
427 filelike::is_write_vectored_at(self)
428 }
429
430 #[inline]
431 fn copy_from<R: ReadAt>(
432 &mut self,
433 offset: u64,
434 input: &R,
435 input_offset: u64,
436 len: u64,
437 ) -> io::Result<u64> {
438 filelike::copy_from(&*self, offset, input, input_offset, len)
439 }
440
441 #[inline]
442 fn set_len(&mut self, size: u64) -> io::Result<()> {
443 filelike::set_len(&*self, size)
444 }
445}
446
447impl WriteAt for &ArrayWriter {
448 #[inline]
449 fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
450 filelike::write_at(&*self, buf, offset)
451 }
452
453 #[inline]
454 fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
455 filelike::write_all_at(&*self, buf, offset)
456 }
457
458 #[inline]
459 fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
460 filelike::write_vectored_at(&*self, bufs, offset)
461 }
462
463 #[inline]
464 fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
465 filelike::write_all_vectored_at(&*self, bufs, offset)
466 }
467
468 #[inline]
469 fn is_write_vectored_at(&self) -> bool {
470 filelike::is_write_vectored_at(self)
471 }
472
473 #[inline]
474 fn copy_from<R: ReadAt>(
475 &mut self,
476 offset: u64,
477 input: &R,
478 input_offset: u64,
479 len: u64,
480 ) -> io::Result<u64> {
481 filelike::copy_from(&*self, offset, input, input_offset, len)
482 }
483
484 #[inline]
485 fn set_len(&mut self, size: u64) -> io::Result<()> {
486 filelike::set_len(&*self, size)
487 }
488}
489
490impl WriteAt for ArrayEditor {
491 #[inline]
492 fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
493 filelike::write_at(&*self, buf, offset)
494 }
495
496 #[inline]
497 fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
498 filelike::write_all_at(&*self, buf, offset)
499 }
500
501 #[inline]
502 fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
503 filelike::write_vectored_at(&*self, bufs, offset)
504 }
505
506 #[inline]
507 fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
508 filelike::write_all_vectored_at(&*self, bufs, offset)
509 }
510
511 #[inline]
512 fn is_write_vectored_at(&self) -> bool {
513 filelike::is_write_vectored_at(self)
514 }
515
516 #[inline]
517 fn copy_from<R: ReadAt>(
518 &mut self,
519 offset: u64,
520 input: &R,
521 input_offset: u64,
522 len: u64,
523 ) -> io::Result<u64> {
524 filelike::copy_from(&*self, offset, input, input_offset, len)
525 }
526
527 #[inline]
528 fn set_len(&mut self, size: u64) -> io::Result<()> {
529 filelike::set_len(&*self, size)
530 }
531}
532
533impl WriteAt for &ArrayEditor {
534 #[inline]
535 fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
536 filelike::write_at(&*self, buf, offset)
537 }
538
539 #[inline]
540 fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
541 filelike::write_all_at(&*self, buf, offset)
542 }
543
544 #[inline]
545 fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
546 filelike::write_vectored_at(&*self, bufs, offset)
547 }
548
549 #[inline]
550 fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
551 filelike::write_all_vectored_at(&*self, bufs, offset)
552 }
553
554 #[inline]
555 fn is_write_vectored_at(&self) -> bool {
556 filelike::is_write_vectored_at(self)
557 }
558
559 #[inline]
560 fn copy_from<R: ReadAt>(
561 &mut self,
562 offset: u64,
563 input: &R,
564 input_offset: u64,
565 len: u64,
566 ) -> io::Result<u64> {
567 filelike::copy_from(&*self, offset, input, input_offset, len)
568 }
569
570 #[inline]
571 fn set_len(&mut self, size: u64) -> io::Result<()> {
572 filelike::set_len(&*self, size)
573 }
574}
575
576impl Array for fs::File {
577 #[inline]
578 fn metadata(&self) -> io::Result<Metadata> {
579 filelike::metadata(self)
580 }
581
582 #[inline]
583 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
584 filelike::advise(self, offset, len, advice)
585 }
586}
587
588impl Array for &fs::File {
589 #[inline]
590 fn metadata(&self) -> io::Result<Metadata> {
591 filelike::metadata(self)
592 }
593
594 #[inline]
595 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
596 filelike::advise(self, offset, len, advice)
597 }
598}
599
600impl ReadAt for fs::File {
601 #[inline]
602 fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
603 filelike::read_at(self, buf, offset)
604 }
605
606 #[inline]
607 fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
608 filelike::read_exact_at(self, buf, offset)
609 }
610
611 #[inline]
612 fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize> {
613 filelike::read_vectored_at(self, bufs, offset)
614 }
615
616 #[inline]
617 fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()> {
618 filelike::read_exact_vectored_at(self, bufs, offset)
619 }
620
621 #[inline]
622 fn is_read_vectored_at(&self) -> bool {
623 filelike::is_read_vectored_at(self)
624 }
625
626 #[cfg(feature = "io-streams")]
627 #[inline]
628 fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader> {
629 filelike::read_via_stream_at(self, offset)
630 }
631}
632
633impl WriteAt for fs::File {
634 #[inline]
635 fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
636 filelike::write_at(&*self, buf, offset)
637 }
638
639 #[inline]
640 fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
641 filelike::write_all_at(&*self, buf, offset)
642 }
643
644 #[inline]
645 fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
646 filelike::write_vectored_at(&*self, bufs, offset)
647 }
648
649 #[inline]
650 fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
651 filelike::write_all_vectored_at(&*self, bufs, offset)
652 }
653
654 #[inline]
655 fn is_write_vectored_at(&self) -> bool {
656 filelike::is_write_vectored_at(self)
657 }
658
659 #[inline]
660 fn copy_from<R: ReadAt>(
661 &mut self,
662 offset: u64,
663 input: &R,
664 input_offset: u64,
665 len: u64,
666 ) -> io::Result<u64> {
667 filelike::copy_from(&*self, offset, input, input_offset, len)
668 }
669
670 #[inline]
671 fn set_len(&mut self, size: u64) -> io::Result<()> {
672 filelike::set_len(&*self, size)
673 }
674}
675
676impl WriteAt for &fs::File {
677 #[inline]
678 fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
679 filelike::write_at(&*self, buf, offset)
680 }
681
682 #[inline]
683 fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
684 filelike::write_all_at(&*self, buf, offset)
685 }
686
687 #[inline]
688 fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
689 filelike::write_vectored_at(&*self, bufs, offset)
690 }
691
692 #[inline]
693 fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
694 filelike::write_all_vectored_at(&*self, bufs, offset)
695 }
696
697 #[inline]
698 fn is_write_vectored_at(&self) -> bool {
699 filelike::is_write_vectored_at(self)
700 }
701
702 #[inline]
703 fn copy_from<R: ReadAt>(
704 &mut self,
705 offset: u64,
706 input: &R,
707 input_offset: u64,
708 len: u64,
709 ) -> io::Result<u64> {
710 filelike::copy_from(&*self, offset, input, input_offset, len)
711 }
712
713 #[inline]
714 fn set_len(&mut self, size: u64) -> io::Result<()> {
715 filelike::set_len(&*self, size)
716 }
717}
718
719#[cfg(feature = "cap-std")]
720impl Array for cap_std::fs::File {
721 #[inline]
722 fn metadata(&self) -> io::Result<Metadata> {
723 filelike::metadata(self)
724 }
725
726 #[inline]
727 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
728 filelike::advise(self, offset, len, advice)
729 }
730}
731
732#[cfg(feature = "cap-std")]
733impl Array for &cap_std::fs::File {
734 #[inline]
735 fn metadata(&self) -> io::Result<Metadata> {
736 filelike::metadata(self)
737 }
738
739 #[inline]
740 fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
741 filelike::advise(self, offset, len, advice)
742 }
743}
744
745#[cfg(feature = "cap-std")]
746impl ReadAt for cap_std::fs::File {
747 #[inline]
748 fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
749 filelike::read_at(self, buf, offset)
750 }
751
752 #[inline]
753 fn read_exact_at(&self, buf: &mut [u8], offset: u64) -> io::Result<()> {
754 filelike::read_exact_at(self, buf, offset)
755 }
756
757 #[inline]
758 fn read_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<usize> {
759 filelike::read_vectored_at(self, bufs, offset)
760 }
761
762 #[inline]
763 fn read_exact_vectored_at(&self, bufs: &mut [IoSliceMut], offset: u64) -> io::Result<()> {
764 filelike::read_exact_vectored_at(self, bufs, offset)
765 }
766
767 #[inline]
768 fn is_read_vectored_at(&self) -> bool {
769 filelike::is_read_vectored_at(self)
770 }
771
772 #[cfg(feature = "io-streams")]
773 #[inline]
774 fn read_via_stream_at(&self, offset: u64) -> io::Result<StreamReader> {
775 filelike::read_via_stream_at(self, offset)
776 }
777}
778
779#[cfg(feature = "cap-std")]
780impl WriteAt for cap_std::fs::File {
781 #[inline]
782 fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
783 filelike::write_at(self, buf, offset)
784 }
785
786 #[inline]
787 fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
788 filelike::write_all_at(self, buf, offset)
789 }
790
791 #[inline]
792 fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
793 filelike::write_vectored_at(self, bufs, offset)
794 }
795
796 #[inline]
797 fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
798 filelike::write_all_vectored_at(self, bufs, offset)
799 }
800
801 #[inline]
802 fn is_write_vectored_at(&self) -> bool {
803 filelike::is_write_vectored_at(self)
804 }
805
806 #[inline]
807 fn copy_from<R: ReadAt>(
808 &mut self,
809 offset: u64,
810 input: &R,
811 input_offset: u64,
812 len: u64,
813 ) -> io::Result<u64> {
814 filelike::copy_from(self, offset, input, input_offset, len)
815 }
816
817 #[inline]
818 fn set_len(&mut self, size: u64) -> io::Result<()> {
819 filelike::set_len(self, size)
820 }
821}
822
823#[cfg(feature = "cap-std")]
824impl WriteAt for &cap_std::fs::File {
825 #[inline]
826 fn write_at(&mut self, buf: &[u8], offset: u64) -> io::Result<usize> {
827 filelike::write_at(self, buf, offset)
828 }
829
830 #[inline]
831 fn write_all_at(&mut self, buf: &[u8], offset: u64) -> io::Result<()> {
832 filelike::write_all_at(self, buf, offset)
833 }
834
835 #[inline]
836 fn write_vectored_at(&mut self, bufs: &[IoSlice], offset: u64) -> io::Result<usize> {
837 filelike::write_vectored_at(self, bufs, offset)
838 }
839
840 #[inline]
841 fn write_all_vectored_at(&mut self, bufs: &mut [IoSlice], offset: u64) -> io::Result<()> {
842 filelike::write_all_vectored_at(self, bufs, offset)
843 }
844
845 #[inline]
846 fn is_write_vectored_at(&self) -> bool {
847 filelike::is_write_vectored_at(self)
848 }
849
850 #[inline]
851 fn copy_from<R: ReadAt>(
852 &mut self,
853 offset: u64,
854 input: &R,
855 input_offset: u64,
856 len: u64,
857 ) -> io::Result<u64> {
858 filelike::copy_from(self, offset, input, input_offset, len)
859 }
860
861 #[inline]
862 fn set_len(&mut self, size: u64) -> io::Result<()> {
863 filelike::set_len(self, size)
864 }
865}
866
867#[cfg(not(windows))]
1166impl AsRawFd for ArrayReader {
1167 #[inline]
1168 fn as_raw_fd(&self) -> RawFd {
1169 self.file.as_raw_fd()
1170 }
1171}
1172
1173#[cfg(not(windows))]
1174impl AsFd for ArrayReader {
1175 #[inline]
1176 fn as_fd(&self) -> BorrowedFd<'_> {
1177 self.file.as_fd()
1178 }
1179}
1180
1181#[cfg(windows)]
1182impl AsRawHandle for ArrayReader {
1183 #[inline]
1184 fn as_raw_handle(&self) -> RawHandle {
1185 self.file.as_raw_handle()
1186 }
1187}
1188
1189#[cfg(windows)]
1190impl AsHandle for ArrayReader {
1191 #[inline]
1192 fn as_handle(&self) -> BorrowedHandle<'_> {
1193 self.file.as_handle()
1194 }
1195}
1196
1197#[cfg(windows)]
1198impl AsRawHandleOrSocket for ArrayReader {
1199 #[inline]
1200 fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
1201 self.file.as_raw_handle_or_socket()
1202 }
1203}
1204
1205#[cfg(not(windows))]
1206impl AsRawFd for ArrayWriter {
1207 #[inline]
1208 fn as_raw_fd(&self) -> RawFd {
1209 self.file.as_raw_fd()
1210 }
1211}
1212
1213#[cfg(not(windows))]
1214impl AsFd for ArrayWriter {
1215 #[inline]
1216 fn as_fd(&self) -> BorrowedFd<'_> {
1217 self.file.as_fd()
1218 }
1219}
1220
1221#[cfg(windows)]
1222impl AsRawHandle for ArrayWriter {
1223 #[inline]
1224 fn as_raw_handle(&self) -> RawHandle {
1225 self.file.as_raw_handle()
1226 }
1227}
1228
1229#[cfg(windows)]
1230impl AsHandle for ArrayWriter {
1231 #[inline]
1232 fn as_handle(&self) -> BorrowedHandle<'_> {
1233 self.file.as_handle()
1234 }
1235}
1236
1237#[cfg(windows)]
1238impl AsRawHandleOrSocket for ArrayWriter {
1239 #[inline]
1240 fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
1241 self.file.as_raw_handle_or_socket()
1242 }
1243}
1244
1245#[cfg(not(windows))]
1246impl AsRawFd for ArrayEditor {
1247 #[inline]
1248 fn as_raw_fd(&self) -> RawFd {
1249 self.file.as_raw_fd()
1250 }
1251}
1252
1253#[cfg(not(windows))]
1254impl AsFd for ArrayEditor {
1255 #[inline]
1256 fn as_fd(&self) -> BorrowedFd<'_> {
1257 self.file.as_fd()
1258 }
1259}
1260
1261#[cfg(windows)]
1262impl AsRawHandle for ArrayEditor {
1263 #[inline]
1264 fn as_raw_handle(&self) -> RawHandle {
1265 self.file.as_raw_handle()
1266 }
1267}
1268
1269#[cfg(windows)]
1270impl AsHandle for ArrayEditor {
1271 #[inline]
1272 fn as_handle(&self) -> BorrowedHandle<'_> {
1273 self.file.as_handle()
1274 }
1275}
1276
1277#[cfg(windows)]
1278impl AsRawHandleOrSocket for ArrayEditor {
1279 #[inline]
1280 fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
1281 self.file.as_raw_handle_or_socket()
1282 }
1283}
1284
1285#[cfg(any(target_os = "android", target_os = "linux"))]
1287fn create_anonymous() -> io::Result<rustix::fd::OwnedFd> {
1288 let flags = rustix::fs::MemfdFlags::CLOEXEC | rustix::fs::MemfdFlags::ALLOW_SEALING;
1289 let name = rustix::cstr!("io_arrays anonymous file");
1290 Ok(rustix::fs::memfd_create(name, flags)?)
1291}
1292
1293#[cfg(not(any(target_os = "android", target_os = "linux")))]
1295fn create_anonymous() -> io::Result<OwnedFilelike> {
1296 let file = tempfile::tempfile()?;
1297 Ok(file.into_filelike())
1298}