fmmap/
mmap_file.rs

1macro_rules! read_impl {
2    ($this:ident, $offset: tt, $typ:tt::$conv:tt) => {{
3        const SIZE: usize = mem::size_of::<$typ>();
4        // try to convert directly from the bytes
5        // this Option<ret> trick is to avoid keeping a borrow on self
6        // when advance() is called (mut borrow) and to call bytes() only once
7        let mut buf = [0; SIZE];
8        $this
9            .read_exact(&mut buf, $offset)
10            .map(|_| unsafe { $typ::$conv(*(&buf as *const _ as *const [_; SIZE])) })
11    }};
12}
13
14macro_rules! impl_from {
15    ($outer: ident, $enum_inner: ident, [$($inner: ident), +$(,)?]) => {
16        $(
17        impl From<$inner> for $outer {
18            fn from(file: $inner) -> Self {
19                $outer{ inner: <$enum_inner>::from(file) }
20            }
21        }
22        )*
23    };
24}
25
26macro_rules! impl_from_mut {
27    ($outer: ident, $enum_inner: ident, [$($inner: ident), +$(,)?]) => {
28        $(
29        impl From<$inner> for $outer {
30            fn from(file: $inner) -> Self {
31                $outer{
32                    inner: <$enum_inner>::from(file),
33                    remove_on_drop: false,
34                    deleted: false,
35                }
36            }
37        }
38        )*
39    };
40}
41
42macro_rules! impl_drop {
43    ($name: ident, $inner: ident, $empty: ident) => {
44        impl Drop for $name {
45            fn drop(&mut self) {
46                if self.remove_on_drop && !self.deleted {
47                    let empty = <$inner>::Empty(<$empty>::default());
48                    // swap the inner to empty
49                    let inner = mem::replace(&mut self.inner, empty);
50                    // do remove and ignore the result
51                    let path = inner.path_buf();
52                    drop(inner);
53                    let _ = std::fs::remove_file(path);
54                }
55            }
56        }
57    };
58}
59
60macro_rules! impl_flush {
61    () => {
62        fn flush(&self) -> Result<()> {
63            self.inner.flush()
64        }
65
66        fn flush_async(&self) -> Result<()> {
67            self.inner.flush_async()
68        }
69
70        fn flush_range(&self, offset: usize, len: usize) -> Result<()> {
71            self.inner.flush_range(offset, len)
72        }
73
74        fn flush_async_range(&self, offset: usize, len: usize) -> Result<()> {
75            self.inner.flush_async_range(offset, len)
76        }
77    };
78}
79
80macro_rules! impl_file_lock {
81    () => {
82        #[inline]
83        fn lock_exclusive(&self) -> crate::error::Result<()> {
84            self.inner.lock_exclusive()
85        }
86
87        #[inline]
88        fn lock_shared(&self) -> crate::error::Result<()> {
89            self.inner.lock_shared()
90        }
91
92        #[inline]
93        fn try_lock_exclusive(&self) -> crate::error::Result<()> {
94            self.inner.try_lock_exclusive()
95        }
96
97        #[inline]
98        fn try_lock_shared(&self) -> crate::error::Result<()> {
99            self.inner.try_lock_shared()
100        }
101
102        #[inline]
103        fn unlock(&self) -> crate::error::Result<()> {
104            self.inner.unlock()
105        }
106    };
107}
108
109macro_rules! impl_constructor_for_memory_mmap_file {
110    ($memory_base: ident, $name: ident, $name_str: literal, $path_str: literal) => {
111        use bytes::Bytes;
112
113        impl $name {
114            #[doc = concat!("Create a in-memory ", $name_str)]
115            #[doc = "# Examples"]
116            #[doc = "```ignore"]
117            #[doc = "use bytes::{BufMut, BytesMut};"]
118            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
119            #[doc = ""]
120            #[doc = "let mut data = BytesMut::with_capacity(100);"]
121            #[doc = "data.put_slice(\"some data...\".as_bytes());"]
122            #[doc = concat!($name_str, "::memory(\"foo.mem\", data.freeze());")]
123            #[doc = "```"]
124            pub fn memory<P: AsRef<Path>>(path: P, data: Bytes) -> Self {
125                Self::from(<$memory_base>::new(path, data))
126            }
127
128            #[doc = concat!("Create a in-memory ", $name_str, " from Vec")]
129            #[doc = "# Examples"]
130            #[doc = "```ignore"]
131            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
132            #[doc = ""]
133            #[doc = "let data = (0..=255u8).collect::<Vec<_>>();"]
134            #[doc = concat!($name_str, "::memory_from_vec(\"foo.mem\", data);")]
135            #[doc = "```"]
136            pub fn memory_from_vec<P: AsRef<Path>>(path: P, src: Vec<u8>) -> Self {
137                Self::from(<$memory_base>::from_vec(path, src))
138            }
139
140            #[doc = concat!("Create a in-memory ", $name_str, " from String")]
141            #[doc = "# Examples"]
142            #[doc = "```ignore"]
143            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
144            #[doc = ""]
145            #[doc = "let data: &'static str = \"some data...\";"]
146            #[doc = concat!($name_str, "::memory_from_string(\"foo.mem\", data.to_string());")]
147            #[doc = "```"]
148            pub fn memory_from_string<P: AsRef<Path>>(path: P, src: String) -> Self {
149                Self::from(<$memory_base>::from_string(path, src))
150            }
151
152            #[doc = concat!("Create a in-memory ", $name_str, " from static slice")]
153            #[doc = "# Examples"]
154            #[doc = "```ignore"]
155            #[doc = "use bytes::Bytes;"]
156            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
157            #[doc = ""]
158            #[doc = "let data: &'static [u8] = \"some data...\".as_bytes();"]
159            #[doc = concat!($name_str, "::memory_from_slice(\"foo.mem\", data);")]
160            #[doc = "```"]
161            pub fn memory_from_slice<P: AsRef<Path>>(path: P, src: &'static [u8]) -> Self {
162                 Self::from(<$memory_base>::from_slice(path, src))
163            }
164
165            #[doc = concat!("Create a in-memory ", $name_str, " from static str")]
166            #[doc = "# Examples"]
167            #[doc = "```ignore"]
168            #[doc = "use bytes::Bytes;"]
169            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
170            #[doc = ""]
171            #[doc = "let data: &'static str = \"some data...\";"]
172            #[doc = concat!($name_str, "::memory_from_str(\"foo.mem\", data);")]
173            #[doc = "```"]
174            pub fn memory_from_str<P: AsRef<Path>>(path: P, src: &'static str) -> Self {
175                Self::from(<$memory_base>::from_str(path, src))
176            }
177
178            #[doc = concat!("Create a in-memory ", $name_str, " by copy from slice")]
179            #[doc = "# Examples"]
180            #[doc = "```ignore"]
181            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
182            #[doc = ""]
183            #[doc = concat!($name_str, "::memory_copy_from_slice(\"foo.mem\", \"some data...\".as_bytes());")]
184            #[doc = "```"]
185            pub fn memory_copy_from_slice<P: AsRef<Path>>(path: P, src: &[u8]) -> Self {
186                Self::from(<$memory_base>::copy_from_slice(path, src))
187            }
188        }
189    };
190}
191
192macro_rules! impl_constructor_for_memory_mmap_file_mut {
193    ($memory_base: ident, $name: ident, $name_str: literal, $path_str: literal) => {
194        impl $name {
195            #[doc = concat!("Create a in-memory ", $name_str)]
196            #[doc = "# Examples"]
197            #[doc = "```ignore"]
198            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
199            #[doc = ""]
200            #[doc = concat!($name_str, "::memory(\"foo.mem\");")]
201            #[doc = "```"]
202            pub fn memory<P: AsRef<Path>>(path: P) -> Self {
203                Self::from(<$memory_base>::new(path))
204            }
205
206            #[doc = concat!("Create a in-memory ", $name_str, "with capacity")]
207            #[doc = "# Examples"]
208            #[doc = "```ignore"]
209            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
210            #[doc = ""]
211            #[doc = concat!($name_str, "::memory_with_capacity(\"foo.mem\", 1000);")]
212            #[doc = "```"]
213            pub fn memory_with_capacity<P: AsRef<Path>>(path: P, cap: usize) -> Self {
214                Self::from(<$memory_base>::with_capacity(path, cap))
215            }
216
217            #[doc = concat!("Create a in-memory ", $name_str, " from Vec")]
218            #[doc = "# Examples"]
219            #[doc = "```ignore"]
220            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
221            #[doc = ""]
222            #[doc = "let data = (0..=255u8).collect::<Vec<_>>();"]
223            #[doc = concat!($name_str, "::memory_from_vec(\"foo.mem\", data);")]
224            #[doc = "```"]
225            pub fn memory_from_vec<P: AsRef<Path>>(path: P, src: Vec<u8>) -> Self {
226                Self::from(<$memory_base>::from_vec(path, src))
227            }
228
229            #[doc = concat!("Create a in-memory ", $name_str, " from String")]
230            #[doc = "# Examples"]
231            #[doc = "```ignore"]
232            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
233            #[doc = ""]
234            #[doc = "let data: &'static str = \"some data...\";"]
235            #[doc = concat!($name_str, "::memory_from_string(\"foo.mem\", data.to_string());")]
236            #[doc = "```"]
237            pub fn memory_from_string<P: AsRef<Path>>(path: P, src: String) -> Self {
238                Self::from(<$memory_base>::from_string(path, src))
239            }
240
241            #[doc = concat!("Create a in-memory ", $name_str, " from static str")]
242            #[doc = "# Examples"]
243            #[doc = "```ignore"]
244            #[doc = "use bytes::Bytes;"]
245            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
246            #[doc = ""]
247            #[doc = "let data: &'static str = \"some data...\";"]
248            #[doc = concat!($name_str, "::memory_from_str(\"foo.mem\", data);")]
249            #[doc = "```"]
250            pub fn memory_from_str<P: AsRef<Path>>(path: P, src: &'static str) -> Self {
251                Self::from(<$memory_base>::from_str(path, src))
252            }
253
254            #[doc = concat!("Create a in-memory ", $name_str, " by from slice")]
255            #[doc = "# Examples"]
256            #[doc = "```ignore"]
257            #[doc = concat!("use fmmap::", $path_str, "::", $name_str, ";")]
258            #[doc = ""]
259            #[doc = concat!($name_str, "::memory_from_slice(\"foo.mem\", \"some data...\".as_bytes());")]
260            #[doc = "```"]
261            pub fn memory_from_slice<P: AsRef<Path>>(path: P, src: &[u8]) -> Self {
262                Self::from(<$memory_base>::from_slice(path, src))
263            }
264        }
265    };
266}
267
268cfg_sync! {
269    macro_rules! impl_mmap_file_ext {
270        ($name: ident) => {
271            impl MmapFileExt for $name {
272                #[inline]
273                fn len(&self) -> usize {
274                    self.inner.len()
275                }
276
277                #[inline]
278                fn as_slice(&self) -> &[u8] {
279                    self.inner.as_slice()
280                }
281
282                #[inline]
283                fn path(&self) -> &Path {
284                    self.inner.path()
285                }
286
287                #[inline]
288                fn is_exec(&self) -> bool {
289                    self.inner.is_exec()
290                }
291
292                #[inline]
293                fn metadata(&self) -> Result<MetaData> {
294                    self.inner.metadata()
295                }
296
297                impl_file_lock!();
298            }
299        };
300    }
301
302    mod sync_impl;
303    pub use sync_impl::{MmapFileExt, MmapFileMutExt, MmapFile, MmapFileMut};
304}
305
306cfg_async! {
307    macro_rules! impl_async_mmap_file_ext {
308        ($name: ident) => {
309
310            impl AsyncMmapFileExt for $name {
311                #[inline]
312                fn len(&self) -> usize {
313                    self.inner.len()
314                }
315
316                #[inline]
317                fn as_slice(&self) -> &[u8] {
318                    self.inner.as_slice()
319                }
320
321                #[inline]
322                fn path(&self) -> &Path {
323                    self.inner.path()
324                }
325
326                #[inline]
327                fn is_exec(&self) -> bool {
328                    self.inner.is_exec()
329                }
330
331                #[inline]
332                async fn metadata(&self) -> Result<MetaData> {
333                    self.inner.metadata().await
334                }
335
336                impl_file_lock!();
337            }
338        };
339    }
340
341    macro_rules! impl_async_mmap_file_mut_ext {
342        ($filename_prefix: literal, $doc_test_runtime: literal, $path_str: literal) => {
343
344            impl AsyncMmapFileMutExt for AsyncMmapFileMut {
345                #[inline]
346                fn as_mut_slice(&mut self) -> &mut [u8] {
347                    self.inner.as_mut_slice()
348                }
349
350                #[inline]
351                fn is_cow(&self) -> bool {
352                    self.inner.is_cow()
353                }
354
355                impl_flush!();
356
357                #[inline]
358                async fn truncate(&mut self, max_sz: u64) -> Result<()> {
359                    self.inner.truncate(max_sz).await
360                }
361
362                /// Remove the underlying file
363                ///
364                /// # Example
365                ///
366                /// ```ignore
367                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileMutExt};")]
368                #[doc = concat!("use ", $path_str, "::fs::File;")]
369                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
370                #[doc = concat!("let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_remove_test.txt\").await.unwrap();")]
371                ///
372                /// file.truncate(12).await;
373                /// file.write_all("some data...".as_bytes(), 0).unwrap();
374                /// file.flush().unwrap();
375                ///
376                /// file.drop_remove().await.unwrap();
377                ///
378                #[doc = concat!("let err = File::open(\"", $filename_prefix, "_remove_test.txt\").await;")]
379                /// assert_eq!(err.unwrap_err().kind(), std::io::ErrorKind::NotFound);
380                /// # })
381                /// ```
382                async fn drop_remove(mut self) -> Result<()> {
383                    let empty = AsyncMmapFileMutInner::Empty(AsyncEmptyMmapFile::default());
384                    // swap the inner to empty
385                    let inner = mem::replace(&mut self.inner, empty);
386                    if !self.remove_on_drop {
387                        // do remove
388                        inner.drop_remove().await?;
389                        self.deleted = true;
390                    }
391                    Ok(())
392                }
393
394                /// Close and truncate the underlying file
395                ///
396                /// # Examples
397                ///
398                /// ```ignore
399                #[doc = concat!("use fmmap::{MetaDataExt,", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileExt, AsyncMmapFileMutExt}};")]
400                /// # use scopeguard::defer;
401                ///
402                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
403                #[doc = concat!("let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_close_with_truncate_test.txt\").await.unwrap();")]
404                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_close_with_truncate_test.txt\").unwrap());")]
405                /// file.truncate(100).await;
406                /// file.write_all("some data...".as_bytes(), 0).unwrap();
407                /// file.flush().unwrap();
408                ///
409                /// file.close_with_truncate(50).await.unwrap();
410                ///
411                #[doc = concat!("let file = AsyncMmapFileMut::open(\"", $filename_prefix, "_close_with_truncate_test.txt\").await.unwrap();")]
412                /// let meta = file.metadata().await.unwrap();
413                /// assert_eq!(meta.len(), 50);
414                /// # })
415                /// ```
416                async fn close_with_truncate(mut self, max_sz: i64) -> Result<()> {
417                    let empty = AsyncMmapFileMutInner::Empty(AsyncEmptyMmapFile::default());
418                    // swap the inner to empty
419                    let inner = mem::replace(&mut self.inner, empty);
420                    inner.close_with_truncate(max_sz).await
421                }
422            }
423        };
424    }
425
426    macro_rules! declare_async_mmap_file_ext {
427        ($disk_file_mut: ty, $opts: ty, $reader: ty) => {
428            /// Utility methods to [`AsyncMmapFile`]
429            ///
430            /// [`AsyncMmapFile`]: structs.AsyncMmapFile.html
431
432            #[enum_dispatch]
433            pub trait AsyncMmapFileExt: Sync {
434                /// Returns the current mmap length
435                fn len(&self) -> usize;
436
437                /// Returns the mmap is empty of not.
438                fn is_empty(&self) -> bool {
439                    self.len() == 0
440                }
441
442                /// Returns the underlying slice of the mmap
443                fn as_slice(&self) -> &[u8];
444
445                /// slice returns data starting from offset off of size sz.
446                ///
447                /// # Panics
448                /// If there's not enough data, it would
449                /// panic.
450                fn slice(&self, offset: usize, sz: usize) -> &[u8] {
451                    &self.as_slice()[offset..offset+sz]
452                }
453
454                /// bytes returns data starting from offset off of size sz.
455                ///
456                /// # Errors
457                /// If there's not enough data, it would return
458                /// `Err(Error::from(ErrorKind::EOF))`.
459                fn bytes(&self, offset: usize, sz: usize) -> Result<&[u8]> {
460                    let buf = self.as_slice();
461                    if buf.len() < offset + sz {
462                        Err(Error::from(ErrorKind::EOF))
463                    } else {
464                        Ok(&buf[offset..offset+sz])
465                    }
466                }
467
468                /// Returns the path of the inner file.
469                fn path(&self) -> &Path;
470
471                /// Returns the path buf of the inner file.
472                fn path_buf(&self) -> PathBuf {
473                    self.path().to_path_buf()
474                }
475
476                /// Returns the path lossy string of the inner file.
477                fn path_lossy(&self) -> Cow<'_, str> {
478                    self.path().to_string_lossy()
479                }
480
481                /// Returns the path string of the inner file.
482                fn path_string(&self) -> String {
483                    self.path_lossy().to_string()
484                }
485
486                /// Whether the mmap is executable
487                fn is_exec(&self) -> bool;
488
489                /// Returns the metadata of file metadata
490                ///
491                /// Metadata information about a file.
492                /// This structure is returned from the metadata or
493                /// symlink_metadata function or method and represents
494                /// known metadata about a file such as its permissions, size, modification times, etc
495                fn metadata(&self) -> impl core::future::Future<Output = Result<MetaData>> + Send;
496
497                /// Copy the content of the mmap file to Vec
498                #[inline]
499                fn copy_all_to_vec(&self) -> Vec<u8> {
500                    self.as_slice().to_vec()
501                }
502
503                /// Copy a range of content of the mmap file to Vec
504                #[inline]
505                fn copy_range_to_vec(&self, offset: usize, len: usize) -> Vec<u8> {
506                    self.slice(offset, len).to_vec()
507                }
508
509                /// Write the content of the mmap file to a new file.
510                #[inline]
511                fn write_all_to_new_file<P: AsRef<Path> + Send + Sync>(&self, new_file_path: P) -> impl core::future::Future<Output = Result<()>> + Send {
512                    async move {
513                        let buf = self.as_slice();
514                        let opts = <$opts>::new().max_size(buf.len() as u64);
515
516                        let mut mmap = <$disk_file_mut>::create_with_options(new_file_path, opts).await?;
517                        mmap.writer(0)?.write_all(buf).await?;
518                        mmap.flush()
519                    }
520                }
521
522                /// Write a range of content of the mmap file to new file.
523                #[inline]
524                fn write_range_to_new_file<P: AsRef<Path> + Send + Sync>(&self, new_file_path: P, offset: usize, len: usize) -> impl core::future::Future<Output = Result<()>> + Send {
525                    async move {
526                        let buf = self.as_slice();
527                    if buf.len() < offset + len {
528                        return Err(Error::from(ErrorKind::EOF));
529                    }
530                    let opts = <$opts>::new().max_size(len as u64);
531
532                    let mut mmap = <$disk_file_mut>::create_with_options(new_file_path, opts).await?;
533                    mmap.writer(0)?.write_all(&buf[offset..offset + len]).await?;
534                    mmap.flush()
535                    }
536                }
537
538                /// Returns a [`AsyncMmapFileReader`] which helps read data from mmap like a normal File.
539                ///
540                /// # Errors
541                /// If there's not enough data, it would return
542                ///  `Err(Error::from(ErrorKind::EOF))`.
543                ///
544                /// [`AsyncMmapFileReader`]: structs.AsyncMmapFileReader.html
545                fn reader(&self, offset: usize) -> Result<$reader> {
546                    let buf = self.as_slice();
547                    if buf.len() < offset {
548                        Err(Error::from(ErrorKind::EOF))
549                    } else {
550                        Ok(<$reader>::new(Cursor::new(&buf[offset..]), offset, buf.len() - offset))
551                    }
552                }
553
554                /// Returns a [`AsyncMmapFileReader`] base on the given `offset` and `len`, which helps read data from mmap like a normal File.
555                ///
556                /// # Errors
557                /// If there's not enough data, it would return
558                ///  `Err(Error::from(ErrorKind::EOF))`.
559                ///
560                /// [`AsyncMmapFileReader`]: structs.AsyncMmapFileReader.html
561                fn range_reader(&self, offset: usize, len: usize) -> Result<$reader> {
562                    let buf = self.as_slice();
563                    if buf.len() < offset + len {
564                        Err(Error::from(ErrorKind::EOF))
565                    } else {
566                        Ok(<$reader>::new(Cursor::new(&buf[offset.. offset + len]), offset, len))
567                    }
568                }
569
570                /// Locks the file for exclusive usage, blocking if the file is currently locked.
571                ///
572                /// # Notes
573                /// This function will do nothing if the underlying is not a real file, e.g. in-memory.
574                fn lock_exclusive(&self) -> Result<()>;
575
576                /// Locks the file for shared usage, blocking if the file is currently locked exclusively.
577                ///
578                /// # Notes
579                /// This function will do nothing if the underlying is not a real file, e.g. in-memory.
580                fn lock_shared(&self) -> Result<()>;
581
582                /// Locks the file for exclusive usage, or returns a an error if the file is currently locked (see lock_contended_error).
583                ///
584                /// # Notes
585                /// This function will do nothing if the underlying is not a real file, e.g. in-memory.
586                fn try_lock_exclusive(&self) -> Result<()>;
587
588                /// Locks the file for shared usage, or returns a an error if the file is currently locked exclusively (see lock_contended_error).
589                ///
590                /// # Notes
591                /// This function will do nothing if the underlying is not a real file, e.g. in-memory.
592                fn try_lock_shared(&self) -> Result<()>;
593
594                /// Unlocks the file.
595                ///
596                /// # Notes
597                /// This function will do nothing if the underlying is not a real file, e.g. in-memory.
598                fn unlock(&self) -> Result<()>;
599
600                /// Read bytes to the dst buf from the offset, returns how many bytes read.
601                fn read(&self, dst: &mut [u8], offset: usize) -> usize {
602                    let buf = self.as_slice();
603
604                    if buf.len() < offset {
605                        0
606                    } else {
607                        let remaining = buf.len() - offset;
608                        let dst_len = dst.len();
609                        if remaining > dst_len {
610                            dst.copy_from_slice(&buf[offset..offset + dst_len]);
611                            dst_len
612                        } else {
613                            dst.copy_from_slice(&buf[offset..offset + remaining]);
614                            remaining
615                        }
616                    }
617                }
618
619                /// Read the exact number of bytes required to fill buf.
620                fn read_exact(&self, dst: &mut [u8], offset: usize) -> Result<()> {
621                    let buf = self.as_slice();
622                    let remaining = buf.len().checked_sub(offset);
623                    match remaining {
624                        None => Err(Error::from(ErrorKind::EOF)),
625                        Some(remaining) => {
626                            let dst_len = dst.len();
627                            if remaining < dst_len {
628                                Err(Error::from(ErrorKind::EOF))
629                            } else {
630                                dst.copy_from_slice(&buf[offset..offset + dst_len]);
631                                Ok(())
632                            }
633                        }
634                    }
635                }
636
637                /// Read a signed 8 bit integer from offset.
638                fn read_i8(&self, offset: usize) -> Result<i8> {
639                    let buf = self.as_slice();
640
641                    let remaining = buf.len().checked_sub(offset);
642                    match remaining {
643                        None => Err(Error::from(ErrorKind::EOF)),
644                        Some(remaining) => {
645                            if remaining < 1 {
646                                Err(Error::from(ErrorKind::EOF))
647                            } else {
648                                Ok(buf[offset] as i8)
649                            }
650                        }
651                    }
652                }
653
654                /// Read a signed 16 bit integer from offset in big-endian byte order.
655                fn read_i16(&self, offset: usize) -> Result<i16> {
656                    read_impl!(self, offset, i16::from_be_bytes)
657                }
658
659                /// Read a signed 16 bit integer from offset in little-endian byte order.
660                fn read_i16_le(&self, offset: usize) -> Result<i16> {
661                    read_impl!(self, offset, i16::from_le_bytes)
662                }
663
664                /// Read a signed integer from offset in big-endian byte order.
665                fn read_isize(&self, offset: usize) -> Result<isize> {
666                    read_impl!(self, offset, isize::from_be_bytes)
667                }
668
669                /// Read a signed integer from offset in little-endian byte order.
670                fn read_isize_le(&self, offset: usize) -> Result<isize> {
671                    read_impl!(self, offset, isize::from_le_bytes)
672                }
673
674                /// Read a signed 32 bit integer from offset in big-endian byte order.
675                fn read_i32(&self, offset: usize) -> Result<i32> {
676                    read_impl!(self, offset, i32::from_be_bytes)
677                }
678
679                /// Read a signed 32 bit integer from offset in little-endian byte order.
680                fn read_i32_le(&self, offset: usize) -> Result<i32> {
681                    read_impl!(self, offset, i32::from_le_bytes)
682                }
683
684                /// Read a signed 64 bit integer from offset in big-endian byte order.
685                fn read_i64(&self, offset: usize) -> Result<i64> {
686                    read_impl!(self, offset, i64::from_be_bytes)
687                }
688
689                /// Read a signed 64 bit integer from offset in little-endian byte order.
690                fn read_i64_le(&self, offset: usize) -> Result<i64> {
691                    read_impl!(self, offset, i64::from_le_bytes)
692                }
693
694                /// Read a signed 128 bit integer from offset in big-endian byte order.
695                fn read_i128(&self, offset: usize) -> Result<i128> {
696                    read_impl!(self, offset, i128::from_be_bytes)
697                }
698
699                /// Read a signed 128 bit integer from offset in little-endian byte order.
700                fn read_i128_le(&self, offset: usize) -> Result<i128> {
701                    read_impl!(self, offset, i128::from_le_bytes)
702                }
703
704                /// Read an unsigned 8 bit integer from offset.
705                fn read_u8(&self, offset: usize) -> Result<u8> {
706                    let buf = self.as_slice();
707
708                    let remaining = buf.len().checked_sub(offset);
709                    match remaining {
710                        None => Err(Error::from(ErrorKind::EOF)),
711                        Some(remaining) => {
712                            if remaining < 1 {
713                                Err(Error::from(ErrorKind::EOF))
714                            } else {
715                                Ok(buf[offset])
716                            }
717                        }
718                    }
719                }
720
721                /// Read an unsigned 16 bit integer from offset in big-endian.
722                fn read_u16(&self, offset: usize) -> Result<u16> {
723                    read_impl!(self, offset, u16::from_be_bytes)
724                }
725
726                /// Read an unsigned 16 bit integer from offset in little-endian.
727                fn read_u16_le(&self, offset: usize) -> Result<u16> {
728                    read_impl!(self, offset, u16::from_le_bytes)
729                }
730
731                /// Read an unsigned integer from offset in big-endian byte order.
732                fn read_usize(&self, offset: usize) -> Result<usize> {
733                    read_impl!(self, offset, usize::from_be_bytes)
734                }
735
736                /// Read an unsigned integer from offset in little-endian byte order.
737                fn read_usize_le(&self, offset: usize) -> Result<usize> {
738                    read_impl!(self, offset, usize::from_le_bytes)
739                }
740
741                /// Read an unsigned 32 bit integer from offset in big-endian.
742                fn read_u32(&self, offset: usize) -> Result<u32> {
743                    read_impl!(self, offset, u32::from_be_bytes)
744                }
745
746                /// Read an unsigned 32 bit integer from offset in little-endian.
747                fn read_u32_le(&self, offset: usize) -> Result<u32> {
748                    read_impl!(self, offset, u32::from_le_bytes)
749                }
750
751                /// Read an unsigned 64 bit integer from offset in big-endian.
752                fn read_u64(&self, offset: usize) -> Result<u64> {
753                    read_impl!(self, offset, u64::from_be_bytes)
754                }
755
756                /// Read an unsigned 64 bit integer from offset in little-endian.
757                fn read_u64_le(&self, offset: usize) -> Result<u64> {
758                    read_impl!(self, offset, u64::from_le_bytes)
759                }
760
761                /// Read an unsigned 128 bit integer from offset in big-endian.
762                fn read_u128(&self, offset: usize) -> Result<u128> {
763                    read_impl!(self, offset, u128::from_be_bytes)
764                }
765
766                /// Read an unsigned 128 bit integer from offset in little-endian.
767                fn read_u128_le(&self, offset: usize) -> Result<u128> {
768                    read_impl!(self, offset, u128::from_le_bytes)
769                }
770
771                /// Read an IEEE754 single-precision (4 bytes) floating point number from
772                /// offset in big-endian byte order.
773                fn read_f32(&self, offset: usize) -> Result<f32> {
774                    read_impl!(self, offset, f32::from_be_bytes)
775                }
776
777                /// Read an IEEE754 single-precision (4 bytes) floating point number from
778                /// offset in little-endian byte order.
779                fn read_f32_le(&self, offset: usize) -> Result<f32> {
780                    read_impl!(self, offset, f32::from_le_bytes)
781                }
782
783                /// Read an IEEE754 single-precision (8 bytes) floating point number from
784                /// offset in big-endian byte order.
785                fn read_f64(&self, offset: usize) -> Result<f64> {
786                    read_impl!(self, offset, f64::from_be_bytes)
787                }
788
789                /// Read an IEEE754 single-precision (8 bytes) floating point number from
790                /// offset in little-endian byte order.
791                fn read_f64_le(&self, offset: usize) -> Result<f64> {
792                    read_impl!(self, offset, f64::from_le_bytes)
793                }
794            }
795        };
796    }
797
798    macro_rules! declare_async_mmap_file_mut_ext {
799        ($writer: ty) => {
800            /// Utility methods to [`AsyncMmapFileMut`]
801            ///
802            /// [`AsyncMmapFileMut`]: structs.AsyncMmapFileMut.html
803
804            #[enum_dispatch]
805            pub trait AsyncMmapFileMutExt {
806                /// Returns the mutable underlying slice of the mmap
807                fn as_mut_slice(&mut self) -> &mut [u8];
808
809                /// slice_mut returns mutable data starting from offset off of size sz.
810                ///
811                /// # Panics
812                /// If there's not enough data, it would
813                /// panic.
814                fn slice_mut(&mut self, offset: usize, sz: usize) -> &mut [u8] {
815                    &mut self.as_mut_slice()[offset..offset+sz]
816                }
817
818                /// Whether mmap is copy on write
819                fn is_cow(&self) -> bool;
820
821                /// bytes_mut returns mutable data starting from offset off of size sz.
822                ///
823                /// # Errors
824                /// If there's not enough data, it would return
825                /// `Err(Error::from(ErrorKind::EOF))`.
826                fn bytes_mut(&mut self, offset: usize, sz: usize) -> Result<&mut [u8]> {
827                    let buf = self.as_mut_slice();
828                    if buf.len() < offset + sz {
829                        Err(Error::from(ErrorKind::EOF))
830                    } else {
831                        Ok(&mut buf[offset..offset+sz])
832                    }
833                }
834
835                /// Fill 0 to the specific range
836                fn zero_range(&mut self, start: usize, end: usize) {
837                    let buf = self.as_mut_slice();
838                    let end = end.min(buf.len());
839                    buf[start..end].fill(0);
840                }
841
842                /// Flushes outstanding memory map modifications to disk (if the inner is a real file).
843                ///
844                /// When this method returns with a non-error result,
845                /// all outstanding changes to a file-backed memory map are guaranteed to be durably stored.
846                /// The file’s metadata (including last modification timestamp) may not be updated.
847                fn flush(&self) -> Result<()>;
848
849                /// Asynchronously flushes outstanding memory map modifications to disk(if the inner is a real file).
850                ///
851                /// This method initiates flushing modified pages to durable storage,
852                /// but it will not wait for the operation to complete before returning.
853                /// The file’s metadata (including last modification timestamp) may not be updated.
854                fn flush_async(&self) -> Result<()>;
855
856                /// Flushes outstanding memory map modifications in the range to disk(if the inner is a real file).
857                ///
858                /// The offset and length must be in the bounds of the memory map.
859                ///
860                /// When this method returns with a non-error result,
861                /// all outstanding changes to a file-backed memory
862                /// in the range are guaranteed to be durable stored.
863                /// The file’s metadata (including last modification timestamp) may not be updated.
864                /// It is not guaranteed the only the changes in the specified range are flushed;
865                /// other outstanding changes to the memory map may be flushed as well.
866                fn flush_range(&self, offset: usize, len: usize) -> Result<()>;
867
868                /// Asynchronously flushes outstanding memory map modifications in the range to disk(if the inner is a real file).
869                ///
870                /// The offset and length must be in the bounds of the memory map.
871                ///
872                /// This method initiates flushing modified pages to durable storage,
873                /// but it will not wait for the operation to complete before returning.
874                /// The file’s metadata (including last modification timestamp) may not be updated.
875                /// It is not guaranteed that the only changes flushed are those in the specified range;
876                /// other outstanding changes to the memory map may be flushed as well.
877                fn flush_async_range(&self, offset: usize, len: usize) -> Result<()>;
878
879                /// Truncates the file to the `max_size`, which will lead to
880                /// do re-mmap and sync_dir if the inner is a real file.
881                fn truncate(&mut self, max_sz: u64) -> impl core::future::Future<Output = Result<()>> + Send;
882
883                /// Remove the underlying file
884                fn drop_remove(self) -> impl core::future::Future<Output = Result<()>> + Send;
885
886                /// Close and truncate the underlying file
887                fn close_with_truncate(self, max_sz: i64) -> impl core::future::Future<Output = Result<()>> + Send;
888
889                /// Returns a [`AsyncMmapFileWriter`] base on the given `offset`, which helps read or write data from mmap like a normal File.
890                ///
891                /// # Notes
892                /// If you use a writer to write data to mmap, there is no guarantee all
893                /// data will be durably stored. So you need to call [`flush`]/[`flush_range`]/[`flush_async`]/[`flush_async_range`] in [`AsyncMmapFileMutExt`]
894                /// to guarantee all data will be durably stored.
895                ///
896                /// # Errors
897                /// If there's not enough data, it would return
898                ///  `Err(Error::from(ErrorKind::EOF))`.
899                ///
900                /// [`flush`]: traits.MmapFileMutExt.html#methods.flush
901                /// [`flush_range`]: traits.MmapFileMutExt.html#methods.flush_range
902                /// [`flush_async`]: traits.MmapFileMutExt.html#methods.flush_async
903                /// [`flush_async_range`]: traits.MmapFileMutExt.html#methods.flush_async_range
904                /// [`MmapFileWriter`]: structs.MmapFileWriter.html
905                fn writer(&mut self, offset: usize) -> Result<$writer> {
906                    let buf = self.as_mut_slice();
907                    let buf_len = buf.len();
908                    if buf_len < offset {
909                        Err(Error::from(ErrorKind::EOF))
910                    } else {
911                        Ok(<$writer>::new(Cursor::new(&mut buf[offset..]), offset, buf_len - offset))
912                    }
913                }
914
915                /// Returns a [`AsyncMmapFileWriter`] base on the given `offset` and `len`, which helps read or write data from mmap like a normal File.
916                ///
917                /// # Notes
918                /// If you use a writer to write data to mmap, there is no guarantee all
919                /// data will be durably stored. So you need to call [`flush`]/[`flush_range`]/[`flush_async`]/[`flush_async_range`] in [`MmapFileMutExt`]
920                /// to guarantee all data will be durably stored.
921                ///
922                /// # Errors
923                /// If there's not enough data, it would return
924                ///  `Err(Error::from(ErrorKind::EOF))`.
925                ///
926                /// [`flush`]: traits.AsyncMmapFileMutExt.html#methods.flush
927                /// [`flush_range`]: traits.AsyncMmapFileMutExt.html#methods.flush_range
928                /// [`flush_async`]: traits.AsyncMmapFileMutExt.html#methods.flush_async
929                /// [`flush_async_range`]: traits.AsyncMmapFileMutExt.html#methods.flush_async_range
930                /// [`AsyncMmapFileWriter`]: structs.AsyncMmapFileWriter.html
931                fn range_writer(&mut self, offset: usize, len: usize) -> Result<$writer> {
932                    let buf = self.as_mut_slice();
933                    if buf.len() < offset + len {
934                        Err(Error::from(ErrorKind::EOF))
935                    } else {
936                        Ok(<$writer>::new(
937                            Cursor::new(&mut buf[offset..offset + len]), offset, len))
938                    }
939                }
940
941                /// Write bytes to the mmap from the offset.
942                fn write(&mut self, src: &[u8], offset: usize) -> usize {
943                    let buf = self.as_mut_slice();
944                    if buf.len() <= offset {
945                        0
946                    } else {
947                        let remaining = buf.len() - offset;
948                        let src_len = src.len();
949                        if remaining > src_len {
950                            buf[offset..offset + src_len].copy_from_slice(src);
951                            src_len
952                        } else {
953                            buf[offset..offset + remaining].copy_from_slice(&src[..remaining]);
954                            remaining
955                        }
956                    }
957                }
958
959                /// Write the all of bytes in `src` to the mmap from the offset.
960                fn write_all(&mut self, src: &[u8], offset: usize) -> Result<()> {
961                    let buf = self.as_mut_slice();
962                    let remaining = buf.len().checked_sub(offset);
963                    match remaining {
964                        None => Err(Error::from(ErrorKind::EOF)),
965                        Some(remaining) => {
966                            let src_len = src.len();
967                            if remaining < src_len {
968                                Err(Error::from(ErrorKind::EOF))
969                            } else {
970                                buf[offset..offset + src_len].copy_from_slice(src);
971                                Ok(())
972                            }
973                        }
974                    }
975                }
976
977                /// Writes a signed 8 bit integer to mmap from the offset.
978                fn write_i8(&mut self, val: i8, offset: usize) -> Result<()> {
979                    self.write_all(&[val as u8], offset)
980                }
981
982                /// Writes a signed 16 bit integer to mmap from the offset in the big-endian byte order.
983                fn write_i16(&mut self, val: i16, offset: usize) -> Result<()> {
984                    self.write_all(&val.to_be_bytes(), offset)
985                }
986
987                /// Writes a signed 16 bit integer to mmap from the offset in the little-endian byte order.
988                fn write_i16_le(&mut self, val: i16, offset: usize) -> Result<()> {
989                    self.write_all(&val.to_le_bytes(), offset)
990                }
991
992                /// Writes a signed integer to mmap from the offset in the big-endian byte order.
993                fn write_isize(&mut self, val: isize, offset: usize) -> Result<()> {
994                    self.write_all(&val.to_be_bytes(), offset)
995                }
996
997                /// Writes a signed integer to mmap from the offset in the little-endian byte order.
998                fn write_isize_le(&mut self, val: isize, offset: usize) -> Result<()> {
999                    self.write_all(&val.to_le_bytes(), offset)
1000                }
1001
1002                /// Writes a signed 32 bit integer to mmap from the offset in the big-endian byte order.
1003                fn write_i32(&mut self, val: i32, offset: usize) -> Result<()> {
1004                    self.write_all(&val.to_be_bytes(), offset)
1005                }
1006
1007                /// Writes a signed 32 bit integer to mmap from the offset in the little-endian byte order.
1008                fn write_i32_le(&mut self, val: i32, offset: usize) -> Result<()> {
1009                    self.write_all(&val.to_le_bytes(), offset)
1010                }
1011
1012                /// Writes a signed 64 bit integer to mmap from the offset in the big-endian byte order.
1013                fn write_i64(&mut self, val: i64, offset: usize) -> Result<()> {
1014                    self.write_all(&val.to_be_bytes(), offset)
1015                }
1016
1017                /// Writes a signed 64 bit integer to mmap from the offset in the little-endian byte order.
1018                fn write_i64_le(&mut self, val: i64, offset: usize) -> Result<()> {
1019                    self.write_all(&val.to_le_bytes(), offset)
1020                }
1021
1022                /// Writes a signed 128 bit integer to mmap from the offset in the big-endian byte order.
1023                fn write_i128(&mut self, val: i128, offset: usize) -> Result<()> {
1024                    self.write_all(&val.to_be_bytes(), offset)
1025                }
1026
1027                /// Writes a signed 128 bit integer to mmap from the offset in the little-endian byte order.
1028                fn write_i128_le(&mut self, val: i128, offset: usize) -> Result<()> {
1029                    self.write_all(&val.to_le_bytes(), offset)
1030                }
1031
1032                /// Writes an unsigned 8 bit integer to mmap from the offset.
1033                fn write_u8(&mut self, val: u8, offset: usize) -> Result<()> {
1034                    self.write_all(&[val], offset)
1035                }
1036
1037                /// Writes an unsigned 16 bit integer to mmap from the offset in the big-endian byte order.
1038                fn write_u16(&mut self, val: u16, offset: usize) -> Result<()> {
1039                    self.write_all(&val.to_be_bytes(), offset)
1040                }
1041
1042                /// Writes an unsigned 16 bit integer to mmap from the offset in the little-endian byte order.
1043                fn write_u16_le(&mut self, val: u16, offset: usize) -> Result<()> {
1044                    self.write_all(&val.to_le_bytes(), offset)
1045                }
1046
1047                /// Writes an unsigned integer to mmap from the offset in the big-endian byte order.
1048                fn write_usize(&mut self, val: usize, offset: usize) -> Result<()> {
1049                    self.write_all(&val.to_be_bytes(), offset)
1050                }
1051
1052                /// Writes an unsigned integer to mmap from the offset in the little-endian byte order.
1053                fn write_usize_le(&mut self, val: usize, offset: usize) -> Result<()> {
1054                    self.write_all(&val.to_le_bytes(), offset)
1055                }
1056
1057                /// Writes an unsigned 32 bit integer to mmap from the offset in the big-endian byte order.
1058                fn write_u32(&mut self, val: u32, offset: usize) -> Result<()> {
1059                    self.write_all(&val.to_be_bytes(), offset)
1060                }
1061
1062                /// Writes an unsigned 32 bit integer to mmap from the offset in the little-endian byte order.
1063                fn write_u32_le(&mut self, val: u32, offset: usize) -> Result<()> {
1064                    self.write_all(&val.to_le_bytes(), offset)
1065                }
1066
1067                /// Writes an unsigned 64 bit integer to mmap from the offset in the big-endian byte order.
1068                fn write_u64(&mut self, val: u64, offset: usize) -> Result<()> {
1069                    self.write_all(&val.to_be_bytes(), offset)
1070                }
1071
1072                /// Writes an unsigned 64 bit integer to mmap from the offset in the little-endian byte order.
1073                fn write_u64_le(&mut self, val: u64, offset: usize) -> Result<()> {
1074                    self.write_all(&val.to_le_bytes(), offset)
1075                }
1076
1077                /// Writes an unsigned 128 bit integer to mmap from the offset in the big-endian byte order.
1078                fn write_u128(&mut self, val: u128, offset: usize) -> Result<()> {
1079                    self.write_all(&val.to_be_bytes(), offset)
1080                }
1081
1082                /// Writes an unsigned 128 bit integer to mmap from the offset in the little-endian byte order.
1083                fn write_u128_le(&mut self, val: u128, offset: usize) -> Result<()> {
1084                    self.write_all(&val.to_le_bytes(), offset)
1085                }
1086
1087                /// Writes an IEEE754 single-precision (4 bytes) floating point number to mmap from the offset in big-endian byte order.
1088                fn write_f32(&mut self, val: f32, offset: usize) -> Result<()> {
1089                    self.write_all(&val.to_be_bytes(), offset)
1090                }
1091
1092                /// Writes an IEEE754 single-precision (4 bytes) floating point number to mmap from the offset in little-endian byte order.
1093                fn write_f32_le(&mut self, val: f32, offset: usize) -> Result<()> {
1094                    self.write_all(&val.to_le_bytes(), offset)
1095                }
1096
1097                /// Writes an IEEE754 single-precision (8 bytes) floating point number to mmap from the offset in big-endian byte order.
1098                fn write_f64(&mut self, val: f64, offset: usize) -> Result<()> {
1099                    self.write_all(&val.to_be_bytes(), offset)
1100                }
1101
1102                /// Writes an IEEE754 single-precision (8 bytes) floating point number to mmap from the offset in little-endian byte order.
1103                fn write_f64_le(&mut self, val: f64, offset: usize) -> Result<()> {
1104                    self.write_all(&val.to_le_bytes(), offset)
1105                }
1106            }
1107        };
1108    }
1109
1110    macro_rules! declare_and_impl_inners {
1111        () => {
1112            enum AsyncMmapFileInner {
1113                Empty(AsyncEmptyMmapFile),
1114                Memory(AsyncMemoryMmapFile),
1115                Disk(AsyncDiskMmapFile)
1116            }
1117
1118            impl From<AsyncEmptyMmapFile> for AsyncMmapFileInner {
1119                fn from(v: AsyncEmptyMmapFile) -> AsyncMmapFileInner {
1120                    AsyncMmapFileInner::Empty(v)
1121                }
1122            }
1123            impl From<AsyncMemoryMmapFile> for AsyncMmapFileInner {
1124                fn from(v: AsyncMemoryMmapFile) -> AsyncMmapFileInner {
1125                    AsyncMmapFileInner::Memory(v)
1126                }
1127            }
1128            impl From<AsyncDiskMmapFile> for AsyncMmapFileInner {
1129                fn from(v: AsyncDiskMmapFile) -> AsyncMmapFileInner {
1130                    AsyncMmapFileInner::Disk(v)
1131                }
1132            }
1133
1134
1135            impl AsyncMmapFileExt for AsyncMmapFileInner {
1136                #[inline]
1137                fn len(&self) -> usize {
1138                    match self {
1139                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::len(inner),
1140                        AsyncMmapFileInner::Memory(inner) => AsyncMmapFileExt::len(inner),
1141                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::len(inner),
1142                    }
1143                }
1144
1145                #[inline]
1146                fn as_slice(&self) -> &[u8] {
1147                    match self {
1148                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::as_slice(inner),
1149                        AsyncMmapFileInner::Memory(inner) => AsyncMmapFileExt::as_slice(inner),
1150                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::as_slice(inner),
1151                    }
1152                }
1153
1154                #[inline]
1155                fn path(&self) -> &Path {
1156                    match self {
1157                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::path(inner),
1158                        AsyncMmapFileInner::Memory(inner) => AsyncMmapFileExt::path(inner),
1159                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::path(inner),
1160                    }
1161                }
1162
1163                #[inline]
1164                fn is_exec(&self) -> bool {
1165                    match self {
1166                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::is_exec(inner),
1167                        AsyncMmapFileInner::Memory(inner) => AsyncMmapFileExt::is_exec(inner),
1168                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::is_exec(inner),
1169                    }
1170                }
1171
1172                #[inline]
1173                async fn metadata(&self) -> Result<MetaData> {
1174                    match self {
1175                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::metadata(inner).await,
1176                        AsyncMmapFileInner::Memory(inner) => AsyncMmapFileExt::metadata(inner).await,
1177                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::metadata(inner).await,
1178                    }
1179                }
1180
1181                #[inline]
1182                fn lock_exclusive(&self) -> Result<()> {
1183                    match self {
1184                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::lock_exclusive(inner),
1185                        AsyncMmapFileInner::Memory(inner) => AsyncMmapFileExt::lock_exclusive(inner),
1186                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::lock_exclusive(inner),
1187                    }
1188                }
1189
1190                #[inline]
1191                fn lock_shared(&self) -> Result<()> {
1192                    match self {
1193                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::lock_shared(inner),
1194                        AsyncMmapFileInner::Memory(inner) => AsyncMmapFileExt::lock_shared(inner),
1195                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::lock_shared(inner),
1196                    }
1197                }
1198
1199                #[inline]
1200                fn try_lock_exclusive(&self) -> Result<()> {
1201                    match self {
1202                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::try_lock_exclusive(inner),
1203                        AsyncMmapFileInner::Memory(inner) => {
1204                            AsyncMmapFileExt::try_lock_exclusive(inner)
1205                        }
1206                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::try_lock_exclusive(inner),
1207                    }
1208                }
1209
1210                #[inline]
1211                fn try_lock_shared(&self) -> Result<()> {
1212                    match self {
1213                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::try_lock_shared(inner),
1214                        AsyncMmapFileInner::Memory(inner) => AsyncMmapFileExt::try_lock_shared(inner),
1215                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::try_lock_shared(inner),
1216                    }
1217                }
1218
1219                #[inline]
1220                fn unlock(&self) -> Result<()> {
1221                    match self {
1222                        AsyncMmapFileInner::Empty(inner) => AsyncMmapFileExt::unlock(inner),
1223                        AsyncMmapFileInner::Memory(inner) => AsyncMmapFileExt::unlock(inner),
1224                        AsyncMmapFileInner::Disk(inner) => AsyncMmapFileExt::unlock(inner),
1225                    }
1226                }
1227            }
1228
1229            enum AsyncMmapFileMutInner {
1230                Empty(AsyncEmptyMmapFile),
1231                Memory(AsyncMemoryMmapFileMut),
1232                Disk(AsyncDiskMmapFileMut)
1233            }
1234
1235            impl From<AsyncEmptyMmapFile> for AsyncMmapFileMutInner {
1236                fn from(v: AsyncEmptyMmapFile) -> AsyncMmapFileMutInner {
1237                    AsyncMmapFileMutInner::Empty(v)
1238                }
1239            }
1240            impl From<AsyncMemoryMmapFileMut> for AsyncMmapFileMutInner {
1241                fn from(v: AsyncMemoryMmapFileMut) -> AsyncMmapFileMutInner {
1242                    AsyncMmapFileMutInner::Memory(v)
1243                }
1244            }
1245            impl From<AsyncDiskMmapFileMut> for AsyncMmapFileMutInner {
1246                fn from(v: AsyncDiskMmapFileMut) -> AsyncMmapFileMutInner {
1247                    AsyncMmapFileMutInner::Disk(v)
1248                }
1249            }
1250
1251
1252            impl AsyncMmapFileExt for AsyncMmapFileMutInner {
1253                #[inline]
1254                fn len(&self) -> usize {
1255                    match self {
1256                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::len(inner),
1257                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileExt::len(inner),
1258                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::len(inner),
1259                    }
1260                }
1261
1262                #[inline]
1263                fn as_slice(&self) -> &[u8] {
1264                    match self {
1265                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::as_slice(inner),
1266                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileExt::as_slice(inner),
1267                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::as_slice(inner),
1268                    }
1269                }
1270
1271                #[inline]
1272                fn path(&self) -> &Path {
1273                    match self {
1274                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::path(inner),
1275                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileExt::path(inner),
1276                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::path(inner),
1277                    }
1278                }
1279
1280                #[inline]
1281                fn is_exec(&self) -> bool {
1282                    match self {
1283                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::is_exec(inner),
1284                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileExt::is_exec(inner),
1285                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::is_exec(inner),
1286                    }
1287                }
1288
1289                #[inline]
1290                async fn metadata(&self) -> Result<MetaData> {
1291                    match self {
1292                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::metadata(inner).await,
1293                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileExt::metadata(inner).await,
1294                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::metadata(inner).await,
1295                    }
1296                }
1297
1298                #[inline]
1299                fn lock_exclusive(&self) -> Result<()> {
1300                    match self {
1301                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::lock_exclusive(inner),
1302                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileExt::lock_exclusive(inner),
1303                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::lock_exclusive(inner),
1304                    }
1305                }
1306
1307                #[inline]
1308                fn lock_shared(&self) -> Result<()> {
1309                    match self {
1310                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::lock_shared(inner),
1311                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileExt::lock_shared(inner),
1312                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::lock_shared(inner),
1313                    }
1314                }
1315
1316                #[inline]
1317                fn try_lock_exclusive(&self) -> Result<()> {
1318                    match self {
1319                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::try_lock_exclusive(inner),
1320                        AsyncMmapFileMutInner::Memory(inner) => {
1321                            AsyncMmapFileExt::try_lock_exclusive(inner)
1322                        }
1323                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::try_lock_exclusive(inner),
1324                    }
1325                }
1326
1327                #[inline]
1328                fn try_lock_shared(&self) -> Result<()> {
1329                    match self {
1330                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::try_lock_shared(inner),
1331                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileExt::try_lock_shared(inner),
1332                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::try_lock_shared(inner),
1333                    }
1334                }
1335
1336                #[inline]
1337                fn unlock(&self) -> Result<()> {
1338                    match self {
1339                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileExt::unlock(inner),
1340                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileExt::unlock(inner),
1341                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileExt::unlock(inner),
1342                    }
1343                }
1344            }
1345
1346
1347            impl AsyncMmapFileMutExt for AsyncMmapFileMutInner {
1348                #[inline]
1349                fn as_mut_slice(&mut self) -> &mut [u8] {
1350                    match self {
1351                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileMutExt::as_mut_slice(inner),
1352                        AsyncMmapFileMutInner::Memory(inner) => {
1353                            AsyncMmapFileMutExt::as_mut_slice(inner)
1354                        }
1355                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileMutExt::as_mut_slice(inner),
1356                    }
1357                }
1358
1359                #[inline]
1360                fn is_cow(&self) -> bool {
1361                    match self {
1362                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileMutExt::is_cow(inner),
1363                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileMutExt::is_cow(inner),
1364                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileMutExt::is_cow(inner),
1365                    }
1366                }
1367
1368                #[inline]
1369                fn flush(&self) -> Result<()> {
1370                    match self {
1371                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileMutExt::flush(inner),
1372                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileMutExt::flush(inner),
1373                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileMutExt::flush(inner),
1374                    }
1375                }
1376
1377                #[inline]
1378                fn flush_async(&self) -> Result<()> {
1379                    match self {
1380                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileMutExt::flush_async(inner),
1381                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileMutExt::flush_async(inner),
1382                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileMutExt::flush_async(inner),
1383                    }
1384                }
1385
1386                #[inline]
1387                fn flush_range(&self, offset: usize, len: usize) -> Result<()> {
1388                    match self {
1389                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileMutExt::flush_range(
1390                            inner,
1391                            offset,
1392                            len,
1393                        ),
1394                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileMutExt::flush_range(
1395                            inner,
1396                            offset,
1397                            len,
1398                        ),
1399                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileMutExt::flush_range(
1400                            inner,
1401                            offset,
1402                            len,
1403                        ),
1404                    }
1405                }
1406
1407                #[inline]
1408                fn flush_async_range(&self, offset: usize, len: usize) -> Result<()> {
1409                    match self {
1410                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileMutExt::flush_async_range(
1411                            inner,
1412                            offset,
1413                            len,
1414                        ),
1415                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileMutExt::flush_async_range(
1416                            inner,
1417                            offset,
1418                            len,
1419                        ),
1420                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileMutExt::flush_async_range(
1421                            inner,
1422                            offset,
1423                            len,
1424                        ),
1425                    }
1426                }
1427
1428                async fn truncate(&mut self, max_sz: u64) -> Result<()> {
1429                    match self {
1430                        AsyncMmapFileMutInner::Empty(inner) => {
1431                            AsyncMmapFileMutExt::truncate(inner, max_sz).await
1432                        }
1433                        AsyncMmapFileMutInner::Memory(inner) => {
1434                            AsyncMmapFileMutExt::truncate(inner, max_sz).await
1435                        }
1436                        AsyncMmapFileMutInner::Disk(inner) => {
1437                            AsyncMmapFileMutExt::truncate(inner, max_sz).await
1438                        }
1439                    }
1440                }
1441
1442                async fn drop_remove(self) -> Result<()> {
1443                    match self {
1444                        AsyncMmapFileMutInner::Empty(inner) => AsyncMmapFileMutExt::drop_remove(inner).await,
1445                        AsyncMmapFileMutInner::Memory(inner) => AsyncMmapFileMutExt::drop_remove(inner).await,
1446                        AsyncMmapFileMutInner::Disk(inner) => AsyncMmapFileMutExt::drop_remove(inner).await,
1447                    }
1448                }
1449
1450                async fn close_with_truncate(self, max_sz: i64) -> Result<()> {
1451                    match self {
1452                        AsyncMmapFileMutInner::Empty(inner) => {
1453                            AsyncMmapFileMutExt::close_with_truncate(inner, max_sz).await
1454                        }
1455                        AsyncMmapFileMutInner::Memory(inner) => {
1456                            AsyncMmapFileMutExt::close_with_truncate(inner, max_sz).await
1457                        }
1458                        AsyncMmapFileMutInner::Disk(inner) => {
1459                            AsyncMmapFileMutExt::close_with_truncate(inner, max_sz).await
1460                        }
1461                    }
1462                }
1463            }
1464
1465        };
1466    }
1467
1468
1469    macro_rules! declare_and_impl_async_mmap_file {
1470        ($filename_prefix: literal, $doc_test_runtime: literal, $path_str: literal) => {
1471            /// A read-only memory map file.
1472            ///
1473            /// There is 3 status of this struct:
1474            /// - __Disk__: mmap to a real file
1475            /// - __Memory__: use [`Bytes`] to mock a mmap, which is useful for test and in-memory storage engine
1476            /// - __Empty__: a state represents null mmap, which is helpful for drop, close the `AsyncMmapFile`. This state cannot be constructed directly.
1477            ///
1478            /// [`Bytes`]: https://docs.rs/bytes/1.1.0/bytes/struct.Bytes.html
1479            #[repr(transparent)]
1480            pub struct AsyncMmapFile {
1481                inner: AsyncMmapFileInner
1482            }
1483
1484            impl_from!(AsyncMmapFile, AsyncMmapFileInner, [AsyncEmptyMmapFile, AsyncMemoryMmapFile, AsyncDiskMmapFile]);
1485
1486            impl_async_mmap_file_ext!(AsyncMmapFile);
1487
1488            impl AsyncMmapFile {
1489                /// Open a readable memory map backed by a file
1490                ///
1491                /// # Examples
1492                ///
1493                #[doc = "```ignore"]
1494                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFile, AsyncMmapFileExt};")]
1495                #[doc = concat!("# use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileMutExt};")]
1496                /// # use scopeguard::defer;
1497                ///
1498                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1499                #[doc = concat!("# let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_test.txt\").await.unwrap();")]
1500                #[doc = concat!(" # defer!(std::fs::remove_file(\"", $filename_prefix, "_open_test.txt\").unwrap());")]
1501                /// # file.truncate(12).await.unwrap();
1502                /// # file.write_all("some data...".as_bytes(), 0).unwrap();
1503                /// # file.flush().unwrap();
1504                /// # drop(file);
1505                /// // mmap the file
1506                #[doc = concat!("let mut file = AsyncMmapFile::open(\"", $filename_prefix, "_open_test.txt\").await.unwrap();")]
1507                /// let mut buf = vec![0; "some data...".len()];
1508                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1509                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1510                /// # })
1511                #[doc = "```"]
1512                pub async fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
1513                    Ok(Self::from(AsyncDiskMmapFile::open(path).await?))
1514                }
1515
1516                /// Open a readable memory map backed by a file with [`Options`]
1517                ///
1518                /// # Examples
1519                ///
1520                #[doc = "```ignore"]
1521                #[doc = concat!("use fmmap::", $path_str, "::{AsyncOptions, AsyncMmapFile, AsyncMmapFileExt};")]
1522                #[doc = concat!("# use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileMutExt};")]
1523                /// # use scopeguard::defer;
1524                ///
1525                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1526                #[doc = concat!("# let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_with_options_test.txt\").await.unwrap();")]
1527                #[doc = concat!(" # defer!(std::fs::remove_file(\"", $filename_prefix, "_open_with_options_test.txt\").unwrap());")]
1528                /// # file.truncate(23).await.unwrap();
1529                /// # file.write_all("sanity text".as_bytes(), 0).unwrap();
1530                /// # file.write_all("some data...".as_bytes(), "sanity text".as_bytes().len()).unwrap();
1531                /// # file.flush().unwrap();
1532                /// # drop(file);
1533                ///
1534                /// // mmap the file
1535                /// let opts = AsyncOptions::new()
1536                ///     // mmap content after the sanity text
1537                ///     .offset("sanity text".as_bytes().len() as u64);
1538                /// // mmap the file
1539                #[doc = concat!("let mut file = AsyncMmapFile::open_with_options(\"", $filename_prefix, "_open_with_options_test.txt\", opts).await.unwrap();")]
1540                /// let mut buf = vec![0; "some data...".len()];
1541                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1542                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1543                /// # })
1544                #[doc = "```"]
1545                ///
1546                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
1547                pub async fn open_with_options<P: AsRef<Path>>(path: P, opts: AsyncOptions) -> Result<Self> {
1548                    Ok(Self::from(AsyncDiskMmapFile::open_with_options(path, opts).await?))
1549                }
1550
1551                /// Open a readable and executable memory map backed by a file
1552                ///
1553                /// # Examples
1554                ///
1555                #[doc = "```ignore"]
1556                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFile, AsyncMmapFileExt};")]
1557                #[doc = concat!("# use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileMutExt};")]
1558                /// # use scopeguard::defer;
1559                ///
1560                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1561                #[doc = concat!("# let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_exec_test.txt\").await.unwrap();")]
1562                #[doc = concat!(" # defer!(std::fs::remove_file(\"", $filename_prefix, "_open_exec_test.txt\").unwrap());")]
1563                /// # file.truncate(12).await.unwrap();
1564                /// # file.write_all("some data...".as_bytes(), 0).unwrap();
1565                /// # file.flush().unwrap();
1566                /// # drop(file);
1567                /// // mmap the file
1568                #[doc = concat!("let mut file = AsyncMmapFile::open_exec(\"", $filename_prefix, "_open_exec_test.txt\").await.unwrap();")]
1569                /// let mut buf = vec![0; "some data...".len()];
1570                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1571                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1572                /// # })
1573                #[doc = "```"]
1574                pub async fn open_exec<P: AsRef<Path>>(path: P) -> Result<Self> {
1575                    Ok(Self::from(AsyncDiskMmapFile::open_exec(path).await?))
1576                }
1577
1578                /// Open a readable and executable memory map backed by a file with [`Options`].
1579                ///
1580                /// # Examples
1581                ///
1582                #[doc = "```ignore"]
1583                #[doc = concat!("use fmmap::", $path_str, "::{AsyncOptions, AsyncMmapFile, AsyncMmapFileExt};")]
1584                #[doc = concat!("# use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileMutExt};")]
1585                /// # use scopeguard::defer;
1586                ///
1587                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1588                #[doc = concat!("# let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_exec_with_options_test.txt\").await.unwrap();")]
1589                #[doc = concat!(" # defer!(std::fs::remove_file(\"", $filename_prefix, "_open_exec_with_options_test.txt\").unwrap());")]
1590                /// # file.truncate(23).await.unwrap();
1591                /// # file.write_all("sanity text".as_bytes(), 0).unwrap();
1592                /// # file.write_all("some data...".as_bytes(), "sanity text".as_bytes().len()).unwrap();
1593                /// # file.flush().unwrap();
1594                /// # drop(file);
1595                ///
1596                /// // mmap the file
1597                /// let opts = AsyncOptions::new()
1598                ///     // mmap content after the sanity text
1599                ///     .offset("sanity text".as_bytes().len() as u64);
1600                /// // mmap the file
1601                #[doc = concat!("let mut file = AsyncMmapFile::open_exec_with_options(\"", $filename_prefix, "_open_exec_with_options_test.txt\", opts).await.unwrap();")]
1602                /// let mut buf = vec![0; "some data...".len()];
1603                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1604                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1605                /// # })
1606                #[doc = "```"]
1607                ///
1608                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
1609                pub async fn open_exec_with_options<P: AsRef<Path>>(path: P, opts: AsyncOptions) -> Result<Self> {
1610                    Ok(Self::from(AsyncDiskMmapFile::open_exec_with_options(path, opts).await?))
1611                }
1612            }
1613
1614            impl_constructor_for_memory_mmap_file!(AsyncMemoryMmapFile, AsyncMmapFile, "AsyncMmapFile", $path_str);
1615        };
1616    }
1617
1618    macro_rules! delcare_and_impl_async_mmap_file_mut {
1619        ($filename_prefix: literal, $doc_test_runtime: literal, $path_str: literal) => {
1620            /// A writable memory map file.
1621            ///
1622            /// There is 3 status of this struct:
1623            /// - __Disk__: mmap to a real file
1624            /// - __Memory__: use [`BytesMut`] to mock a mmap, which is useful for test and in-memory storage engine
1625            /// - __Empty__: a state represents null mmap, which is helpful for drop, remove, close the `AsyncMmapFileMut`. This state cannot be constructed directly.
1626            ///
1627            /// [`BytesMut`]: https://docs.rs/bytes/1.1.0/bytes/struct.BytesMut.html
1628            pub struct AsyncMmapFileMut {
1629                inner: AsyncMmapFileMutInner,
1630                remove_on_drop: bool,
1631                deleted: bool,
1632            }
1633
1634            impl_from_mut!(AsyncMmapFileMut, AsyncMmapFileMutInner, [AsyncEmptyMmapFile, AsyncMemoryMmapFileMut, AsyncDiskMmapFileMut]);
1635
1636            impl_async_mmap_file_ext!(AsyncMmapFileMut);
1637
1638            impl_async_mmap_file_mut_ext!($filename_prefix, $doc_test_runtime, $path_str);
1639
1640            impl AsyncMmapFileMut {
1641                /// Create a new file and mmap this file
1642                ///
1643                /// # Notes
1644                /// The new file is zero size, so, before write, you should truncate first.
1645                /// Or you can use [`create_with_options`] and set `max_size` field for [`AsyncOptions`] to enable directly write
1646                /// without truncating.
1647                /// # Examples
1648                ///
1649                #[doc = "```ignore"]
1650                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileMutExt};")]
1651                /// # use scopeguard::defer;
1652                ///
1653                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1654                #[doc = concat!("let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_create_test.txt\").await.unwrap();")]
1655                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_create_test.txt\").unwrap());")]
1656                /// file.truncate(12).await;
1657                /// file.write_all("some data...".as_bytes(), 0).unwrap();
1658                /// file.flush().unwrap();
1659                /// # })
1660                #[doc = "```"]
1661                ///
1662                #[doc = concat!("[`create_with_options`]: ", $path_str, "/struct.AsyncMmapFileMut.html#method.create_with_options")]
1663                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
1664                pub async fn create<P: AsRef<Path>>(path: P) -> Result<Self> {
1665                    Ok(Self::from(AsyncDiskMmapFileMut::create(path).await?))
1666                }
1667
1668                /// Create a new file and mmap this file with [`AsyncOptions`]
1669                ///
1670                /// # Example
1671                ///
1672                #[doc = "```ignore"]
1673                #[doc = concat!("use fmmap::", $path_str, "::{AsyncOptions, AsyncMmapFileMut, AsyncMmapFileMutExt};")]
1674                /// # use scopeguard::defer;
1675                ///
1676                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1677                /// let opts = AsyncOptions::new()
1678                ///     // truncate to 100
1679                ///     .max_size(100);
1680                #[doc = concat!("let mut file = AsyncMmapFileMut::create_with_options(\"", $filename_prefix, "_create_with_options_test.txt\", opts).await.unwrap();")]
1681                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_create_with_options_test.txt\").unwrap());")]
1682                /// file.write_all("some data...".as_bytes(), 0).unwrap();
1683                /// file.flush().unwrap();
1684                /// # })
1685                #[doc = "```"]
1686                ///
1687                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
1688                pub async fn create_with_options<P: AsRef<Path>>(path: P, opts: AsyncOptions) -> Result<Self> {
1689                    Ok(Self::from(AsyncDiskMmapFileMut::create_with_options(path, opts).await?))
1690                }
1691
1692                /// Open or Create(if not exists) a file and mmap this file.
1693                ///
1694                /// # Notes
1695                /// If the file does not exist, then the new file will be open in zero size, so before do write, you should truncate first.
1696                /// Or you can use [`open_with_options`] and set `max_size` field for [`AsyncOptions`] to enable directly write
1697                /// without truncating.
1698                ///
1699                /// # Examples
1700                ///
1701                /// File already exists
1702                ///
1703                #[doc = "```ignore"]
1704                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileExt, AsyncMmapFileMutExt};")]
1705                /// # use scopeguard::defer;
1706                ///
1707                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1708                #[doc = concat!("# let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_test.txt\").await.unwrap();")]
1709                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_open_test.txt\").unwrap());")]
1710                /// # file.truncate(12).await.unwrap();
1711                /// # file.write_all("some data...".as_bytes(), 0).unwrap();
1712                /// # file.flush().unwrap();
1713                /// # drop(file);
1714                ///
1715                /// // mmap the file
1716                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_test.txt\").await.unwrap();")]
1717                /// let mut buf = vec![0; "some data...".len()];
1718                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1719                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1720                ///
1721                /// // modify the file data
1722                /// file.truncate("some modified data...".len() as u64).await.unwrap();
1723                /// file.write_all("some modified data...".as_bytes(), 0).unwrap();
1724                /// file.flush().unwrap();
1725                /// drop(file);
1726                ///
1727                /// // reopen to check content
1728                /// let mut buf = vec![0; "some modified data...".len()];
1729                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_test.txt\").await.unwrap();")]
1730                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1731                /// assert_eq!(buf.as_slice(), "some modified data...".as_bytes());
1732                /// # })
1733                #[doc = "```"]
1734                ///
1735                /// File does not exists
1736                ///
1737                #[doc = "```ignore"]
1738                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileExt, AsyncMmapFileMutExt};")]
1739                /// # use scopeguard::defer;
1740                ///
1741                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1742                /// // mmap the file
1743                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_test.txt\").await.unwrap();")]
1744                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_open_test.txt\").unwrap());")]
1745                /// file.truncate(100).await.unwrap();
1746                /// file.write_all("some data...".as_bytes(), 0).unwrap();
1747                /// file.flush().unwrap();
1748                ///
1749                /// let mut buf = vec![0; "some data...".len()];
1750                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1751                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1752                ///
1753                /// // modify the file data
1754                /// file.truncate("some modified data...".len() as u64).await.unwrap();
1755                /// file.write_all("some modified data...".as_bytes(), 0).unwrap();
1756                /// file.flush().unwrap();
1757                /// drop(file);
1758                ///
1759                /// // reopen to check content
1760                /// let mut buf = vec![0; "some modified data...".len()];
1761                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_test.txt\").await.unwrap();")]
1762                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1763                /// assert_eq!(buf.as_slice(), "some modified data...".as_bytes());
1764                /// # })
1765                #[doc = "```"]
1766                ///
1767                #[doc = concat!("[`open_with_options`]: ", $path_str, "/struct.AsyncMmapFileMut.html#method.open_with_options")]
1768                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
1769                pub async fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
1770                    Ok(Self::from(AsyncDiskMmapFileMut::open(path).await?))
1771                }
1772
1773                /// Open or Create(if not exists) a file and mmap this file with [`AsyncOptions`].
1774                ///
1775                /// # Examples
1776                ///
1777                /// File already exists
1778                ///
1779                /// ```ignore
1780                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileExt, AsyncMmapFileMutExt, AsyncOptions};")]
1781                /// # use scopeguard::defer;
1782                ///
1783                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1784                #[doc = concat!("# let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_with_options_test.txt\").await.unwrap();")]
1785                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_open_with_options_test.txt\").unwrap());")]
1786                /// # file.truncate(23).await.unwrap();
1787                /// # file.write_all("sanity text".as_bytes(), 0).unwrap();
1788                /// # file.write_all("some data...".as_bytes(), "sanity text".as_bytes().len()).unwrap();
1789                /// # file.flush().unwrap();
1790                /// # drop(file);
1791                ///
1792                /// // mmap the file
1793                /// let opts = AsyncOptions::new()
1794                ///     // allow read
1795                ///     .read(true)
1796                ///     // allow write
1797                ///     .write(true)
1798                ///     // allow append
1799                ///     .append(true)
1800                ///     // truncate to 100
1801                ///     .max_size(100)
1802                ///     // mmap content after the sanity text
1803                ///     .offset("sanity text".as_bytes().len() as u64);
1804                #[doc = concat!("let mut file = AsyncMmapFileMut::open_with_options(\"", $filename_prefix, "_open_with_options_test.txt\", opts).await.unwrap();")]
1805                /// let mut buf = vec![0; "some data...".len()];
1806                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1807                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1808                ///
1809                /// // modify the file data
1810                /// file.truncate(("some modified data...".len() + "sanity text".len()) as u64).await.unwrap();
1811                /// file.write_all("some modified data...".as_bytes(), 0).unwrap();
1812                /// file.flush().unwrap();
1813                /// drop(file);
1814                ///
1815                /// // reopen to check content
1816                /// let mut buf = vec![0; "some modified data...".len()];
1817                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_with_options_test.txt\").await.unwrap();")]
1818                /// // skip the sanity text
1819                /// file.read_exact(buf.as_mut_slice(), "sanity text".as_bytes().len()).unwrap();
1820                /// assert_eq!(buf.as_slice(), "some modified data...".as_bytes());
1821                /// # })
1822                #[doc = "```"]
1823                ///
1824                /// File does not exists
1825                ///
1826                /// ```ignore
1827                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileExt, AsyncMmapFileMutExt, AsyncOptions};")]
1828                /// # use scopeguard::defer;
1829                ///
1830                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1831                /// // mmap the file with options
1832                /// let opts = AsyncOptions::new()
1833                ///     // allow read
1834                ///     .read(true)
1835                ///     // allow write
1836                ///     .write(true)
1837                ///     // allow append
1838                ///     .append(true)
1839                ///     // truncate to 100
1840                ///     .max_size(100);
1841                ///
1842                #[doc = concat!("let mut file = AsyncMmapFileMut::open_with_options(\"", $filename_prefix, "_open_with_options_test.txt\", opts).await.unwrap();")]
1843                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_open_with_options_test.txt\").unwrap());")]
1844                /// file.write_all("some data...".as_bytes(), 0).unwrap();
1845                ///
1846                /// let mut buf = vec![0; "some data...".len()];
1847                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1848                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1849                ///
1850                /// // modify the file data
1851                /// file.truncate("some modified data...".len() as u64).await.unwrap();
1852                /// file.write_all("some modified data...".as_bytes(), 0).unwrap();
1853                /// file.flush().unwrap();
1854                /// drop(file);
1855                ///
1856                /// // reopen to check content
1857                /// let mut buf = vec![0; "some modified data...".len()];
1858                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_with_options_test.txt\").await.unwrap();")]
1859                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1860                /// assert_eq!(buf.as_slice(), "some modified data...".as_bytes());
1861                /// # })
1862                #[doc = "```"]
1863                ///
1864                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
1865                pub async fn open_with_options<P: AsRef<Path>>(path: P, opts: AsyncOptions) -> Result<Self> {
1866                    Ok(Self::from(AsyncDiskMmapFileMut::open_with_options(path, opts).await?))
1867                }
1868
1869                /// Open an existing file and mmap this file
1870                ///
1871                /// # Examples
1872                #[doc = "```ignore"]
1873                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileExt, AsyncMmapFileMutExt};")]
1874                /// # use scopeguard::defer;
1875                ///
1876                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1877                /// // create a temp file
1878                #[doc = concat!("let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_existing_test.txt\").await.unwrap();")]
1879                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_open_existing_test.txt\").unwrap());")]
1880                /// file.truncate(12).await.unwrap();
1881                /// file.write_all("some data...".as_bytes(), 0).unwrap();
1882                /// file.flush().unwrap();
1883                /// drop(file);
1884                ///
1885                /// // mmap the file
1886                #[doc = concat!("let mut file = AsyncMmapFileMut::open_exist(\"", $filename_prefix, "_open_existing_test.txt\").await.unwrap();")]
1887                /// let mut buf = vec![0; "some data...".len()];
1888                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1889                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1890                ///
1891                /// // modify the file data
1892                /// file.truncate("some modified data...".len() as u64).await.unwrap();
1893                /// file.write_all("some modified data...".as_bytes(), 0).unwrap();
1894                /// file.flush().unwrap();
1895                /// drop(file);
1896                ///
1897                ///
1898                /// // reopen to check content
1899                /// let mut buf = vec![0; "some modified data...".len()];
1900                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_existing_test.txt\").await.unwrap();")]
1901                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1902                /// assert_eq!(buf.as_slice(), "some modified data...".as_bytes());
1903                /// # })
1904                #[doc = "```"]
1905                ///
1906                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
1907                pub async fn open_exist<P: AsRef<Path>>(path: P) -> Result<Self> {
1908                    Ok(Self::from(AsyncDiskMmapFileMut::open_exist(path).await?))
1909                }
1910
1911                /// Open an existing file and mmap this file with [`AsyncOptions`]
1912                ///
1913                /// # Examples
1914                ///
1915                /// ```ignore
1916                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileExt, AsyncMmapFileMutExt, AsyncOptions};")]
1917                /// # use scopeguard::defer;
1918                ///
1919                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1920                /// // create a temp file
1921                #[doc = concat!("let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_existing_test_with_options.txt\").await.unwrap();")]
1922                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_open_existing_test_with_options.txt\").unwrap());")]
1923                /// file.truncate(23).await.unwrap();
1924                /// file.write_all("sanity text".as_bytes(), 0).unwrap();
1925                /// file.write_all("some data...".as_bytes(), "sanity text".as_bytes().len()).unwrap();
1926                /// file.flush().unwrap();
1927                /// drop(file);
1928                ///
1929                /// // mmap the file
1930                /// let opts = AsyncOptions::new()
1931                ///     // truncate to 100
1932                ///     .max_size(100)
1933                ///     // mmap content after the sanity text
1934                ///     .offset("sanity text".as_bytes().len() as u64);
1935                ///
1936                #[doc = concat!("let mut file = AsyncMmapFileMut::open_exist_with_options(\"", $filename_prefix, "_open_existing_test_with_options.txt\", opts).await.unwrap();")]
1937                ///
1938                /// let mut buf = vec![0; "some data...".len()];
1939                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1940                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1941                ///
1942                /// // modify the file data
1943                /// file.truncate(("some modified data...".len() + "sanity text".len()) as u64).await.unwrap();
1944                /// file.write_all("some modified data...".as_bytes(), 0).unwrap();
1945                /// file.flush().unwrap();
1946                ///
1947                /// // reopen to check content, cow will not change the content.
1948                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_existing_test_with_options.txt\").await.unwrap();")]
1949                /// let mut buf = vec![0; "some modified data...".len()];
1950                /// // skip the sanity text
1951                /// // file.read_exact(buf.as_mut_slice(), "sanity text".as_bytes().len()).unwrap();
1952                /// // assert_eq!(buf.as_slice(), "some modified data...".as_bytes());
1953                /// # })
1954                #[doc = "```"]
1955                ///
1956                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
1957                pub async fn open_exist_with_options<P: AsRef<Path>>(path: P, opts: AsyncOptions) -> Result<Self> {
1958                    Ok(Self::from(AsyncDiskMmapFileMut::open_exist_with_options(path, opts).await?))
1959                }
1960
1961                /// Open and mmap an existing file in copy-on-write mode(copy-on-write memory map backed by a file).
1962                /// Data written to the memory map will not be visible by other processes, and will not be carried through to the underlying file.
1963                ///
1964                /// # Examples
1965                ///
1966                #[doc = "```ignore"]
1967                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileExt, AsyncMmapFileMutExt};")]
1968                /// # use scopeguard::defer;
1969                ///
1970                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
1971                /// // create a temp file
1972                #[doc = concat!("let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_cow_test.txt\").await.unwrap();")]
1973                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_open_cow_test.txt\").unwrap());")]
1974                /// file.truncate(12).await.unwrap();
1975                /// file.write_all("some data...".as_bytes(), 0).unwrap();
1976                /// file.flush().unwrap();
1977                /// drop(file);
1978                ///
1979                /// // mmap the file
1980                #[doc = concat!("let mut file = AsyncMmapFileMut::open_cow(\"", $filename_prefix, "_open_cow_test.txt\").await.unwrap();")]
1981                /// let mut buf = vec![0; "some data...".len()];
1982                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1983                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1984                ///
1985                /// // modify the file data
1986                /// file.write_all("some data!!!".as_bytes(), 0).unwrap();
1987                /// file.flush().unwrap();
1988                ///
1989                /// // cow, change will only be seen in current caller
1990                /// assert_eq!(file.as_slice(), "some data!!!".as_bytes());
1991                /// drop(file);
1992                ///
1993                /// // reopen to check content, cow will not change the content.
1994                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_cow_test.txt\").await.unwrap();")]
1995                /// let mut buf = vec![0; "some data...".len()];
1996                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
1997                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
1998                /// # })
1999                #[doc = "```"]
2000                ///
2001                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
2002                pub async fn open_cow<P: AsRef<Path>>(path: P) -> Result<Self> {
2003                    Ok(Self::from(AsyncDiskMmapFileMut::open_cow(path).await?))
2004                }
2005
2006                /// Open and mmap an existing file in copy-on-write mode(copy-on-write memory map backed by a file) with [`AsyncOptions`].
2007                /// Data written to the memory map will not be visible by other processes, and will not be carried through to the underlying file.
2008                ///
2009                /// # Examples
2010                ///
2011                #[doc = "```ignore"]
2012                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileExt, AsyncMmapFileMutExt, AsyncOptions};")]
2013                /// use std::io::SeekFrom;
2014                /// # use scopeguard::defer;
2015                ///
2016                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
2017                /// // create a temp file
2018                #[doc = concat!("let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_open_cow_with_options_test.txt\").await.unwrap();")]
2019                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_open_cow_with_options_test.txt\").unwrap());")]
2020                /// file.truncate(23).await.unwrap();
2021                /// file.write_all("sanity text".as_bytes(), 0).unwrap();
2022                /// file.write_all("some data...".as_bytes(), "sanity text".as_bytes().len()).unwrap();
2023                /// file.flush().unwrap();
2024                /// drop(file);
2025                ///
2026                /// // mmap the file
2027                /// let opts = AsyncOptions::new()
2028                ///     // mmap content after the sanity text
2029                ///     .offset("sanity text".as_bytes().len() as u64);
2030                ///
2031                #[doc = concat!("let mut file = AsyncMmapFileMut::open_cow_with_options(\"", $filename_prefix, "_open_cow_with_options_test.txt\", opts).await.unwrap();")]
2032                /// let mut buf = vec![0; "some data...".len()];
2033                /// file.read_exact(buf.as_mut_slice(), 0).unwrap();
2034                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
2035                ///
2036                /// // modify the file data
2037                /// file.write_all("some data!!!".as_bytes(), 0).unwrap();
2038                /// file.flush().unwrap();
2039                ///
2040                /// // cow, change will only be seen in current caller
2041                /// assert_eq!(file.as_slice(), "some data!!!".as_bytes());
2042                /// drop(file);
2043                ///
2044                /// // reopen to check content, cow will not change the content.
2045                #[doc = concat!("let mut file = AsyncMmapFileMut::open(\"", $filename_prefix, "_open_cow_with_options_test.txt\").await.unwrap();")]
2046                /// let mut buf = vec![0; "some data...".len()];
2047                /// // skip the sanity text
2048                /// file.read_exact(buf.as_mut_slice(), "sanity text".as_bytes().len()).unwrap();
2049                /// assert_eq!(buf.as_slice(), "some data...".as_bytes());
2050                /// # })
2051                #[doc = "```"]
2052                ///
2053                #[doc = concat!("[`AsyncOptions`]: ", $path_str, "/struct.AsyncOptions.html")]
2054                pub async fn open_cow_with_options<P: AsRef<Path>>(path: P, opts: AsyncOptions) -> Result<Self> {
2055                    Ok(Self::from(AsyncDiskMmapFileMut::open_cow_with_options(path, opts).await?))
2056                }
2057
2058                /// Make the mmap file read-only.
2059                ///
2060                /// # Notes
2061                /// If `remove_on_drop` is set to `true`, then the underlying file will not be removed on drop if this function is invoked. [Read more]
2062                ///
2063                /// Returns an immutable version of this memory mapped buffer.
2064                /// If the memory map is file-backed, the file must have been opened with read permissions.
2065                ///
2066                /// # Errors
2067                /// This method returns an error when the underlying system call fails,
2068                /// which can happen for a variety of reasons,
2069                /// such as when the file has not been opened with read permissions.
2070                ///
2071                /// # Examples
2072                ///
2073                #[doc = "```ignore"]
2074                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileMutExt};")]
2075                /// # use scopeguard::defer;
2076                ///
2077                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
2078                #[doc = concat!("let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_freeze_test.txt\").await.unwrap();")]
2079                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_freeze_test.txt\").unwrap());")]
2080                /// file.truncate(12).await;
2081                /// file.write_all("some data...".as_bytes(), 0).unwrap();
2082                /// file.flush().unwrap();
2083                /// // freeze
2084                /// file.freeze().unwrap();
2085                /// # })
2086                #[doc = "```"]
2087                ///
2088                #[doc = concat!("[Read more]: ", $path_str, "/struct.AsyncMmapFileMut.html#methods.set_remove_on_drop")]
2089                ///
2090                #[inline]
2091                pub fn freeze(mut self) -> Result<AsyncMmapFile> {
2092                    let empty = AsyncMmapFileMutInner::Empty(AsyncEmptyMmapFile::default());
2093                    // swap the inner to empty
2094                    let inner = mem::replace(&mut self.inner, empty);
2095                    match inner {
2096                        AsyncMmapFileMutInner::Empty(empty) => Ok(AsyncMmapFile::from(empty)), // unreachable, keep this for good measure
2097                        AsyncMmapFileMutInner::Memory(memory) => Ok(AsyncMmapFile::from(memory.freeze())),
2098                        AsyncMmapFileMutInner::Disk(disk) => Ok(AsyncMmapFile::from(disk.freeze()?)),
2099                    }
2100                }
2101
2102                /// Transition the memory map to be readable and executable.
2103                /// If the memory map is file-backed, the file must have been opened with execute permissions.
2104                ///
2105                /// # Notes
2106                /// If `remove_on_drop` is set to `true`, then the underlying file will not be removed on drop if this function is invoked. [Read more]
2107                ///
2108                /// # Errors
2109                /// This method returns an error when the underlying system call fails,
2110                /// which can happen for a variety of reasons,
2111                /// such as when the file has not been opened with execute permissions
2112                ///
2113                /// # Examples
2114                ///
2115                #[doc = "```ignore"]
2116                #[doc = concat!("use fmmap::", $path_str, "::{AsyncMmapFileMut, AsyncMmapFileMutExt};")]
2117                /// # use scopeguard::defer;
2118                ///
2119                #[doc = concat!("# ", $doc_test_runtime, "::block_on(async {")]
2120                #[doc = concat!("let mut file = AsyncMmapFileMut::create(\"", $filename_prefix, "_freeze_exec_test.txt\").await.unwrap();")]
2121                #[doc = concat!("# defer!(std::fs::remove_file(\"", $filename_prefix, "_freeze_exec_test.txt\").unwrap());")]
2122                /// file.truncate(12).await;
2123                /// file.write_all("some data...".as_bytes(), 0).unwrap();
2124                /// file.flush().unwrap();
2125                /// // freeze_exec
2126                /// file.freeze_exec().unwrap();
2127                /// # })
2128                #[doc = "```"]
2129                ///
2130                #[doc = concat!("[Read more]: ", $path_str, "/struct.AsyncMmapFileMut.html#methods.set_remove_on_drop")]
2131                ///
2132                #[inline]
2133                pub fn freeze_exec(mut self) -> Result<AsyncMmapFile> {
2134                    let empty = AsyncMmapFileMutInner::Empty(AsyncEmptyMmapFile::default());
2135                    // swap the inner to empty
2136                    let inner = mem::replace(&mut self.inner, empty);
2137                    match inner {
2138                        AsyncMmapFileMutInner::Empty(empty) => Ok(AsyncMmapFile::from(empty)), // unreachable, keep this for good measure
2139                        AsyncMmapFileMutInner::Memory(memory) => Ok(AsyncMmapFile::from(memory.freeze())),
2140                        AsyncMmapFileMutInner::Disk(disk) => Ok(AsyncMmapFile::from(disk.freeze_exec()?)),
2141                    }
2142                }
2143
2144                /// Returns whether remove the underlying file on drop.
2145                #[inline]
2146                pub fn get_remove_on_drop(&self) -> bool {
2147                    self.remove_on_drop
2148                }
2149
2150                /// Whether remove the underlying file on drop.
2151                /// Default is false.
2152                ///
2153                /// # Notes
2154                /// If invoke [`AsyncMmapFileMut::freeze`], then the file will
2155                /// not be removed even though the field `remove_on_drop` is true.
2156                ///
2157                /// [`AsyncMmapFileMut::freeze`]: structs.AsyncMmapFileMut.html#methods.freeze
2158                #[inline]
2159                pub fn set_remove_on_drop(&mut self, val: bool) {
2160                    self.remove_on_drop = val;
2161                }
2162
2163                /// Close the file. It would also truncate the file if max_sz >= 0.
2164                #[inline]
2165                pub async fn close(&mut self, max_sz: i64) -> Result<()> {
2166                    let empty = AsyncMmapFileMutInner::Empty(AsyncEmptyMmapFile::default());
2167                    // swap the inner to empty
2168                    let inner = mem::replace(&mut self.inner, empty);
2169                    match inner {
2170                        AsyncMmapFileMutInner::Disk(disk) => {
2171                            disk.flush()?;
2172                            if max_sz >= 0 {
2173                                disk.file.set_len(max_sz as u64).await.map_err(From::from)
2174                            } else {
2175                                Ok(())
2176                            }
2177                        },
2178                        _ => Ok(()),
2179                    }
2180                }
2181
2182                /// Remove the underlying file without dropping, leaving an [`AsyncEmptyMmapFile`].
2183                #[inline]
2184                pub async fn remove(&mut self) -> Result<()> {
2185                    let empty = AsyncMmapFileMutInner::Empty(AsyncEmptyMmapFile::default());
2186                    // swap the inner to empty
2187                    let inner = mem::replace(&mut self.inner, empty);
2188                    match inner {
2189                        AsyncMmapFileMutInner::Disk(disk) => {
2190                            let path = disk.path;
2191                            drop(disk.mmap);
2192                            disk.file
2193                                .set_len(0)
2194                                .await?;
2195                            drop(disk.file);
2196                            remove_file(path)
2197                                .await
2198                                .map_err(From::from)
2199                        },
2200                        _ => Ok(()),
2201                    }
2202                }
2203            }
2204
2205            impl_constructor_for_memory_mmap_file_mut!(AsyncMemoryMmapFileMut, AsyncMmapFileMut, "AsyncMmapFileMut", $path_str);
2206
2207            impl_drop!(AsyncMmapFileMut, AsyncMmapFileMutInner, AsyncEmptyMmapFile);
2208        };
2209    }
2210
2211    macro_rules! file_lock_tests {
2212        ($filename_prefix: literal, $runtime: meta) => {
2213            #[$runtime]
2214            async fn test_flush() {
2215                let path = concat!($filename_prefix, "_flush.txt");
2216                let mut file1 = AsyncMmapFileMut::create_with_options(path, AsyncOptions::new().max_size(100)).await.unwrap();
2217                file1.set_remove_on_drop(true);
2218                file1.write_all(vec![1; 100].as_slice(), 0).unwrap();
2219                file1.flush_range(0, 10).unwrap();
2220                file1.flush_async_range(11, 20).unwrap();
2221                file1.flush_async().unwrap();
2222            }
2223
2224            #[$runtime]
2225            async fn test_lock_shared() {
2226                let path = concat!($filename_prefix, "_lock_shared.txt");
2227                let file1 = AsyncMmapFileMut::open(path).await.unwrap();
2228                let file2 = AsyncMmapFileMut::open(path).await.unwrap();
2229                let file3 = AsyncMmapFileMut::open(path).await.unwrap();
2230                defer!(std::fs::remove_file(path).unwrap());
2231
2232                // Concurrent shared access is OK, but not shared and exclusive.
2233                file1.lock_shared().unwrap();
2234                file2.lock_shared().unwrap();
2235                assert!(file3.try_lock_exclusive().is_err());
2236                file1.unlock().unwrap();
2237                assert!(file3.try_lock_exclusive().is_err());
2238
2239                // Once all shared file locks are dropped, an exclusive lock may be created;
2240                file2.unlock().unwrap();
2241                file3.lock_exclusive().unwrap();
2242            }
2243        };
2244    }
2245}
2246
2247cfg_async_std!(
2248    pub(crate) mod async_std_impl;
2249);
2250
2251cfg_smol!(
2252    pub(crate) mod smol_impl;
2253);
2254
2255cfg_tokio!(
2256    pub(crate) mod tokio_impl;
2257);