use crate::id::{MessageId, PartId, SessionId}; use crate::storage::FileReader; use crate::types::message::FileDiff; use crate::types::{Message, Part, SessionInfo}; use crate::Result; pub struct SessionLoader { reader: FileReader, } impl SessionLoader { pub fn new() -> Result { let reader = FileReader::new()?; Ok(Self { reader }) } pub fn with_reader(reader: FileReader) -> Self { Self { reader } } pub fn reader(&self) -> &FileReader { &self.reader } pub fn load_session(&self, project_id: &str, session_id: &SessionId) -> Result { let info = self.reader.read_session(project_id, session_id)?; let diff = self.reader.read_diff(session_id).ok(); Ok(LoadedSession { info, diff }) } pub fn load_message(&self, session_id: &SessionId, message_id: &MessageId) -> Result { self.reader.read_message(session_id, message_id) } pub fn load_part(&self, message_id: &MessageId, part_id: &PartId) -> Result { self.reader.read_part(message_id, part_id) } pub fn load_messages(&self, session_id: &SessionId) -> Result> { let message_ids = self.reader.list_messages(session_id)?; self.load_messages_by_ids(session_id, &message_ids) } pub fn load_messages_by_ids( &self, session_id: &SessionId, message_ids: &[MessageId], ) -> Result> { let mut messages = Vec::with_capacity(message_ids.len()); for msg_id in message_ids { messages.push(self.load_message(session_id, msg_id)?); } Ok(messages) } pub fn load_parts(&self, message_id: &MessageId) -> Result> { let part_ids = self.reader.list_parts(message_id)?; self.load_parts_by_ids(message_id, &part_ids) } pub fn load_parts_by_ids( &self, message_id: &MessageId, part_ids: &[PartId], ) -> Result> { let mut parts = Vec::with_capacity(part_ids.len()); for part_id in part_ids { parts.push(self.load_part(message_id, part_id)?); } Ok(parts) } pub fn load_message_with_parts( &self, session_id: &SessionId, message_id: &MessageId, ) -> Result { let message = self.load_message(session_id, message_id)?; let part_ids = self.reader.list_parts(message_id)?; let parts = self.load_parts_by_ids(message_id, &part_ids)?; Ok(MessageWithParts { message, parts }) } pub fn load_messages_with_parts( &self, session_id: &SessionId, message_ids: &[MessageId], ) -> Result> { let mut messages = Vec::with_capacity(message_ids.len()); for message_id in message_ids { messages.push(self.load_message_with_parts(session_id, message_id)?); } Ok(messages) } pub fn load_session_tree( &self, project_id: &str, session_id: &SessionId, ) -> Result { let session = self.load_session(project_id, session_id)?; let message_ids = self.reader.list_messages(session_id)?; let messages = self.load_messages_with_parts(session_id, &message_ids)?; Ok(SessionTree { session, messages }) } pub fn list_sessions(&self, project_id: &str) -> Result> { self.reader.list_sessions(project_id) } pub fn list_messages(&self, session_id: &SessionId) -> Result> { self.reader.list_messages(session_id) } pub fn list_parts(&self, message_id: &MessageId) -> Result> { self.reader.list_parts(message_id) } pub fn list_projects(&self) -> Result> { self.reader.paths().project_dirs() } } #[derive(Debug, Clone)] pub struct LoadedSession { pub info: SessionInfo, pub diff: Option>, } #[derive(Debug, Clone)] pub struct MessageWithParts { pub message: Message, pub parts: Vec, } #[derive(Debug, Clone)] pub struct SessionTree { pub session: LoadedSession, pub messages: Vec, } #[cfg(test)] mod tests { use super::*; use crate::Error; #[test] fn test_loader_creation() { let result = SessionLoader::new(); match result { Ok(_) => {} Err(Error::StorageRootNotFound) => {} Err(e) => panic!("unexpected error: {}", e), } } }