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
//! Encoder trait for type-safe conversions.
//!
//! The `Encoder` trait enables converting from a source type `T` to an
//! encoded type `E` in a type-safe manner. It is the inverse of the
//! `Decoder` trait and is used to convert PKI data structures back into
//! their encoded representations.
//!
//! # Design Pattern
//!
//! The encoder uses a two-trait pattern for type safety:
//!
//! 1. `Encoder<T, E>` - Performs the actual conversion
//! 2. `EncodableTo<T>` - Marker trait constraining valid conversions
//!
//! This ensures that only valid type conversions are possible at compile time.
//!
//! # Implementation Guide
//!
//! To add a new encodable type, implement both traits:
//!
//! ```no_run
//! use tsumiki::encoder::{Encoder, EncodableTo};
//!
//! struct SourceType { data: Vec<u8> }
//! struct EncodedType(Vec<u8>);
//!
//! #[derive(Debug)]
//! struct MyError;
//!
//! // 1. Mark the destination type as encodable from the source type
//! impl EncodableTo<SourceType> for EncodedType {}
//!
//! // 2. Implement the encoder on the source type
//! impl Encoder<SourceType, EncodedType> for SourceType {
//! type Error = MyError;
//!
//! fn encode(&self) -> Result<EncodedType, Self::Error> {
//! // Encoding logic here
//! Ok(EncodedType(self.data.clone()))
//! }
//! }
//! ```
//!
//! # Example
//!
//! The `der` crate implements encoding from DER structures to bytes:
//!
//! ```ignore
//! use tsumiki::encoder::Encoder;
//! use tsumiki_der::Der;
//!
//! let der = Der::new(vec![0x30, 0x00]);
//! let bytes: Vec<u8> = der.encode().unwrap();
//! ```
/// Encoder trait for converting from type `T` to type `E`.
///
/// This trait is implemented by the source type `T` to enable conversion
/// to the encoded type `E`. The destination type must implement
/// `EncodableTo<T>` to ensure type safety.
///
/// # Type Parameters
///
/// * `T` - The source type (usually `Self`)
/// * `E` - The encoded type that `T` can be encoded to
///
/// # Examples
///
/// Implementing an encoder:
///
/// ```no_run
/// use tsumiki::encoder::{Encoder, EncodableTo};
///
/// struct MyType { value: u32 }
///
/// #[derive(Debug)]
/// struct MyError;
///
/// impl EncodableTo<MyType> for Vec<u8> {}
///
/// impl Encoder<MyType, Vec<u8>> for MyType {
/// type Error = MyError;
///
/// fn encode(&self) -> Result<Vec<u8>, Self::Error> {
/// // Serialize self (MyType) to bytes
/// Ok(self.value.to_be_bytes().to_vec())
/// }
/// }
/// ```
///
/// Using an encoder:
///
/// ```ignore
/// use tsumiki::encoder::Encoder;
/// use tsumiki_der::Der;
///
/// let der = Der::new(vec![0x30, 0x00]);
/// let bytes: Vec<u8> = der.encode().unwrap();
/// ```
/// Marker trait indicating that type `E` can be encoded from type `T`.
///
/// This trait is used to constrain the `Encoder` 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 encode into any other type, leading to potential
/// runtime errors. By requiring `EncodableTo<T>` to be implemented,
/// the compiler can verify that a conversion is valid before allowing
/// the `Encoder` implementation.
///
/// # Implementation
///
/// This trait has no methods and serves only as a marker. Implement it
/// for destination types that can be encoded from a source type:
///
/// ```no_run
/// use tsumiki::encoder::EncodableTo;
///
/// struct MySourceType;
/// struct MyEncodedType;
///
/// // Allow MySourceType to be encoded to MyEncodedType
/// impl EncodableTo<MySourceType> for MyEncodedType {}
/// ```