1pub mod error;
6pub mod routes;
7pub mod state;
8
9use axum::{routing::get, Router};
10use serde::{Deserialize, Serialize};
11use std::net::SocketAddr;
12use tower_http::{
13 compression::CompressionLayer,
14 cors::{Any, CorsLayer},
15 trace::TraceLayer,
16};
17
18pub use error::{Error, Result};
19pub use state::AppState;
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct Config {
24 pub host: String,
26 pub port: u16,
28 pub enable_cors: bool,
30 pub enable_compression: bool,
32}
33
34impl Default for Config {
35 fn default() -> Self {
36 Self {
37 host: "127.0.0.1".to_string(),
38 port: 6333,
39 enable_cors: true,
40 enable_compression: true,
41 }
42 }
43}
44
45pub struct RuvectorServer {
47 config: Config,
48 state: AppState,
49}
50
51impl RuvectorServer {
52 pub fn new() -> Self {
54 Self {
55 config: Config::default(),
56 state: AppState::new(),
57 }
58 }
59
60 pub fn with_config(config: Config) -> Self {
62 Self {
63 config,
64 state: AppState::new(),
65 }
66 }
67
68 fn build_router(&self) -> Router {
70 let mut router = Router::new()
71 .route("/health", get(routes::health::health_check))
72 .route("/ready", get(routes::health::readiness))
73 .nest("/collections", routes::collections::routes())
74 .merge(routes::points::routes())
75 .with_state(self.state.clone());
76
77 router = router.layer(TraceLayer::new_for_http());
79
80 if self.config.enable_compression {
81 router = router.layer(CompressionLayer::new());
82 }
83
84 if self.config.enable_cors {
85 let cors = CorsLayer::new()
86 .allow_origin(Any)
87 .allow_methods(Any)
88 .allow_headers(Any);
89 router = router.layer(cors);
90 }
91
92 router
93 }
94
95 pub async fn start(self) -> Result<()> {
101 let addr: SocketAddr = format!("{}:{}", self.config.host, self.config.port)
102 .parse()
103 .map_err(|e| Error::Config(format!("Invalid address: {}", e)))?;
104
105 let router = self.build_router();
106
107 tracing::info!("Starting ruvector-server on {}", addr);
108
109 let listener = tokio::net::TcpListener::bind(addr)
110 .await
111 .map_err(|e| Error::Server(format!("Failed to bind to {}: {}", addr, e)))?;
112
113 axum::serve(listener, router)
114 .await
115 .map_err(|e| Error::Server(format!("Server error: {}", e)))?;
116
117 Ok(())
118 }
119}
120
121impl Default for RuvectorServer {
122 fn default() -> Self {
123 Self::new()
124 }
125}