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
//! What a writer derives from an item's bytes before handing them to the
//! store: its `link_id`, its `meta` summary and its `sort_key` (spec
//! Annex A).
//!
//! The store never parses `meta` (spec §13) and this module does not
//! change that: it is a library the writer calls before the bytes reach
//! the store, the way [`hash`](crate::hash) is one for naming them. What
//! it removes is the agreement two writers of one collection had to keep
//! by hand. Annex A is informative, so nothing enforces it, and
//! consumers implementing it separately diverge: one writes a whole
//! calendar summary and a resolved key, another an empty key for every
//! item, and the first then reads the second's calendar with no row to
//! render and no ordering.
//!
//! The fallback ids are fixed here for the same reason, and it is the
//! sharper one: two writers disagreeing about the id of a message with
//! no `Message-ID` link it twice and store one body twice, the
//! object-hash bug on the identity axis.
//!
//! Each kind is read by a small scanner rather than by a parser. A body
//! crosses this crate byte for byte, and the fields a summary holds are
//! a shallow read of a handful of properties. The `no_std` core is also
//! why: the parsers a frontend renders with (vcard-rs, ical-rs,
//! mail-parser) belong where the rendering happens.
use String;
use ;
/// Everything a writer derives from one item's bytes.
///
/// Kept together because all three come from one read and are written
/// together: a mutation refreshing the body without the key leaves the
/// item sorted where its old start put it.
/// Derives from a body of the given kind, or `None` when this crate has no
/// conventions for that media type.
///
/// The kind is the collection's declared `kind` (spec §14), matched on
/// the bare media type: `text/vcard; charset=utf-8` reads as
/// `text/vcard`.
/// The FNV-1a 64 digest of a body, as the sixteen lowercase hexadecimal
/// digits a fallback id carries.
///
/// A fallback needs to be stable across writers and cheap, not
/// collision-resistant: the body it names is stored under the store's own
/// hash (spec §5) either way, and this only has to keep two writers from
/// linking one item twice.
/// Unfolds a folded body into its logical lines (RFC 5322 §2.2.3, RFC
/// 5545 §3.1, RFC 6350 §3.2): a line beginning with a space or a tab
/// continues the one before it.
///
/// Invalid UTF-8 is replaced rather than refused: a summary carrying a
/// replacement character beats no summary at all, and the body itself is
/// stored untouched either way.