Add backend trait and git backend stub
parent: tbd commit: b9203a9
Showing 6 changed files with 220 insertions and 21 deletions
src/backend/git.rs
@@ -0,0 +1,65 @@ | ||
1 | use std::error::Error; | |
2 | ||
3 | use crate::{ | |
4 | command::repository::{ | |
5 | CreateRepositoryCommand, CreateRepositoryResponse, RepositoryFileInspectionCommand, | |
6 | RepositoryFileInspectionResponse, RepositoryInfoRequest, RepositoryIssueLabelsRequest, | |
7 | RepositoryIssueLabelsResponse, RepositoryIssuesCountRequest, RepositoryIssuesCountResponse, | |
8 | RepositoryIssuesRequest, RepositoryIssuesResponse, | |
9 | }, | |
10 | model::repository::RepositoryView, | |
11 | }; | |
12 | ||
13 | use super::RepositoryBackend; | |
14 | ||
15 | pub struct GitBackend; | |
16 | ||
17 | impl GitBackend { | |
18 | pub fn new() -> Self { | |
19 | Self | |
20 | } | |
21 | } | |
22 | ||
23 | impl RepositoryBackend for GitBackend { | |
24 | fn create_repository( | |
25 | &mut self, | |
26 | request: &CreateRepositoryCommand, | |
27 | ) -> Result<CreateRepositoryResponse, Box<dyn Error + Send>> { | |
28 | todo!() | |
29 | } | |
30 | ||
31 | fn repository_info( | |
32 | &mut self, | |
33 | request: &RepositoryInfoRequest, | |
34 | ) -> Result<RepositoryView, Box<dyn Error + Send>> { | |
35 | todo!() | |
36 | } | |
37 | ||
38 | fn repository_file_inspect( | |
39 | &mut self, | |
40 | request: &RepositoryFileInspectionCommand, | |
41 | ) -> Result<RepositoryFileInspectionResponse, Box<dyn Error + Send>> { | |
42 | todo!() | |
43 | } | |
44 | ||
45 | fn repository_issues_count( | |
46 | &mut self, | |
47 | request: &RepositoryIssuesCountRequest, | |
48 | ) -> Result<RepositoryIssuesCountResponse, Box<dyn Error + Send>> { | |
49 | todo!() | |
50 | } | |
51 | ||
52 | fn repository_issue_labels( | |
53 | &mut self, | |
54 | request: &RepositoryIssueLabelsRequest, | |
55 | ) -> Result<RepositoryIssueLabelsResponse, Box<dyn Error + Send>> { | |
56 | todo!() | |
57 | } | |
58 | ||
59 | fn repository_issues( | |
60 | &mut self, | |
61 | request: &RepositoryIssuesRequest, | |
62 | ) -> Result<RepositoryIssuesResponse, Box<dyn Error + Send>> { | |
63 | todo!() | |
64 | } | |
65 | } |
src/backend/mod.rs
@@ -0,0 +1,41 @@ | ||
1 | pub mod git; | |
2 | ||
3 | use std::error::Error; | |
4 | ||
5 | use crate::{ | |
6 | command::repository::{ | |
7 | CreateRepositoryCommand, CreateRepositoryResponse, RepositoryFileInspectionCommand, | |
8 | RepositoryFileInspectionResponse, RepositoryInfoRequest, RepositoryIssueLabelsRequest, | |
9 | RepositoryIssueLabelsResponse, RepositoryIssuesCountRequest, RepositoryIssuesCountResponse, | |
10 | RepositoryIssuesRequest, RepositoryIssuesResponse, | |
11 | }, | |
12 | model::repository::RepositoryView, | |
13 | }; | |
14 | ||
15 | pub trait RepositoryBackend { | |
16 | fn create_repository( | |
17 | &mut self, | |
18 | request: &CreateRepositoryCommand, | |
19 | ) -> Result<CreateRepositoryResponse, Box<dyn Error + Send>>; | |
20 | fn repository_info( | |
21 | &mut self, | |
22 | request: &RepositoryInfoRequest, | |
23 | ) -> Result<RepositoryView, Box<dyn Error + Send>>; | |
24 | fn repository_file_inspect( | |
25 | &mut self, | |
26 | request: &RepositoryFileInspectionCommand, | |
27 | ) -> Result<RepositoryFileInspectionResponse, Box<dyn Error + Send>>; | |
28 | ||
29 | fn repository_issues_count( | |
30 | &mut self, | |
31 | request: &RepositoryIssuesCountRequest, | |
32 | ) -> Result<RepositoryIssuesCountResponse, Box<dyn Error + Send>>; | |
33 | fn repository_issue_labels( | |
34 | &mut self, | |
35 | request: &RepositoryIssueLabelsRequest, | |
36 | ) -> Result<RepositoryIssueLabelsResponse, Box<dyn Error + Send>>; | |
37 | fn repository_issues( | |
38 | &mut self, | |
39 | request: &RepositoryIssuesRequest, | |
40 | ) -> Result<RepositoryIssuesResponse, Box<dyn Error + Send>>; | |
41 | } |
src/command/repository.rs
@@ -34,7 +34,7 @@ pub enum RepositoryResponse { | ||
34 | 34 | CreateRepository(CreateRepositoryResponse), |
35 | 35 | RepositoryFileInspection(RepositoryFileInspectionResponse), |
36 | 36 | RepositoryInfo(RepositoryView), |
37 | IssuesCount(IssuesCountResponse), | |
37 | IssuesCount(RepositoryIssuesCountResponse), | |
38 | 38 | IssueLabels(RepositoryIssueLabelsResponse), |
39 | 39 | Issues(RepositoryIssuesResponse), |
40 | 40 | } |
src/connection.rs
@@ -13,6 +13,7 @@ use tokio::{ | ||
13 | 13 | use tokio_tungstenite::{tungstenite::Message, WebSocketStream}; |
14 | 14 | |
15 | 15 | use crate::{ |
16 | backend::RepositoryBackend, | |
16 | 17 | command::{ |
17 | 18 | issues::IssuesCountResponse, |
18 | 19 | repository::{ |
@@ -56,6 +57,7 @@ pub async fn connection_worker( | ||
56 | 57 | mut socket: WebSocketStream<TcpStream>, |
57 | 58 | listeners: Arc<Mutex<Listeners>>, |
58 | 59 | mut connections: Arc<Mutex<Connections>>, |
60 | backend: Arc<Mutex<dyn RepositoryBackend + Send>>, | |
59 | 61 | addr: SocketAddr, |
60 | 62 | ) { |
61 | 63 | let mut handshaked = false; |
@@ -183,20 +185,76 @@ pub async fn connection_worker( | ||
183 | 185 | // This message is targeting this instance |
184 | 186 | match &repository.command { |
185 | 187 | RepositoryMessageKind::Request(request) => match request { |
186 | RepositoryRequest::CreateRepository(_) => todo!(), | |
187 | RepositoryRequest::RepositoryFileInspection(_) => { | |
188 | let response = RepositoryFileInspectionResponse::File { | |
189 | commit_metadata: CommitMetadata::default(), | |
188 | RepositoryRequest::CreateRepository(request) => { | |
189 | let mut backend = backend.lock().await; | |
190 | let response = backend.create_repository(request); | |
191 | ||
192 | let response = match response { | |
193 | Ok(response) => response, | |
194 | Err(err) => { | |
195 | error!("Error handling request: {:?}", err); | |
196 | continue; | |
197 | } | |
190 | 198 | }; |
199 | drop(backend); | |
200 | ||
201 | socket | |
202 | .send(Message::Binary( | |
203 | serde_json::to_vec(&MessageKind::Repository( | |
204 | RepositoryMessage { | |
205 | target: repository.target.clone(), | |
206 | command: RepositoryMessageKind::Response( | |
207 | RepositoryResponse::CreateRepository(response), | |
208 | ), | |
209 | }, | |
210 | )) | |
211 | .unwrap(), | |
212 | )) | |
213 | .await | |
214 | .unwrap(); | |
215 | } | |
216 | RepositoryRequest::RepositoryFileInspection(request) => { | |
217 | let mut backend = backend.lock().await; | |
218 | let response = backend.repository_file_inspect(request); | |
219 | ||
220 | let response = match response { | |
221 | Ok(response) => response, | |
222 | Err(err) => { | |
223 | error!("Error handling request: {:?}", err); | |
224 | continue; | |
225 | } | |
226 | }; | |
227 | drop(backend); | |
228 | ||
229 | socket | |
230 | .send(Message::Binary( | |
231 | serde_json::to_vec(&MessageKind::Repository( | |
232 | RepositoryMessage { | |
233 | target: repository.target.clone(), | |
234 | command: RepositoryMessageKind::Response( | |
235 | RepositoryResponse::RepositoryFileInspection( | |
236 | response, | |
237 | ), | |
238 | ), | |
239 | }, | |
240 | )) | |
241 | .unwrap(), | |
242 | )) | |
243 | .await | |
244 | .unwrap(); | |
191 | 245 | } |
192 | RepositoryRequest::RepositoryInfo(_) => { | |
193 | let response = RepositoryView { | |
194 | name: String::from("Nederland"), | |
195 | description: String::from("ik hou van het nederland"), | |
196 | default_branch: String::from("nederland"), | |
197 | latest_commit: CommitMetadata::default(), | |
198 | files: vec![], | |
246 | RepositoryRequest::RepositoryInfo(request) => { | |
247 | let mut backend = backend.lock().await; | |
248 | let response = backend.repository_info(request); | |
249 | ||
250 | let response = match response { | |
251 | Ok(response) => response, | |
252 | Err(err) => { | |
253 | error!("Error handling request: {:?}", err); | |
254 | continue; | |
255 | } | |
199 | 256 | }; |
257 | drop(backend); | |
200 | 258 | |
201 | 259 | socket |
202 | 260 | .send(Message::Binary( |
@@ -213,9 +271,18 @@ pub async fn connection_worker( | ||
213 | 271 | .await |
214 | 272 | .unwrap(); |
215 | 273 | } |
216 | RepositoryRequest::IssuesCount(_) => { | |
217 | let response: IssuesCountResponse = | |
218 | IssuesCountResponse { count: 727420 }; | |
274 | RepositoryRequest::IssuesCount(request) => { | |
275 | let mut backend = backend.lock().await; | |
276 | let response = backend.repository_issues_count(request); | |
277 | ||
278 | let response = match response { | |
279 | Ok(response) => response, | |
280 | Err(err) => { | |
281 | error!("Error handling request: {:?}", err); | |
282 | continue; | |
283 | } | |
284 | }; | |
285 | drop(backend); | |
219 | 286 | |
220 | 287 | socket |
221 | 288 | .send(Message::Binary( |
@@ -232,9 +299,18 @@ pub async fn connection_worker( | ||
232 | 299 | .await |
233 | 300 | .unwrap(); |
234 | 301 | } |
235 | RepositoryRequest::IssueLabels(_) => { | |
236 | let response = RepositoryIssueLabelsResponse { labels: vec![] }; | |
237 | ||
302 | RepositoryRequest::IssueLabels(request) => { | |
303 | let mut backend = backend.lock().await; | |
304 | let response = backend.repository_issue_labels(request); | |
305 | ||
306 | let response = match response { | |
307 | Ok(response) => response, | |
308 | Err(err) => { | |
309 | error!("Error handling request: {:?}", err); | |
310 | continue; | |
311 | } | |
312 | }; | |
313 | drop(backend); | |
238 | 314 | socket |
239 | 315 | .send(Message::Binary( |
240 | 316 | serde_json::to_vec(&MessageKind::Repository( |
@@ -250,8 +326,18 @@ pub async fn connection_worker( | ||
250 | 326 | .await |
251 | 327 | .unwrap(); |
252 | 328 | } |
253 | RepositoryRequest::Issues(_) => { | |
254 | let response = RepositoryIssuesResponse { issues: vec![] }; | |
329 | RepositoryRequest::Issues(request) => { | |
330 | let mut backend = backend.lock().await; | |
331 | let response = backend.repository_issues(request); | |
332 | ||
333 | let response = match response { | |
334 | Ok(response) => response, | |
335 | Err(err) => { | |
336 | error!("Error handling request: {:?}", err); | |
337 | continue; | |
338 | } | |
339 | }; | |
340 | drop(backend); | |
255 | 341 | |
256 | 342 | socket |
257 | 343 | .send(Message::Binary( |
src/lib.rs
@@ -1,3 +1,4 @@ | ||
1 | pub mod backend; | |
1 | 2 | pub mod command; |
2 | 3 | pub mod connection; |
3 | 4 | pub mod handshake; |
src/main.rs
@@ -1,7 +1,10 @@ | ||
1 | 1 | use std::{error::Error, net::SocketAddr, sync::Arc}; |
2 | 2 | |
3 | 3 | use connection::{connection_worker, Connections, RawConnection, UnestablishedConnection}; |
4 | use giterated_daemon::{connection, listener}; | |
4 | use giterated_daemon::{ | |
5 | backend::{git::GitBackend, RepositoryBackend}, | |
6 | connection, listener, | |
7 | }; | |
5 | 8 | use listener::Listeners; |
6 | 9 | use tokio::{ |
7 | 10 | io::{AsyncRead, AsyncWrite}, |
@@ -19,6 +22,8 @@ async fn main() -> Result<(), Box<dyn Error>> { | ||
19 | 22 | let mut listener = TcpListener::bind("127.0.0.1:8080").await?; |
20 | 23 | let mut connections: Arc<Mutex<Connections>> = Arc::default(); |
21 | 24 | let mut listeners: Arc<Mutex<Listeners>> = Arc::default(); |
25 | let mut backend: Arc<Mutex<dyn RepositoryBackend + Send>> = | |
26 | Arc::new(Mutex::new(GitBackend::new())); | |
22 | 27 | |
23 | 28 | loop { |
24 | 29 | let stream = accept_stream(&mut listener).await; |
@@ -53,6 +58,7 @@ async fn main() -> Result<(), Box<dyn Error>> { | ||
53 | 58 | connection, |
54 | 59 | listeners.clone(), |
55 | 60 | connections.clone(), |
61 | backend.clone(), | |
56 | 62 | address, |
57 | 63 | )), |
58 | 64 | }; |