impl<T> Deref for Scope<T> { type Target = T; fn deref(&self) -> &T { &self.data }} impl<T> Deref for File<T> { type Target = T; fn deref(&self) -> &T { &self.scope }} /// A handle to a directory which will live at most `'dir`, accessing data that will live for at/// least `'data`.////// Dropping a ScopedDir will not delete or clean it up, this is expected to occur through dropping/// the `Scope` that created it.pub struct ScopedDir<'data, 'dir> { #[cfg(CONFIG_DEBUG_FS)] entry: ManuallyDrop<Entry<'dir>>, _phantom: PhantomData<fn(&'data ()) -> &'dir ()>,} impl<'data, 'dir> ScopedDir<'data, 'dir> { /// Creates a subdirectory inside this `ScopedDir`. /// /// The returned directory handle cannot outlive this one. pub fn dir<'dir2>(&'dir2 self, name: &CStr) -> ScopedDir<'data, 'dir2> { #[cfg(not(CONFIG_DEBUG_FS))] let _ = name; ScopedDir { #[cfg(CONFIG_DEBUG_FS)] entry: ManuallyDrop::new(Entry::dir(name, Some(&*self.entry))), _phantom: PhantomData, } } fn create_file<T: Sync>(&self, name: &CStr, data: &'data T, vtable: &'static FileOps<T>) { #[cfg(CONFIG_DEBUG_FS)] core::mem::forget(Entry::file(name, &self.entry, data, vtable)); } /// Creates a read-only file in this directory. /// /// The file's contents are produced by invoking [`Writer::write`]. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn read_only_file<T: Writer + Send + Sync + 'static>(&self, name: &CStr, data: &'data T) { self.create_file(name, data, &T::FILE_OPS) } /// Creates a read-only binary file in this directory. /// /// The file's contents are produced by invoking [`BinaryWriter::write_to_slice`]. /// /// This function does not produce an owning handle to the file. The created file is removed /// when the [`Scope`] that this directory belongs to is dropped. pub fn read_binary_file<T: BinaryWriter + Send + Sync + 'static>( &self, name: &CStr, data: &'data T, ) { self.create_file(name, data, &T::FILE_OPS) } /// Creates a read-only file in this directory, with contents from a callback. /// /// The file contents are generated by calling `f` with `data`. /// /// /// `f` must be a function item or a non-capturing closure. /// This is statically asserted and not a safety requirement. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn read_callback_file<T, F>(&self, name: &CStr, data: &'data T, _f: &'static F) where T: Send + Sync + 'static, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync, { let vtable = <FormatAdapter<T, F> as ReadFile<_>>::FILE_OPS.adapt(); self.create_file(name, data, vtable) } /// Creates a read-write file in this directory. /// /// Reading the file uses the [`Writer`] implementation on `data`. Writing to the file uses /// the [`Reader`] implementation on `data`. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn read_write_file<T: Writer + Reader + Send + Sync + 'static>( &self, name: &CStr, data: &'data T, ) { let vtable = &<T as ReadWriteFile<_>>::FILE_OPS; self.create_file(name, data, vtable) } /// Creates a read-write binary file in this directory. /// /// Reading the file uses the [`BinaryWriter`] implementation on `data`. Writing to the file /// uses the [`BinaryReader`] implementation on `data`. /// /// This function does not produce an owning handle to the file. The created file is removed /// when the [`Scope`] that this directory belongs to is dropped. pub fn read_write_binary_file<T: BinaryWriter + BinaryReader + Send + Sync + 'static>( &self, name: &CStr, data: &'data T, ) { let vtable = &<T as BinaryReadWriteFile<_>>::FILE_OPS; self.create_file(name, data, vtable) } /// Creates a read-write file in this directory, with logic from callbacks. /// /// Reading from the file is handled by `f`. Writing to the file is handled by `w`. /// /// `f` and `w` must be function items or non-capturing closures. /// This is statically asserted and not a safety requirement. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn read_write_callback_file<T, F, W>( &self, name: &CStr, data: &'data T, _f: &'static F, _w: &'static W, ) where T: Send + Sync + 'static, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync, W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync, { let vtable = <WritableAdapter<FormatAdapter<T, F>, W> as ReadWriteFile<_>>::FILE_OPS .adapt() .adapt(); self.create_file(name, data, vtable) } /// Creates a write-only file in this directory. /// /// Writing to the file uses the [`Reader`] implementation on `data`. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn write_only_file<T: Reader + Send + Sync + 'static>(&self, name: &CStr, data: &'data T) { let vtable = &<T as WriteFile<_>>::FILE_OPS; self.create_file(name, data, vtable) } /// Creates a write-only binary file in this directory. /// /// Writing to the file uses the [`BinaryReader`] implementation on `data`. /// /// This function does not produce an owning handle to the file. The created file is removed /// when the [`Scope`] that this directory belongs to is dropped. pub fn write_binary_file<T: BinaryReader + Send + Sync + 'static>( &self, name: &CStr, data: &'data T, ) { self.create_file(name, data, &T::FILE_OPS) } /// Creates a write-only file in this directory, with write logic from a callback. /// /// Writing to the file is handled by `w`. /// /// `w` must be a function item or a non-capturing closure. /// This is statically asserted and not a safety requirement. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn write_only_callback_file<T, W>(&self, name: &CStr, data: &'data T, _w: &'static W) where T: Send + Sync + 'static, W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync, { let vtable = &<WritableAdapter<NoWriter<T>, W> as WriteFile<_>>::FILE_OPS .adapt() .adapt(); self.create_file(name, data, vtable) } fn empty() -> Self { ScopedDir { #[cfg(CONFIG_DEBUG_FS)] entry: ManuallyDrop::new(Entry::empty()), _phantom: PhantomData, } } #[cfg(CONFIG_DEBUG_FS)] fn into_entry(self) -> Entry<'dir> { ManuallyDrop::into_inner(self.entry) } #[cfg(not(CONFIG_DEBUG_FS))] fn into_entry(self) {}} impl<'data> ScopedDir<'data, 'static> { // This is safe, but intentionally not exported due to footgun status. A ScopedDir with no // parent will never be released by default, and needs to have its entry extracted and used // somewhere. fn new(name: &CStr) -> ScopedDir<'data, 'static> { ScopedDir { #[cfg(CONFIG_DEBUG_FS)] entry: ManuallyDrop::new(Entry::dir(name, None)), _phantom: PhantomData, } }}Lines 501–724 of 724. Previous lines
impl<T> Deref for Scope<T> { type Target = T; fn deref(&self) -> &T { &self.data } } impl<T> Deref for File<T> { type Target = T; fn deref(&self) -> &T { &self.scope } } /// A handle to a directory which will live at most `'dir`, accessing data that will live for at /// least `'data`. /// /// Dropping a ScopedDir will not delete or clean it up, this is expected to occur through dropping /// the `Scope` that created it. pub struct ScopedDir<'data, 'dir> { #[cfg(CONFIG_DEBUG_FS)] entry: ManuallyDrop<Entry<'dir>>, _phantom: PhantomData<fn(&'data ()) -> &'dir ()>, } impl<'data, 'dir> ScopedDir<'data, 'dir> { /// Creates a subdirectory inside this `ScopedDir`. /// /// The returned directory handle cannot outlive this one. pub fn dir<'dir2>(&'dir2 self, name: &CStr) -> ScopedDir<'data, 'dir2> { #[cfg(not(CONFIG_DEBUG_FS))] let _ = name; ScopedDir { #[cfg(CONFIG_DEBUG_FS)] entry: ManuallyDrop::new(Entry::dir(name, Some(&*self.entry))), _phantom: PhantomData, } } fn create_file<T: Sync>(&self, name: &CStr, data: &'data T, vtable: &'static FileOps<T>) { #[cfg(CONFIG_DEBUG_FS)] core::mem::forget(Entry::file(name, &self.entry, data, vtable)); } /// Creates a read-only file in this directory. /// /// The file's contents are produced by invoking [`Writer::write`]. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn read_only_file<T: Writer + Send + Sync + 'static>(&self, name: &CStr, data: &'data T) { self.create_file(name, data, &T::FILE_OPS) } /// Creates a read-only binary file in this directory. /// /// The file's contents are produced by invoking [`BinaryWriter::write_to_slice`]. /// /// This function does not produce an owning handle to the file. The created file is removed /// when the [`Scope`] that this directory belongs to is dropped. pub fn read_binary_file<T: BinaryWriter + Send + Sync + 'static>( &self, name: &CStr, data: &'data T, ) { self.create_file(name, data, &T::FILE_OPS) } /// Creates a read-only file in this directory, with contents from a callback. /// /// The file contents are generated by calling `f` with `data`. /// /// /// `f` must be a function item or a non-capturing closure. /// This is statically asserted and not a safety requirement. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn read_callback_file<T, F>(&self, name: &CStr, data: &'data T, _f: &'static F) where T: Send + Sync + 'static, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync, { let vtable = <FormatAdapter<T, F> as ReadFile<_>>::FILE_OPS.adapt(); self.create_file(name, data, vtable) } /// Creates a read-write file in this directory. /// /// Reading the file uses the [`Writer`] implementation on `data`. Writing to the file uses /// the [`Reader`] implementation on `data`. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn read_write_file<T: Writer + Reader + Send + Sync + 'static>( &self, name: &CStr, data: &'data T, ) { let vtable = &<T as ReadWriteFile<_>>::FILE_OPS; self.create_file(name, data, vtable) } /// Creates a read-write binary file in this directory. /// /// Reading the file uses the [`BinaryWriter`] implementation on `data`. Writing to the file /// uses the [`BinaryReader`] implementation on `data`. /// /// This function does not produce an owning handle to the file. The created file is removed /// when the [`Scope`] that this directory belongs to is dropped. pub fn read_write_binary_file<T: BinaryWriter + BinaryReader + Send + Sync + 'static>( &self, name: &CStr, data: &'data T, ) { let vtable = &<T as BinaryReadWriteFile<_>>::FILE_OPS; self.create_file(name, data, vtable) } /// Creates a read-write file in this directory, with logic from callbacks. /// /// Reading from the file is handled by `f`. Writing to the file is handled by `w`. /// /// `f` and `w` must be function items or non-capturing closures. /// This is statically asserted and not a safety requirement. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn read_write_callback_file<T, F, W>( &self, name: &CStr, data: &'data T, _f: &'static F, _w: &'static W, ) where T: Send + Sync + 'static, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync, W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync, { let vtable = <WritableAdapter<FormatAdapter<T, F>, W> as ReadWriteFile<_>>::FILE_OPS .adapt() .adapt(); self.create_file(name, data, vtable) } /// Creates a write-only file in this directory. /// /// Writing to the file uses the [`Reader`] implementation on `data`. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn write_only_file<T: Reader + Send + Sync + 'static>(&self, name: &CStr, data: &'data T) { let vtable = &<T as WriteFile<_>>::FILE_OPS; self.create_file(name, data, vtable) } /// Creates a write-only binary file in this directory. /// /// Writing to the file uses the [`BinaryReader`] implementation on `data`. /// /// This function does not produce an owning handle to the file. The created file is removed /// when the [`Scope`] that this directory belongs to is dropped. pub fn write_binary_file<T: BinaryReader + Send + Sync + 'static>( &self, name: &CStr, data: &'data T, ) { self.create_file(name, data, &T::FILE_OPS) } /// Creates a write-only file in this directory, with write logic from a callback. /// /// Writing to the file is handled by `w`. /// /// `w` must be a function item or a non-capturing closure. /// This is statically asserted and not a safety requirement. /// /// This function does not produce an owning handle to the file. The created /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn write_only_callback_file<T, W>(&self, name: &CStr, data: &'data T, _w: &'static W) where T: Send + Sync + 'static, W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync, { let vtable = &<WritableAdapter<NoWriter<T>, W> as WriteFile<_>>::FILE_OPS .adapt() .adapt(); self.create_file(name, data, vtable) } fn empty() -> Self { ScopedDir { #[cfg(CONFIG_DEBUG_FS)] entry: ManuallyDrop::new(Entry::empty()), _phantom: PhantomData, } } #[cfg(CONFIG_DEBUG_FS)] fn into_entry(self) -> Entry<'dir> { ManuallyDrop::into_inner(self.entry) } #[cfg(not(CONFIG_DEBUG_FS))] fn into_entry(self) {} } impl<'data> ScopedDir<'data, 'static> { // This is safe, but intentionally not exported due to footgun status. A ScopedDir with no // parent will never be released by default, and needs to have its entry extracted and used // somewhere. fn new(name: &CStr) -> ScopedDir<'data, 'static> { ScopedDir { #[cfg(CONFIG_DEBUG_FS)] entry: ManuallyDrop::new(Entry::dir(name, None)), _phantom: PhantomData, } } }