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
/*******************************************************************************
*
* Copyright (c) 2026 Haixing Hu.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0.
*
******************************************************************************/
//! Slot that owns the converter's retained decoded value.
use super::{
buffered_encode_engine::BufferedEncodeEngine,
buffered_encode_hooks::BufferedEncodeHooks,
convert_state::ConvertState,
pending_encode_step::PendingEncodeStep,
pending_value::PendingValue,
transcode_progress::TranscodeProgress,
};
use crate::{
CapacityError,
Codec,
};
/// Slot that owns the converter's retained decoded value.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub(super) struct PendingValueSlot<Value> {
/// Retained decoded value waiting for output capacity.
value: Option<PendingValue<Value>>,
}
impl<Value> PendingValueSlot<Value> {
/// Creates an empty pending-value slot.
#[must_use]
#[inline(always)]
pub(super) const fn empty() -> Self {
Self { value: None }
}
/// Returns the target-output bound for the retained value.
///
/// # Type Parameters
///
/// - `E`: Encoder codec type used to query output bounds.
/// - `H`: Encoder hook type used by the encoder engine.
///
/// # Parameters
///
/// - `engine`: Target encode engine for one-value output bound query.
///
/// # Returns
///
/// Returns the output unit bound contributed by the retained value.
#[must_use = "capacity planning can fail on overflow"]
#[inline]
pub(super) fn max_output_len<E, H>(&self, engine: &BufferedEncodeEngine<E, H>) -> Result<usize, CapacityError>
where
E: Codec<Value = Value>,
H: BufferedEncodeHooks<E>,
{
if self.value.is_some() {
engine.max_output_len(1)
} else {
Ok(0)
}
}
/// Removes any retained decoded value.
///
/// # Returns
///
/// Returns unit `()`.
#[inline(always)]
pub(super) fn clear(&mut self) {
self.value = None;
}
/// Takes the retained decoded value, if any.
///
/// # Returns
///
/// Returns the retained value when present, otherwise `None`.
#[inline(always)]
pub(super) fn take(&mut self) -> Option<PendingValue<Value>> {
self.value.take()
}
/// Applies a pending-value encode step to this slot and the current conversion state.
///
/// # Type Parameters
///
/// - `Input`: Converter input-unit type carried by conversion state.
/// - `Output`: Converter output-unit type carried by conversion state.
///
/// # Parameters
///
/// - `step`: Pending encode step produced by encoding attempts.
/// - `state`: Shared conversion state updated by the step result.
///
/// # Returns
///
/// Returns:
/// - `None` when output has been produced immediately.
/// - `Some(progress)` when output progress should stop for missing capacity.
#[inline]
pub(super) fn apply_pending_encode_step<Input, Output>(
&mut self,
step: PendingEncodeStep<Value>,
state: &mut ConvertState<'_, Input, Output>,
) -> Option<TranscodeProgress> {
match step {
PendingEncodeStep::Written { written } => {
state.advance_output(written);
None
}
PendingEncodeStep::NeedOutput {
pending,
additional,
available,
} => {
self.value = Some(pending);
Some(state.need_output_progress(additional, available))
}
}
}
}