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
//! Decoder trait for type-safe conversions.
//!
//! The `Decoder` trait enables converting from a source type `T` to a
//! destination type `D` in a type-safe manner. It is used throughout
//! tsumiki to convert between different representations of PKI data.
//!
//! # Design Pattern
//!
//! The decoder uses a two-trait pattern for type safety:
//!
//! 1. `Decoder<T, D>` - Performs the actual conversion
//! 2. `DecodableFrom<T>` - Marker trait constraining valid conversions
//!
//! This ensures that only valid type conversions are possible at compile time.
//!
//! # Implementation Guide
//!
//! To add a new decodable type, implement both traits:
//!
//! ```no_run
//! use tsumiki::decoder::{Decoder, DecodableFrom};
//!
//! struct SourceType(Vec<u8>);
//! struct DestType(String);
//!
//! #[derive(Debug)]
//! struct MyError;
//!
//! // 1. Mark the destination type as decodable from the source type
//! impl DecodableFrom<SourceType> for DestType {}
//!
//! // 2. Implement the decoder on the source type
//! impl Decoder<SourceType, DestType> for SourceType {
//! type Error = MyError;
//!
//! fn decode(&self) -> Result<DestType, Self::Error> {
//! // Conversion logic here
//! Ok(DestType(String::from_utf8_lossy(&self.0).to_string()))
//! }
//! }
//! ```
//!
//! # Example
//!
//! The `der` crate implements decoding from byte slices to DER structures:
//!
//! ```ignore
//! use tsumiki::decoder::Decoder;
//! use tsumiki_der::Der;
//!
//! let bytes = vec![0x30, 0x00]; // SEQUENCE with length 0
//! let der: Der = bytes.decode().unwrap();
//! ```
/// Decoder trait for converting from type `T` to type `D`.
///
/// This trait is implemented by the source type `T` to enable conversion
/// to the destination type `D`. The destination type must implement
/// `DecodableFrom<T>` to ensure type safety.
///
/// # Type Parameters
///
/// * `T` - The source type (usually `Self`)
/// * `D` - The destination type that can be decoded from `T`
///
/// # Examples
///
/// Implementing a decoder:
///
/// ```no_run
/// use tsumiki::decoder::{Decoder, DecodableFrom};
///
/// struct MyType(String);
///
/// #[derive(Debug)]
/// struct MyError;
///
/// impl DecodableFrom<Vec<u8>> for MyType {}
///
/// impl Decoder<Vec<u8>, MyType> for Vec<u8> {
/// type Error = MyError;
///
/// fn decode(&self) -> Result<MyType, Self::Error> {
/// // Parse self (Vec<u8>) and construct MyType
/// Ok(MyType(String::from_utf8_lossy(self).to_string()))
/// }
/// }
/// ```
///
/// Using a decoder:
///
/// ```ignore
/// use tsumiki::decoder::Decoder;
/// use tsumiki_der::Der;
///
/// let bytes = vec![0x30, 0x00];
/// let result: Der = bytes.decode().unwrap();
/// ```
/// Marker trait indicating that type `D` can be decoded from type `T`.
///
/// This trait is used to constrain the `Decoder` trait and ensure
/// type safety at compile time. It prevents invalid conversions by
/// requiring explicit implementation for each valid type pair.
///
/// # Purpose
///
/// This trait serves as a compile-time guard. Without it, any type
/// could attempt to decode into any other type, leading to potential
/// runtime errors. By requiring `DecodableFrom<T>` to be implemented,
/// the compiler can verify that a conversion is valid before allowing
/// the `Decoder` implementation.
///
/// # Implementation
///
/// This trait has no methods and serves only as a marker. Implement it
/// for destination types that can be decoded from a source type:
///
/// ```no_run
/// use tsumiki::decoder::DecodableFrom;
///
/// struct MySourceType;
/// struct MyDestType;
///
/// // Allow MyDestType to be decoded from MySourceType
/// impl DecodableFrom<MySourceType> for MyDestType {}
/// ```