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
/*
* SPDX-FileCopyrightText: 2023 Inria
* SPDX-FileCopyrightText: 2023 Sebastiano Vigna
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
*/
//! Traits computing information about a type.
use cratepad_align_to;
use Hash;
use ZeroCopy;
/// Recursively compute a type hash for a type.
///
/// [`type_hash`](TypeHash::type_hash) is a recursive function that computes
/// information about a type. It is used to check that the type of the data
/// being deserialized matches syntactically the type of the data that was
/// written.
///
/// The type hasher should store information about the name and the type of the
/// fields of a type, and the name of the type itself.
///
/// When serializing an instance of type `T`,
/// [`SerType<T>`](crate::ser::SerInner::SerType) must implement this trait.
///
/// Additionally, it is recommended that commonly used types implement this
/// trait, even if their serialization type is different, because it makes it
/// possible to use [`PhantomData`](core::marker::PhantomData) and
/// [`PhantomDeserData`](crate::PhantomDeserData).
/// Recursively compute an alignment hash for a zero-copy type.
///
/// [`align_hash`](AlignHash::align_hash) is a recursive function that computes
/// alignment information about zero-copy types. It is used to check that the
/// alignment (and thus padding) of data that is zero-copied matches the
/// alignment at serialization time.
///
/// More precisely, at each call a zero-copy type looks at `offset_of`, assuming
/// that the type is stored at that offset in the structure, hashes in the
/// padding necessary to make `offset_of` a multiple of [`core::mem::align_of`]
/// the type, hashes in the type size, and finally increases `offset_of` by
/// [`core::mem::size_of`] the type.
///
/// All deep-copy types must implement [`AlignHash`] as a no-op.
///
/// When serializing an instance of type `T`,
/// [`SerType<T>`](crate::ser::SerInner::SerType) must implement this trait.
/// Thus, if `T` different from its serialization type it is not necessary to
/// implement this trait for `T`. For example, [`String`] does not need to
/// implement this trait, because its serialization type is `Box<str>`,
/// which indeed implements this trait.
/// A function providing a reasonable default
/// implementation of [`AlignHash::align_hash`] for basic sized types.
pub
/// A trait providing the desired alignment of zero-copy types in serialized
/// data.
///
/// We use the value returned by [`AlignTo::align_to`] to generate padding
/// before storing a zero-copy type. Note that this is different from the
/// padding used to align the same type inside a struct, which is not under our
/// control and is given by [`core::mem::align_of`].
///
/// The alignment returned by this function is computed by maximizing the
/// alignment required by the type itself (i.e., [`core::mem::align_of`]) and
/// the [`AlignTo::align_to`] of its fields; moreover, [`AlignTo::align_to`] of
/// primitive types is defined using the size, rather than the value returned by
/// [`core::mem::align_of`]. In this way we increase interoperability between
/// architectures with different alignment requirements for the same types
/// (e.g., 4 or 8 bytes for `u64`).
///
/// By maximizing with [`core::mem::align_of`] we ensure that we provide
/// sufficient alignment in case the attribute `repr(align(N))` was specified.
///
/// Deep-copy types do not need to implement [`AlignTo`].