sys_traits 0.1.7

Trait per function for system related functionality.
Documentation
# `sys_traits`

Trait per function for system related functionality.

Write functions that specify only the system functions they need.

```rs
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.

## Implementations

Comes with two implementations that implement all the traits.

- `sys_traits::impl::RealSys` - A real implementation of the current system.
  - Automatically works with Wasm in Deno
  - Will implement Node.js support once I need it
    (https://github.com/dsherret/sys_traits/issues/4)
- `sys_traits::impl::InMemorySys` - An in-memory system useful for testing.

## 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`:

```rs
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:

```rs
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.