gitent_server/
server.rs

1use crate::api::{create_router, AppState};
2use crate::watcher::FileWatcher;
3use gitent_core::{Session, Storage};
4use std::net::SocketAddr;
5use std::path::PathBuf;
6use std::sync::{Arc, Mutex};
7use tracing::info;
8
9pub struct GitentServer {
10    session: Session,
11    storage: Arc<Mutex<Storage>>,
12    _watcher: FileWatcher,
13}
14
15impl GitentServer {
16    pub fn new(root_path: PathBuf, db_path: PathBuf) -> anyhow::Result<Self> {
17        let session = Session::new(root_path);
18        let storage = Arc::new(Mutex::new(Storage::new(db_path)?));
19
20        {
21            let storage_guard = storage.lock().unwrap();
22            storage_guard.create_session(&session)?;
23        }
24
25        let watcher = FileWatcher::new(&session, Arc::clone(&storage))?;
26
27        Ok(Self {
28            session,
29            storage,
30            _watcher: watcher,
31        })
32    }
33
34    pub async fn serve(self, addr: SocketAddr) -> anyhow::Result<()> {
35        let state = AppState {
36            storage: self.storage,
37        };
38
39        let app = create_router(state);
40
41        info!("Server listening on {}", addr);
42        info!("Session ID: {}", self.session.id);
43        info!("Watching: {:?}", self.session.root_path);
44
45        let listener = tokio::net::TcpListener::bind(addr).await?;
46        axum::serve(listener, app).await?;
47
48        Ok(())
49    }
50
51    pub fn session_id(&self) -> uuid::Uuid {
52        self.session.id
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use tempfile::TempDir;
60
61    #[tokio::test]
62    async fn test_server_creation() {
63        let temp_dir = TempDir::new().unwrap();
64        let db_dir = TempDir::new().unwrap();
65
66        let db_path = db_dir.path().join("test.db");
67        let server = GitentServer::new(temp_dir.path().to_path_buf(), db_path);
68
69        assert!(server.is_ok());
70    }
71}