qubit_codec/codec/codec_encode_error.rs
1// =============================================================================
2// Copyright (c) 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Generic encode error used by codec-backed encoder adapters.
9
10use thiserror::Error;
11
12/// Error reported by codec-backed buffered encoder adapters.
13///
14/// The wrapped codec remains responsible for domain-specific encode failures.
15/// This type adds adapter-level domain failures that cannot be represented by
16/// the wrapped codec itself, such as a value outside the codec's encodable
17/// domain. Buffer index and capacity failures are represented by
18/// [`crate::TranscodeError`].
19#[derive(Clone, Copy, Debug, Eq, Error, Hash, PartialEq)]
20pub enum CodecEncodeError<E> {
21 /// The wrapped codec reported an encode error.
22 #[error("codec encode error at input index {input_index}: {source}")]
23 Encode {
24 /// Error returned by the wrapped codec.
25 #[source]
26 source: E,
27 /// Absolute input index of the value being encoded.
28 input_index: usize,
29 },
30
31 /// The wrapped codec reported an error while resetting encode state.
32 #[error("codec encode reset error: {source}")]
33 EncodeReset {
34 /// Error returned by [`crate::Codec::encode_reset`].
35 #[source]
36 source: E,
37 },
38
39 /// The wrapped codec reported an error while flushing encode state.
40 #[error("codec encode flush error: {source}")]
41 EncodeFlush {
42 /// Error returned by [`crate::Codec::encode_flush`].
43 #[source]
44 source: E,
45 },
46
47 /// The wrapped codec cannot represent the input value.
48 #[error("unencodable value at input index {input_index}")]
49 UnencodableValue {
50 /// Absolute input index of the value being encoded.
51 input_index: usize,
52 },
53}
54
55impl<E> CodecEncodeError<E> {
56 /// Creates an error wrapping a codec-specific encode error.
57 ///
58 /// # Parameters
59 ///
60 /// - `source`: Error returned by the wrapped codec.
61 /// - `input_index`: Absolute input index of the value being encoded.
62 ///
63 /// # Returns
64 ///
65 /// Returns a codec encode error wrapper.
66 #[inline(always)]
67 #[must_use]
68 pub const fn encode(source: E, input_index: usize) -> Self {
69 Self::Encode {
70 source,
71 input_index,
72 }
73 }
74
75 /// Creates an error wrapping a codec-specific encode-reset error.
76 ///
77 /// # Parameters
78 ///
79 /// - `source`: Error returned by [`crate::Codec::encode_reset`].
80 ///
81 /// # Returns
82 ///
83 /// Returns a codec encode-reset error wrapper.
84 #[inline(always)]
85 #[must_use]
86 pub const fn encode_reset(source: E) -> Self {
87 Self::EncodeReset { source }
88 }
89
90 /// Creates an error wrapping a codec-specific encode-flush error.
91 ///
92 /// # Parameters
93 ///
94 /// - `source`: Error returned by [`crate::Codec::encode_flush`].
95 ///
96 /// # Returns
97 ///
98 /// Returns a codec encode-flush error wrapper.
99 #[inline(always)]
100 #[must_use]
101 pub const fn encode_flush(source: E) -> Self {
102 Self::EncodeFlush { source }
103 }
104
105 /// Creates an unencodable-value error.
106 ///
107 /// # Parameters
108 ///
109 /// - `input_index`: Absolute input index of the value being encoded.
110 ///
111 /// # Returns
112 ///
113 /// Returns an unencodable-value error.
114 #[inline(always)]
115 #[must_use]
116 pub const fn unencodable_value(input_index: usize) -> Self {
117 Self::UnencodableValue { input_index }
118 }
119
120 /// Extracts the wrapped codec source error, when this variant has one.
121 ///
122 /// # Returns
123 ///
124 /// Returns `Some(source)` for codec encode, reset, and flush failures.
125 /// Returns `None` for adapter-only failures.
126 #[inline(always)]
127 #[must_use]
128 pub fn into_source(self) -> Option<E> {
129 match self {
130 Self::Encode { source, .. }
131 | Self::EncodeReset { source }
132 | Self::EncodeFlush { source } => Some(source),
133 Self::UnencodableValue { .. } => None,
134 }
135 }
136}