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}