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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! DAG-CBOR serialization and deserialization.
//!
//! # Usage
//!
//! Add this to your `Cargo.toml`:
//! ```toml
//! [dependencies]
//! serde_ipld_dagcbor = "0.1.0"
//! ```
//!
//! Storing and loading Rust types is easy and requires only
//! minimal modifications to the program code.
//!
//! ```rust
//! # #[cfg(not(feature = "std"))]
//! # fn main() {}
//! use serde_derive::{Deserialize, Serialize};
//! use std::error::Error;
//! use std::fs::File;
//! use std::io::BufReader;
//!
//! // Types annotated with `Serialize` can be stored as CBOR.
//! // To be able to load them again add `Deserialize`.
//! #[derive(Debug, Serialize, Deserialize)]
//! struct Mascot {
//!     name: String,
//!     species: String,
//!     year_of_birth: u32,
//! }
//!
//! # #[cfg(feature = "std")]
//! fn main() -> Result<(), Box<dyn Error>> {
//!     let ferris = Mascot {
//!         name: "Ferris".to_owned(),
//!         species: "crab".to_owned(),
//!         year_of_birth: 2015,
//!     };
//!
//!     let ferris_file = File::create("examples/ferris.cbor")?;
//!     // Write Ferris to the given file.
//!     // Instead of a file you can use any type that implements `io::Write`
//!     // like a HTTP body, database connection etc.
//!     serde_ipld_dagcbor::to_writer(ferris_file, &ferris)?;
//!
//!     let tux_file = File::open("examples/tux.cbor")?;
//!     let tux_reader = BufReader::new(tux_file);
//!     // Load Tux from a file.
//!     // Serde CBOR performs roundtrip serialization meaning that
//!     // the data will not change in any way.
//!     let tux: Mascot = serde_ipld_dagcbor::from_reader(tux_reader)?;
//!
//!     println!("{:?}", tux);
//!     // prints: Mascot { name: "Tux", species: "penguin", year_of_birth: 1996 }
//!
//!     Ok(())
//! }
//! ```
//!
//! There are a lot of options available to customize the format.
//! To operate on untyped DAG-CBOR values have a look at the [`libipld_core::ipld::Ipld`] type.
//!
//! # Type-based Serialization and Deserialization
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from CBOR via the serialization API. To be able to serialize a piece of data, it must implement
//! the `serde::Serialize` trait. To be able to deserialize a piece of data, it must implement the
//! `serde::Deserialize` trait. Serde provides an annotation to automatically generate the
//! code for these traits: `#[derive(Serialize, Deserialize)]`.
//!
//! Read a general CBOR value with an unknown content.
//!
//! ```rust
//! use serde_ipld_dagcbor::from_slice;
//! use libipld_core::ipld::Ipld;
//!
//! let slice = b"\x82\x01\xa1aaab";
//! let value: Ipld = from_slice(slice).unwrap();
//! println!("{:?}", value); // List([Integer(1), Map({"a": String("b")})])
//! ```
//!
//! Serialize an object.
//!
//! ```rust
//! use std::collections::BTreeMap;
//! use serde_ipld_dagcbor::to_vec;
//!
//! let mut programming_languages = BTreeMap::new();
//! programming_languages.insert("rust", vec!["safe", "concurrent", "fast"]);
//! programming_languages.insert("python", vec!["powerful", "friendly", "open"]);
//! programming_languages.insert("js", vec!["lightweight", "interpreted", "object-oriented"]);
//! let encoded = to_vec(&programming_languages);
//! assert_eq!(encoded.unwrap().len(), 103);
//! ```
//!
//! # `no-std` support
//!
//! Serde CBOR supports building in a `no_std` context, use the following lines
//! in your `Cargo.toml` dependencies:
//! ``` toml
//! [dependencies]
//! serde = { version = "1.0", default-features = false }
//! serde_ipld_dagcbor = { version = "0.1.0", default-features = false }
//! ```
//!
//! Without the `std` feature the functions [from_reader], and [to_writer] are not exported.
//!
//! *Note*: to use derive macros in serde you will need to declare `serde`
//! dependency like so:
//! ``` toml
//! serde = { version = "1.0", default-features = false, features = ["derive"] }
//! ```

#![deny(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(not(feature = "std"))]
extern crate alloc;

mod cbor4ii_nonpub;
pub mod de;
pub mod error;
pub mod ser;

#[doc(inline)]
pub use crate::error::{DecodeError, EncodeError};

// Convenience functions for serialization and deserialization.
#[doc(inline)]
pub use crate::de::from_slice;

#[cfg(feature = "std")]
#[doc(inline)]
pub use crate::de::from_reader;

#[doc(inline)]
pub use crate::ser::to_vec;

#[cfg(feature = "std")]
#[doc(inline)]
pub use crate::ser::to_writer;

/// The CBOR tag that is used for CIDs.
const CBOR_TAGS_CID: u64 = 42;