1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! # Butcher
//!
//! An easy way to interact with `Cow`ed structs and enums.
//!
//! This crate provides the following functionalities for data wrapped in `Cow`:
//! - [destructuring/pattern matching over structs and enums](#destructuringpattern-matching),
//! - [iterating over collections, or any type that implements `IntoIterator`](#iteration),
//! - [flattening `Cow`](#flattening),
//! - [removing an indirection level `Cow`](#removing-an-indirection-level).
//!
//! ## Destructuring/pattern matching
//!
//! The `Butcher` trait can be used when it is necessary to destruture something
//! wrapped in a `Cow`. Below is a simple example:
//!
//! ```rust
//! use std::borrow::Cow;
//! use butcher::Butcher;
//!
//! #[derive(Butcher, Clone)]
//! struct MyNumberList {
//! val: u32,
//! next: Option<Box<MyNumberList>>,
//! }
//!
//! fn destructure_list_elem(i: Cow<MyNumberList>) -> (Cow<u32>, Cow<Option<Box<MyNumberList>>>) {
//! let ButcheredMyNumberList { val, next } = Butcher::butcher(i);
//!
//! (val, next)
//! }
//! ```
//!
//! This also allows pattern matching, as demonstrated in the following example:
//!
//! ```rust
//! 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 `Butcher` procedural macro can be derived for [structs][butcher-struct]
//! and for [enums][butcher-enum].
//!
//! [butcher-struct]: deriving_butcher_struct/index.html
//! [butcher-enum]: deriving_butcher_enum/index.html
//!
//! ## Iteration
//!
//! Here is a demonstration of how to iterate over an object wrapped in a `Cow`:
//!
//! ```rust
//! use std::borrow::Cow;
//! use butcher::iterator::{CowIter, IntoCowIterator};
//!
//! fn print_numbers(elems: Cow<[u32]>) {
//! let mut iter = elems.into_cow_iter();
//!
//! for element in iter {
//! // The type of element is Cow<u32>
//! println!("{:?}", element);
//! }
//! }
//! ```
//!
//! See the documentation of [`CowIter`] for more information.
//!
//! [`CowIter`]: iterator/enum.CowIter.html
//!
//! ## Flattening
//!
//! In some situations, the `Butcher` proc macro can generate tricky fields,
//! such as nested `Cow`. The [`FlattenCow`] trait aims to remove such
//! flattening.
//!
//! [`FlattenCow`]: flatten/trait.FlattenCow.html
//!
//! ## Removing an indirection level
//!
//! The [`AsDerefCow`] trait allows to transform a given `Cow<T>` into a
//! `Cow<<T as Deref>::Target>`. This can be usefull when it is needed to
//! transform a `Cow<String>` into `Cow<str>`.
//!
//! [`AsDerefCow`]: as_deref/trait.AsDerefCow.html
pub use *;
use Cow;