use alloc::string::String;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ReasoningState {
provider: String,
payload: String,
}
impl ReasoningState {
#[must_use]
pub fn new(provider: impl Into<String>, payload: impl Into<String>) -> Self {
Self {
provider: provider.into(),
payload: payload.into(),
}
}
#[must_use]
pub fn provider(&self) -> &str {
&self.provider
}
#[must_use]
pub fn payload(&self) -> &str {
&self.payload
}
#[must_use]
pub fn payload_for(&self, provider: &str) -> Option<&str> {
(self.provider == provider).then_some(self.payload.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec::Vec;
#[test]
fn payload_is_returned_only_to_its_own_provider() {
let state = ReasoningState::new("claude", "opaque-signature");
assert_eq!(state.payload_for("claude"), Some("opaque-signature"));
assert_eq!(state.payload_for("openai"), None);
assert_eq!(state.payload_for("gemini"), None);
}
#[test]
fn filtering_a_mixed_conversation_keeps_only_native_state() {
let states = [
ReasoningState::new("claude", "a"),
ReasoningState::new("openai", "b"),
ReasoningState::new("claude", "c"),
];
let kept: Vec<&str> = states
.iter()
.filter_map(|state| state.payload_for("claude"))
.collect();
assert_eq!(kept, ["a", "c"]);
}
}