23 releases

0.1.16 Jun 7, 2025
0.1.15 Jun 2, 2025
0.1.14 May 28, 2025
0.1.9 Apr 9, 2025
0.1.6 Dec 31, 2024

#40 in WebAssembly

Download history 5229/week @ 2025-02-28 4186/week @ 2025-03-07 5415/week @ 2025-03-14 5828/week @ 2025-03-21 4917/week @ 2025-03-28 5422/week @ 2025-04-04 5964/week @ 2025-04-11 6733/week @ 2025-04-18 5992/week @ 2025-04-25 4847/week @ 2025-05-02 4883/week @ 2025-05-09 5529/week @ 2025-05-16 7322/week @ 2025-05-23 8179/week @ 2025-05-30 7838/week @ 2025-06-06 7331/week @ 2025-06-13

31,613 downloads per month
Used in 65 crates (19 directly)

MIT license

165KB
5K SLoC

sys_traits

Trait per function for system related functionality.

Write functions that specify only the system functions they need.

use sys_traits::FsWriteFile;
use sys_traits::SystemRandom;

pub fn write_random_data<TSys: FsWriteFile + SystemRandom>(
  sys: &TSys,
  file_path: &Path,
) -> std::io::Result<()> {
  let mut buf = [0u8; 16];
  sys.sys_random(&mut buf)?;
  sys.fs_write_file(file_path, buf)
}

Now a caller only needs to provide a type that implements those two functions.

#[sys_traits::auto_impl]

Use the #[sys_traits::auto_impl] macro to reduce boilerplate when wanting to automatically implement a trait for T when T implements the required traits.

This is useful for aliasing and reducing verbosity when using this crate.

+#[sys_traits::auto_impl]
pub trait WriteRandomDataSys: FsWriteFile + SystemRandom
{
}

-impl<T> DenoResolverSys for T where T: FsWriteFile + SystemRandom
-{
-}

Implementations

Comes with two implementations that implement all the traits.

Creating an implementation

To create an implementation you must implement the traits; however, some traits require implementing Base<TraitName> traits instead. For example, instead of implementing FsWrite, you must implement BaseFsWrite:

pub struct MyCustomFileSystem;

impl sys_traits::BaseFsWrite for MyCustomFileSystem {
  fn base_fs_write(&self, path: &Path, data: &[u8]) -> std::io::Result<()> {
    // ...
  }
}

The sys_traits::FsWrite trait gets automatically implemented for this as its definition is:

pub trait FsWrite: BaseFsWrite {
  #[inline]
  fn fs_write(
    &self,
    path: impl AsRef<Path>,
    data: impl AsRef<[u8]>,
  ) -> std::io::Result<()> {
    self.base_fs_write(path.as_ref(), data.as_ref())
  }
}

impl<T: BaseFsWrite> FsWrite for T {}

There's two reasons for this:

  1. You can't box traits with impl ....
  2. By design it limits code generation of multiple kinds of impl AsRef<Path> and impl AsRef<[u8]> to only being a single statement.

Dependencies

~0.2–9MB
~85K SLoC