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
const FNV_OFFSET_BASIS: u64 = 0xcbf29ce484222325;
const FNV_PRIME: u64 = 0x100000001b3;
const
/// The span label for a generator identified by a name.
///
/// A label is an opaque value identifying a generator to the engine, which
/// treats two spans with the same label as coming from the same generator
/// (see [`Generator::label`](super::Generator::label)). This derives one
/// from a name — the 64-bit FNV-1a hash of its UTF-8 bytes, the same
/// function libhegel exports as `hegel_label_from_name` — so it can be
/// computed at compile time:
///
/// ```
/// use hegel::generators as gs;
///
/// const PAIRS_LABEL: u64 = gs::label_from_name("mycrate.pairs");
/// ```
///
/// A name only has to be stable and unique to its generator; prefixing it
/// with the crate's name keeps it clear of Hegel's own `hegel.<kind>` names.
pub const
/// The span label for a generator built from other generators.
///
/// Combines the given labels, in order, into one — the same function
/// libhegel exports as `hegel_label_combine`. Pass the generator's own label
/// (from [`label_from_name`]) first and its components' labels after it, so
/// that a pair of integers and a pair of strings get different labels while
/// every pair of integers gets the same one. Combine once, when the
/// generator is built, and keep the result: `label` is asked for on every
/// draw.
///
/// ```
/// use hegel::generators::{self as gs, Generator};
///
/// const PAIRS_LABEL: u64 = gs::label_from_name("mycrate.pairs");
///
/// struct Pairs<G> {
/// inner: G,
/// label: u64,
/// }
///
/// fn pairs<T, G: Generator<T>>(inner: G) -> Pairs<G> {
/// let label = gs::combine_labels(&[PAIRS_LABEL, inner.label()]);
/// Pairs { inner, label }
/// }
///
/// impl<T, G: Generator<T>> Generator<(T, T)> for Pairs<G> {
/// fn label(&self) -> u64 {
/// self.label
/// }
///
/// fn do_draw(&self, tc: &hegel::TestCase) -> (T, T) {
/// (tc.draw_silent(&self.inner), tc.draw_silent(&self.inner))
/// }
/// }
/// ```
///
/// Combining is order-sensitive, and combining a single label does not
/// return it unchanged.
pub const