Crates.io | butcher |
lib.rs | butcher |
version | 0.5.0 |
source | src |
created_at | 2020-06-09 13:15:15.204604 |
updated_at | 2020-08-03 16:31:11.099176 |
description | An easy way to interact with structs and enums wrapped in Cows |
homepage | |
repository | https://github.com/scileo/butcher |
max_upload_size | |
id | 251888 |
size | 36,003 |
An easy way to interact with structs and enums wrapped in Cow
.
The standard library has a clone on write type, which allows to work with data with either owned or borrowed data, without any distinction. However, this can lead to a lot of code duplication in some situations.
This crate currently provide the following functionalities:
Cow
,Cow
,Cow
,Cow
flattening,Cow
unnesting.The Butcher
trait can be derived on structs and enums. Destructuring is then
made easy:
use std::borrow::Cow;
use butcher::Butcher;
#[derive(Butcher, Clone)]
struct MyNumberList {
val: u32,
next: Option<Box<MyNumberList>>,
}
fn get_elem(i: Cow<MyNumberList>) -> Cow<u32> {
let ButcheredMyNumberList { val, .. } = Butcher::butcher(i);
val
}
The Butcher
trait can also be derived on enums. This allows, for example:
use butcher::Butcher;
use std::borrow::Cow;
#[derive(Butcher, Clone)]
enum WebEvent {
PageLoad,
KeyPress(char),
Paste(String),
// or c-like structures.
Click { x: i64, y: i64 },
}
fn print_action(i: Cow<WebEvent>) {
match WebEvent::butcher(i) {
ButcheredWebEvent::PageLoad => { /* ... */ },
ButcheredWebEvent::KeyPress(key) => { /* ... */ },
ButcheredWebEvent::Paste(pasted) => { /* ... */ },
ButcheredWebEvent::Click { x, y } => { /* ... */ },
}
}
The fields in each variant will be Cow<T>
by default. This can be configured.
See the documentation for more information.
This crate provide a CowIter
type, which allows to write Cow
fiendly
iterators. See this example:
use std::borrow::Cow;
use butcher::iterator::CowIter;
fn print_numbers(elems: Cow<[u32]>) {
let mut iter = CowIter::from(elems);
for element in iter {
// The type of element is Cow<u32>
println!("{:?}", element);
}
}
Thanks to the Deref
trait, it is possible to flatten
a Cow<T>
to
Cow<<T as Deref>::Target>
. For instance, it is possible to create a Cow<str>
from a Cow<String>
, a Cow<[T]>
from a Cow<Vec<T>>
, and so on.
Thanks to how Deref
is defined, the target type is always infered by the
type inference system, which is very convenient.
use std::borrow::Cow;
use butcher::flatten::FlattenCow;
let some_cow: Cow<String> = Cow::Owned(String::from("Hello 🦀"));
let flattened_cow: Cow<str> = some_cow.flatten();
The Unnest
trait allows to simply remove nested usage of cow. It provides the
unnest
method, which transforms a Cow<Cow<T>>
into Cow<T>
.
use std::borrow::Cow;
use butcher::unnest::UnnestCow;
let foo: Cow<Cow<usize>> = Cow::Owned(Cow::Owned(42usize));
let foo_unnested: Cow<usize> = foo.unnest();
This crate compiles in rust 1.42 and older. Upgrading MSRV is a breaking change. CI is set up so that it guarantees that the crate compiles and tests pass on both 1.42 and stable rust.