Skip to content

Commit

Permalink
A beginning is a very delicate time
Browse files Browse the repository at this point in the history
  • Loading branch information
myrrlyn committed Sep 22, 2019
0 parents commit 9014b06
Show file tree
Hide file tree
Showing 17 changed files with 1,868 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
################################################################################
# Editor Configuration #
# #
# This file controls behavior in conformant editors with respect to some #
# common baseline settings. #
################################################################################

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[Justfile]
indent_size = 8
indent_style = tab

[*.md]
indent_size = 2
indent_style = space

[*.rs]
indent_size = 4
indent_style = tab

[*.toml]
indent_size = 8
indent_style = tab
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target
**/*.rs.bk
Cargo.lock
1 change: 1 addition & 0 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
myrrlyn <[email protected]>
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog <!-- omit in toc -->

All notable changes will be documented in this file.

This document is written according to the [Keep a Changelog][kac] style.
8 changes: 8 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Code of Conduct

This project is subject to the official [Rust code of conduct][coc].

As there are no dedicated fora for this project, this is only relevant in the
repository or in communication with me about it.

[coc]: https://www.rust-lang.org/policies/code-of-conduct
37 changes: 37 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Contributing Guide

Contributions are absolutely welcome!

## Contact Information

In order of likelihood that I will actionably receive your contact, my
information is:

- Email: [[email protected]](mailto:[email protected])
- GitHub: [@myrrlyn](//github.com/myrrlyn)
- Twitter: [@myrrlyn](//twitter.com/myrrlyn)
- Mastodon: [@myrrlyn@cybre.space](//cybre.space/myrrlyn)
- Reddit: [/u/myrrlyn](//reddit.com/u/myrrlyn)

I am not active on any IRC channels at this time. I am on Discord in the Rust
channel, so you may be able to reach me there, but I don’t know offhand how to
give out Discord profile links. I have a very consistent username scheme and so
anywhere you see my name, it’s *probably* me and I’ll *probably* respond to it.

## Preconditions

Be able to make a Rust project compile.

Be comfortable using `U+0009 CHARACTER TABULATION` as your indentation setting.

## Contributing

If you have a patch you think is worth inspecting right away, opening a pull
request without prelude is fine, although I would certainly appreciate an
accompanying explanation of what the patch does and why.

If you have questions, bugs, suggestions, or other contributions of any kind
that do not immediately touch the codebase, you can reach me informally to talk
about them or open an issue.

I will do my best to respond to all contacts in a timely manner.
32 changes: 32 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
################################################################################
# Project Manifest #
# #
# This file describes the Rust project to the Cargo build tool for operations. #
################################################################################

[package]
name = "wyz"
version = "0.1.0"
authors = [
"myrrlyn <[email protected]>",
]
edition = "2018"
categories = [
"no-std",
]
description = "myrrlyn’s utility collection"
documentation = "https://docs.rs/wyz"
homepage = "https://myrrlyn.net/crates/wyz"
keywords = [
]
license = "MIT"
readme = "README.md"
repository = "https://github.com/myrrlyn/wyz"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[features]
alloc = []
std = ["alloc"]
51 changes: 51 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
################################################################################
# Justfile #
# #
# Set of routines to execute for development work. #
################################################################################

# Run the benchmarks. Currently, this requires the nightly compiler series.
bench:
cargo +nightly bench

# Build the project, after checking that it is valid.
build: check
cargo build

# Runs the checker and linter.
check:
cargo check
cargo clippy

# Destroys build artifacts.
clean:
cargo clean

# Documents the project, after checking that it is valid.
doc: check
cargo doc --document-private-items

# Runs a Justfile recipe on every change to the workspace.
loop action:
cargo watch -s "just {{action}}"

# Runs the project under the Miri interpreter. This is currently nightly-only.
miri:
cargo +nightly miri test

# Prepares the project for package deployment.
#
# This allows uncommitted VCS files, as a convenience for development.
package: test doc
cargo package --allow-dirty

# Publishes the project to crates.io.
#
# This repackages the project and fails on a dirty VCS checkout.
publish: test doc
cargo package # no --allow-dirty this time
cargo publish

# Runs the test suite.
test: build
cargo test
21 changes: 21 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) {{current_year}} myrrlyn (Alexander Payne)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
175 changes: 175 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<div align="center">

# `wyz` <!-- omit in toc -->

[![Crate][crate_img]][crate]
[![Documentation][docs_img]][docs]
[![License][license_img]][license_file]

[![Continuous Integration][travis_img]][travis]
[![Code Coverage][codecov_img]][codecov]
[![Crate Downloads][downloads_img]][crate]
[![Crate Size][loc_img]][loc]

</div>

I have developed a collection of utility and convenience Rust modules that are
useful to me, and may be useful to you also.

This crate is a collection of largely-independent small modules. I do not
currently offer features to disable modules independently of each other, but
their compilation cost is small enough to essentially not matter.

## Modules <!-- omit in toc -->

1. [`conv`](#conv)
1. [`exit`](#exit)
1. [`pipe`](#pipe)
1. [`pretty`](#pretty)
1. [`tap`](#tap)

## `conv`

This module provides a single trait, of the same name, with a single generic
method, also of the same name. This trait is a sibling to `Into`, but rather
than placing its type parameter in the trait (`Into::<T>::into`), `Conv` places
it in the method: `Conv::conv::<T>`.

By placing the type parameter in the method name, `.conv` can be called in
suffix position in expressions where the result type cannot be inferred and must
be explicitly stated.

```rust
use wyz::conv::Conv;

let digits = 0xabcd.conv::<String>().len();
```

This is a trivial example, but writing a code context where `.conv` makes sense
takes a lot more context than a `README` wants.

## `exit`

This is a macro that calls `std::process::exit`. It can return a status code,
and also print a message to `stderr`.

```rust
use wyz::exit::exit;

exit();
exit!(2);
exit!(3, "This is a {} message", "failure");
```

The default call is `exit(1)`; a call may provide an exit code and, in addition,
a set of arguments to pass directly to `eprintln!`. The error message is not
guaranteed to be emitted, as `stderr` may be closed at time of `exit!`.

## `pipe`

Rust does not permit universal suffix-position function call syntax. That is,
you can *always* call a function with `Scope::name(arguments…)`, but only *some*
functions can be called as `first_arg.name(other_args…)`. Working in “data
pipelines” – flows where the return value of one function is passed directly as
the first argument to the next – is common enough in our field that it has a
name in languages that support it: *method chaining*. A *method* is a function
that the language considers to be treated specially in regards to only its
first argument, and permits changing the abstract token series
`function arg1 args…` into the series `arg1 function args…`.

Rust restricts that order transformation to only functions defined in scope for
some type (either `impl Type` or `impl Trait for Type` blocks) and that take a
first argument named `self`.

Other languages permit calling *any* function, regardless of its definition site
in source code, in this manner, as long as the first argument is of the correct
type for the first parameter of the function.

In languages like F♯ and Elixir, this uses the call operator `|>` rather than
the C++ family’s `.` caller. This operator is pronounced `pipe`.

Rust does not have a pipe operator. The dot-caller is restricted to only the
implementation blocks listed above, and this is not likely to change because it
also performs limited type transformation operations in order to find a name
that fits.

This module provides a `Pipe` trait whose method, `pipe`, passes its `self`
first argument as the argument to its second-order function:

```rust
use wyz::pipe::Pipe;

let final = 5
.pipe(|a| a + 10)
.pipe(|a| a * 2);

assert_eq!(final, 30);
```

Without language-level syntax support, piping into closures always requires
restating the argument, and functions cannot curry the argument they receive
from `pipe` and arguments from the environment in the manner that dot-called
methods can.

```rust
fn fma(a: i32, b: i32, c: i32) -> i32 {
(a * b) + c
}
5.pipe(|a| fma(a, 2, 3));

let fma_2_3 = |a| fma(a, 2, 3);
5.pipe(fma_2_3);
```

These are the only ways to express `5 |> fma(2, 3)`.

Sorry.

Bug the language team.

## `pretty`

This is a wrapper type that implements `Debug` by printing the `Display`
implementation of the wrapped type. Useful for when you want the `Display`
implementation to get called by a `Debug` hook.

## `tap`

Tapping is a cousin operation to piping, except that rather than pass the
receiver by *value* into some function, and return the result of that function,
it passes a *borrow* of a value into a function, and then returns the original
value.

It is useful for inserting an operation into an expression without changing the
overall state (type or value) of the expression.

```rust
use wyz::tap::Tap;

let result = complex_value()
.tap(|v| log::info!("First stage: {}", v))
.transform(other, args)
.tap(|v| lo::info!("Second stage: {}", v));
```

The tap calls have no effect on the expression into which they are placed,
except to induce side effects somewhere else in the system. Commenting out the
two `.tap` calls does not change anything about `complex_value()`, `.transform`,
or `result`; it only removes the log statements.

This enables easily inserting or removing inspection points in an expression
without otherwise altering it.

[codecov]: https://codecov.io/gh/myrrlyn/wyz "Code Coverage"
[codecov_img]: https://img.shields.io/codecov/c/github/myrrlyn/wyz.svg?logo=codecov "Code Coverage Display"
[crate]: https://crates.io/crates/wyz "Crate Link"
[crate_img]: https://img.shields.io/crates/v/wyz.svg?logo=rust "Crate Page"
[docs]: https://docs.rs/wyz "Documentation"
[docs_img]: https://docs.rs/wyz/badge.svg "Documentation Display"
[downloads_img]: https://img.shields.io/crates/dv/wyz.svg?logo=rust "Crate Downloads"
[license_file]: https://github.com/myrrlyn/wyz/blob/master/LICENSE.txt "License File"
[license_img]: https://img.shields.io/crates/l/wyz.svg "License Display"
[loc]: https://github.com/myrrlyn/wyz "Repository"
[loc_img]: https://tokei.rs/b1/github/myrrlyn/wyz?category=code "Repository Size"
[travis]: https://travis-ci.org/myrrlyn/wyz "Travis CI"
[travis_img]: https://img.shields.io/travis/myrrlyn/wyz.svg?logo=travis "Travis CI Display"
1 change: 1 addition & 0 deletions rust-toolchain
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
stable
Loading

0 comments on commit 9014b06

Please sign in to comment.