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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
// SPDX-License-Identifier: MIT or Apache-2.0
//! # multi-codec
//!
//! Implementation of the [Multicodec](https://github.com/multiformats/multicodec)
//! specification for self-describing protocol and encoding identifiers.
//!
//! ## Overview
//!
//! Multicodec is a self-describing multiformat that provides a way to uniquely
//! identify protocols, encodings, cryptographic algorithms, and other systems.
//! Each codec has:
//! - A unique numeric identifier (code)
//! - A human-readable name
//! - A canonical string representation
//!
//! This crate provides the [`Codec`] enum with 570+ variants representing all
//! standardized multicodec identifiers from the official specification.
//!
//! ## Features
//!
//! - **570+ Codec Variants**: All standardized multicodec identifiers
//! - **Type-Safe Conversions**: `TryFrom`/`Into` for all numeric types and strings
//! - **Serde Support**: JSON and binary serialization (feature-gated)
//! - **Zero Unsafe Code**: Completely safe Rust implementation
//! - **Thread-Safe**: All types are `Send + Sync`
//! - **Type Safety**: Optional newtype wrappers ([`CodecCode`], [`CodecName`])
//! - **Rich Errors**: Detailed error messages with context
//! - **Performance**: Optimized for speed with zero-copy operations where possible
//!
//! ## Quick Start
//!
//! ### Basic Usage
//!
//! ```rust
//! use multi_codec::Codec;
//!
//! // Create codec from name
//! let codec = Codec::try_from("ed25519-pub")?;
//! assert_eq!(codec, Codec::Ed25519Pub);
//!
//! // Get codec properties
//! assert_eq!(codec.code(), 0xED);
//! assert_eq!(codec.as_str(), "ed25519-pub");
//! assert_eq!(format!("{:?}", codec), "ed25519-pub (0xed)");
//! # Ok::<(), multi_codec::Error>(())
//! ```
//!
//! ### Encoding and Decoding
//!
//! ```rust
//! use multi_codec::Codec;
//! use multi_trait::TryDecodeFrom;
//!
//! let codec = Codec::Sha2256;
//!
//! // Encode to varint bytes
//! let bytes: Vec<u8> = codec.into();
//! assert_eq!(bytes, vec![0x12]); // Sha2-256 encodes as single byte
//!
//! // Decode from bytes
//! let (decoded, remaining) = Codec::try_decode_from(&bytes)?;
//! assert_eq!(decoded, codec);
//! assert!(remaining.is_empty());
//! # Ok::<(), multi_codec::Error>(())
//! ```
//!
//! ### Working with Codes and Names
//!
//! ```rust
//! use multi_codec::Codec;
//!
//! // From numeric code
//! let codec = Codec::try_from(0x12u64)?;
//! assert_eq!(codec, Codec::Sha2256);
//!
//! // From string name
//! let codec = Codec::try_from("sha2-256")?;
//! assert_eq!(codec, Codec::Sha2256);
//!
//! // Get code and name
//! assert_eq!(codec.code(), 0x12);
//! assert_eq!(codec.as_str(), "sha2-256");
//! # Ok::<(), multi_codec::Error>(())
//! ```
//!
//! ### Serde Integration
//!
//! ```rust
//! use multi_codec::Codec;
//! use serde::{Serialize, Deserialize};
//!
//! #[derive(Serialize, Deserialize, Debug, PartialEq)]
//! struct SignatureInfo {
//! algorithm: Codec,
//! public_key: Vec<u8>,
//! }
//!
//! let info = SignatureInfo {
//! algorithm: Codec::Ed25519Pub,
//! public_key: vec![1, 2, 3, 4],
//! };
//!
//! // Serialize to JSON (human-readable)
//! let json = serde_json::to_string(&info)?;
//! // JSON: {"algorithm":"ed25519-pub","public_key":[1,2,3,4]}
//!
//! // Deserialize from JSON
//! let deserialized: SignatureInfo = serde_json::from_str(&json)?;
//! assert_eq!(deserialized, info);
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ### Error Handling
//!
//! ```rust
//! use multi_codec::{Codec, Error};
//!
//! // Handle invalid names
//! match Codec::try_from("unknown-codec") {
//! Ok(codec) => println!("Valid: {}", codec.as_str()),
//! Err(Error::InvalidName { name }) => {
//! eprintln!("Unknown codec name: {}", name);
//! // Error includes link to valid codec table
//! }
//! Err(e) => eprintln!("Other error: {}", e),
//! }
//!
//! // Handle invalid codes
//! match Codec::try_from(0xDEADBEEFu64) {
//! Ok(codec) => println!("Valid: {}", codec.as_str()),
//! Err(Error::InvalidValue { code }) => {
//! eprintln!("Unknown codec value: 0x{:x}", code);
//! }
//! Err(e) => eprintln!("Other error: {}", e),
//! }
//!
//! // Handle negative values
//! match Codec::try_from(-1i64) {
//! Ok(codec) => println!("Valid: {}", codec.as_str()),
//! Err(Error::NegativeValue { value }) => {
//! eprintln!("Negative values not allowed: {}", value);
//! }
//! Err(e) => eprintln!("Other error: {}", e),
//! }
//! ```
//!
//! ## Type Safety with Newtypes
//!
//! For additional type safety, use the newtype wrappers:
//!
//! ```rust
//! use multi_codec::{Codec, CodecCode, CodecName};
//!
//! // Type-safe code value
//! let code = CodecCode::new(0xED);
//! assert_eq!(code.get(), 0xED);
//! assert_eq!(code.to_string(), "0xed");
//!
//! // Type-safe name
//! let name = CodecName::new("sha2-256");
//! assert_eq!(name.as_str(), "sha2-256");
//! assert!(!name.is_identity());
//! ```
//!
//! ## Thread Safety
//!
//! All types in this crate are `Send + Sync` and can be safely shared between threads:
//!
//! ```rust
//! use std::sync::Arc;
//! use std::thread;
//! use multi_codec::Codec;
//!
//! let codec = Arc::new(Codec::Ed25519Pub);
//! let handle = thread::spawn(move || {
//! println!("Codec: {} (0x{:x})", codec.as_str(), codec.code());
//! });
//! handle.join().unwrap();
//! ```
//!
//! ## Performance Characteristics
//!
//! - **Codec enum**: Zero-cost abstraction, `Copy` type (no heap allocations)
//! - **String lookups**: O(1) hash table lookups
//! - **Code lookups**: O(log n) binary search in generated match expressions
//! - **Encoding**: Stack-allocated buffers (no heap allocation)
//! - **Hash**: Direct u64 hashing (optimized in Phase 1)
//! - **Serialization**: Stack-allocated arrays (optimized in Phase 1)
//!
//! ## Security
//!
//! This crate follows strict security practices:
//!
//! - **No unsafe code**: Completely safe Rust implementation
//! - **Input validation**: All conversions validate input ranges
//! - **DoS protection**: Size limits on deserialization (max 19 bytes)
//! - **Integer overflow protection**: Negative value checks in signed conversions
//! - **Error handling**: All errors return `Result` types, no panics on invalid input
//! - **Thread safety**: All types are `Send + Sync` with no shared mutable state
//!
//! ## Multicodec Table
//!
//! The codec table is generated at build time from the official
//! [Multicodec Table CSV](https://github.com/multiformats/multicodec/blob/master/table.csv).
//! This ensures the crate stays synchronized with the specification.
//!
//! To update the table, replace `table.csv` and rebuild.
//!
//! ## Feature Flags
//!
//! - **`serde`** (default): Enables serde serialization/deserialization support
//!
//! ### Disabling Default Features
//!
//! ```toml
//! [dependencies]
//! multi-codec = { version = "1.0", default-features = false }
//! ```
//!
//! ## Common Patterns
//!
//! ### Using in Data Structures
//!
//! ```rust
//! use multi_codec::Codec;
//! use std::collections::HashMap;
//!
//! // Codec as HashMap key
//! let mut algorithms = HashMap::new();
//! algorithms.insert(Codec::Sha2256, "SHA-256");
//! algorithms.insert(Codec::Sha2512, "SHA-512");
//! algorithms.insert(Codec::Blake3, "BLAKE3");
//!
//! assert_eq!(algorithms.get(&Codec::Sha2256), Some(&"SHA-256"));
//! ```
//!
//! ### Sequential Codec Handling
//!
//! ```rust
//! use multi_codec::Codec;
//! use multi_trait::{TryDecodeFrom, EncodeIntoBuffer};
//!
//! // Encode multiple codecs sequentially
//! let codecs = vec![Codec::Identity, Codec::Sha2256, Codec::Ed25519Pub];
//!
//! let mut buffer = Vec::new();
//! for codec in &codecs {
//! let code: u64 = (*codec).into();
//! code.encode_into_buffer(&mut buffer);
//! }
//!
//! // Decode them back
//! let mut remaining = buffer.as_slice();
//! for expected in &codecs {
//! let (code, rest) = u64::try_decode_from(remaining)?;
//! let decoded = Codec::try_from(code)?;
//! assert_eq!(decoded, *expected);
//! remaining = rest;
//! }
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ## Examples
//!
//! See the `docs/multicodec/` directory for additional documentation and examples.
//!
//! ## Specification Compliance
//!
//! This crate implements the [Multicodec specification](https://github.com/multiformats/multicodec)
//! and maintains compatibility with the official codec table.
/// Errors produced by this library
pub use Error;
/// Codec enum definition from the table
pub use Codec;
/// Type-safe wrappers for codec identifiers
pub use ;
/// Serde serialization
/// Commonly used items
///
/// ```
/// use multi_codec::prelude::*;
///
/// let codec = Codec::try_from("sha2-256")?;
/// assert_eq!(codec.code(), 0x12);
/// # Ok::<(), multi_codec::Error>(())
/// ```