gemini_genai_rs/session/
traits.rs

1//! Session traits for testability and middleware injection.
2//!
3//! [`SessionWriter`] — write-side: send commands without owning the full handle.
4//! [`SessionReader`] — read-side: subscribe to events and observe phase.
5
6use super::errors::SessionError;
7use super::events::SessionEvent;
8use super::state::SessionPhase;
9use crate::protocol::{Content, FunctionResponse};
10use async_trait::async_trait;
11use tokio::sync::broadcast;
12
13/// Write-side of a session — send commands without owning the full handle.
14#[async_trait]
15pub trait SessionWriter: Send + Sync + 'static {
16    /// Send raw PCM16 audio bytes.
17    async fn send_audio(&self, data: Vec<u8>) -> Result<(), SessionError>;
18    /// Send a text message.
19    async fn send_text(&self, text: String) -> Result<(), SessionError>;
20    /// Send tool/function call responses back to the model.
21    async fn send_tool_response(
22        &self,
23        responses: Vec<FunctionResponse>,
24    ) -> Result<(), SessionError>;
25    /// Send client content (conversation history or context).
26    async fn send_client_content(
27        &self,
28        turns: Vec<Content>,
29        turn_complete: bool,
30    ) -> Result<(), SessionError>;
31    /// Send a video/image frame (raw JPEG bytes).
32    async fn send_video(&self, jpeg_data: Vec<u8>) -> Result<(), SessionError>;
33    /// Update the system instruction mid-session.
34    async fn update_instruction(&self, instruction: String) -> Result<(), SessionError>;
35    /// Signal that user speech activity has started.
36    async fn signal_activity_start(&self) -> Result<(), SessionError>;
37    /// Signal that user speech activity has ended.
38    async fn signal_activity_end(&self) -> Result<(), SessionError>;
39    /// Gracefully disconnect the session.
40    async fn disconnect(&self) -> Result<(), SessionError>;
41}
42
43/// Read-side of a session — subscribe to events and observe phase.
44pub trait SessionReader: Send + Sync + 'static {
45    /// Subscribe to the session event broadcast stream.
46    fn subscribe(&self) -> broadcast::Receiver<SessionEvent>;
47    /// Returns the current session phase.
48    fn phase(&self) -> SessionPhase;
49    /// Returns the unique session ID.
50    fn session_id(&self) -> &str;
51}
52
53#[cfg(test)]
54mod tests {
55    use super::super::handle::SessionHandle;
56    use super::*;
57
58    #[test]
59    fn session_handle_implements_session_writer() {
60        fn assert_impl<T: SessionWriter>() {}
61        assert_impl::<SessionHandle>();
62    }
63
64    #[test]
65    fn session_handle_implements_session_reader() {
66        fn assert_impl<T: SessionReader>() {}
67        assert_impl::<SessionHandle>();
68    }
69
70    #[test]
71    fn session_writer_is_object_safe() {
72        fn _assert(_: &dyn SessionWriter) {}
73    }
74
75    #[test]
76    fn session_reader_is_object_safe() {
77        fn _assert(_: &dyn SessionReader) {}
78    }
79}