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
//! # plod, deriving plain old data
//!
//! Plod is an easy to use plain old data reader and writer.
//! It transforms them from and to natural rust types.
//!
//! Plain old are were commonly designed to be used in C, but in rust we can have more meaningful
//! datastructures for the same representation. For example, in C unions with a separate tag are
//! the only way to represent the thing called enum that we have for grated in rust.
//!
//! Since it uses the standard `Read` and `Write` traits, Plod can be used to read and write
//! binary files as well as network protocols as long as you have a reader or a writer.
//!
//! Here is an example with a struct and an enum:
//! ```
//! use plod::Plod;
//!
//! #[derive(Plod)]
//! struct Value {
//! kind: u16,
//! value: u32,
//! }
//!
//! #[derive(Plod)]
//! #[plod(tag_type(u8))]
//! enum ValueStore{
//! #[plod(tag=1)]
//! Series {
//! kind: u16,
//! #[plod(size_type(u16))]
//! values: Vec<u32> },
//! #[plod(tag=2,size_type(u16))]
//! Keys(Vec<Value>),
//! }
//! ```
//!
//! More documentation about `#[plod]` attributes at [`Plod`](macro@Plod)
//!
//! # Why use plod ?
//!
//! Plod transforms a serialized plain old data into a ready to use plain Rust data-structure.
//! It uses attributes to achieve that.
//! This means that an enum or a vec can easily be read from a binary file.
//!
//! Other reasons:
//! * Plod is based on generic `Read`and `Write` traits.
//! * Plod knows about endianness during serialization, it reorders bytes for you.
//! * Plod doesn't use unsafe or transmute for read and write
//! * Plod doesn't need you to play with `#[repr()]`
//!
//! Plod is for *plain old data*, which means that is well suited for known, existing, binary formats.
//! *But*:
//! - If you want a way to serialize your own data and be able to read it later, you should
//! prefer serde which can serialize any data into many more formats that can be self describing.
//!
//! - If your file format is not binary and not easily supported by serde, you may look at nom for parsing it.
//!
//! - If your data only contains primary types and all you want is speed you may take a look at plain, pod and nue.
//!
//! # Special cases
//!
//! Plod use the obvious representation for struct as C does. However some data structure are not so obvious.
//! - enum are represented with a specific tag at the start, each variant can have its own size
//! - Vec are represented with their size at the start (either in bytes or in item count)
//! - Option are not stored, they are read as `None`, the idea is that you can read a structure and
//! then add some more high level information to it by replacing Options with anything.
//!
//! Document endianness and it inheritance
//!
//! How to call Plod trait methods
//!
//! Example, tutorial, first use
//!
use ;
/// plod results Result uses io errors
pub type Result<T> = Result;
/// The main thing
pub use Plod;
/// The main plain old data trait
/// It is usually implemented using `#[derive(Plod)]`, but it can also be implemented manually to
/// handle specific cases.
/// The endianness is implied by implementation and not a generic type because it makes calling and writing
/// the trait much easier and because I never found a data format that is both big and little
/// endian (counter example anyone ?).
// everything in this library is public and is tested via integration tests