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