diff --git a/Cargo.lock b/Cargo.lock index a27ac7f..b9f4c0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,6 +265,33 @@ dependencies = [ ] [[package]] +name = "color-eyre" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] name = "const-oid" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -510,6 +537,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] name = "fastrand" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -701,6 +738,7 @@ dependencies = [ "async-trait", "bincode", "chrono", + "color-eyre", "deadpool", "futures-util", "giterated-models", @@ -978,6 +1016,12 @@ dependencies = [ ] [[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] name = "indexmap" version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1381,6 +1425,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] name = "parking_lot" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2514,6 +2564,16 @@ dependencies = [ ] [[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] name = "tracing-log" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/giterated-daemon/src/cache_backend.rs b/giterated-daemon/src/cache_backend.rs index a236d9f..cbdfb8d 100644 --- a/giterated-daemon/src/cache_backend.rs +++ b/giterated-daemon/src/cache_backend.rs @@ -14,7 +14,8 @@ impl ObjectBackend for CacheBackend { async fn object_operation + Debug>( &self, _object: O, - _operation: D, + operation: &str, + payload: D, ) -> Result> { // We don't handle operations with this backend Err(OperationError::Unhandled) diff --git a/giterated-daemon/src/connection/wrapper.rs b/giterated-daemon/src/connection/wrapper.rs index 2f9b8e4..ce24414 100644 --- a/giterated-daemon/src/connection/wrapper.rs +++ b/giterated-daemon/src/connection/wrapper.rs @@ -83,10 +83,17 @@ pub async fn connection_wrapper( let message: GiteratedMessage = message.into_message(); - backend - .object_operation(message.object, message.payload) - .await - .unwrap(); + let result = backend + .object_operation(message.object, &message.operation, message.payload) + .await; + + let mut socket = connection_state.socket.lock().await; + let _ = socket + .send(Message::Binary(bincode::serialize(&result).unwrap())) + .await; + + info!("Done!"); + drop(socket); } _ => { return; diff --git a/giterated-daemon/src/database_backend/handler.rs b/giterated-daemon/src/database_backend/handler.rs index 10caea2..724fa0c 100644 --- a/giterated-daemon/src/database_backend/handler.rs +++ b/giterated-daemon/src/database_backend/handler.rs @@ -2,12 +2,12 @@ use std::{collections::HashMap, pin::Pin, sync::Arc}; use futures_util::{future::BoxFuture, Future, FutureExt}; use giterated_models::{ - error::{GetValueError, OperationError}, + error::{GetValueError, OperationError, UserError}, object::{AnyObject, GiteratedObject}, operation::{AnyOperation, GiteratedOperation}, - repository::Repository, + repository::{Repository, RepositorySummary}, settings::{AnySetting, GetSetting, GetSettingError, SetSetting, SetSettingError}, - user::User, + user::{User, UserRepositoriesRequest}, value::{AnyValue, GetValue}, }; @@ -120,6 +120,25 @@ impl OperationWrapper { } } +pub fn user_get_repositories( + object: &User, + operation: UserRepositoriesRequest, + state: DatabaseBackend, +) -> BoxFuture<'static, Result, OperationError>> { + let object = object.clone(); + + async move { + let mut repositories_backend = state.repository_backend.lock().await; + let repositories = repositories_backend + .repositories_for_user(None, &object) + .await + .map_err(|e| OperationError::Internal(e.to_string()))?; + + Ok(repositories) + } + .boxed() +} + pub fn user_get_value( object: &User, operation: GetValue>, diff --git a/giterated-daemon/src/database_backend/mod.rs b/giterated-daemon/src/database_backend/mod.rs index b93adce..c4e649d 100644 --- a/giterated-daemon/src/database_backend/mod.rs +++ b/giterated-daemon/src/database_backend/mod.rs @@ -6,7 +6,7 @@ use std::{str::FromStr, sync::Arc}; use giterated_models::error::OperationError; use giterated_models::instance::Instance; use giterated_models::object::{ - GiteratedObject, Object, ObjectRequest, ObjectRequestError, ObjectResponse, + AnyObject, GiteratedObject, Object, ObjectRequest, ObjectRequestError, ObjectResponse, }; use giterated_models::object_backend::ObjectBackend; use giterated_models::operation::{AnyOperation, GiteratedOperation}; @@ -18,8 +18,8 @@ use tokio::sync::Mutex; use crate::backend::{RepositoryBackend, UserBackend}; use self::handler::{ - repository_get_setting, repository_get_value, repository_set_setting, user_get_setting, - user_get_value, user_set_setting, OperationHandlers, + repository_get_setting, repository_get_value, repository_set_setting, user_get_repositories, + user_get_setting, user_get_value, user_set_setting, OperationHandlers, }; #[derive(Clone, Debug)] @@ -30,7 +30,8 @@ impl ObjectBackend for Foobackend { async fn object_operation + Debug>( &self, _object: O, - _operation: D, + operation: &str, + payload: D, ) -> Result> { // We don't handle operations with this backend Err(OperationError::Unhandled) @@ -77,15 +78,17 @@ impl ObjectBackend for DatabaseBackend { async fn object_operation + Debug>( &self, object: O, - operation: D, + operation: &str, + payload: D, ) -> Result> { let serialized = - serde_json::to_value(operation).map_err(|e| OperationError::Internal(e.to_string()))?; + serde_json::to_value(payload).map_err(|e| OperationError::Internal(e.to_string()))?; let object = object.to_string(); if let Ok(user) = User::from_str(&object) { let mut handler = OperationHandlers::default(); handler + .insert(user_get_repositories) .insert(user_get_value) .insert(user_get_setting) .insert(user_set_setting); @@ -93,14 +96,16 @@ impl ObjectBackend for DatabaseBackend { match handler .handle( &user, - D::operation_name(), + operation, serde_json::from_value(serialized.clone()).unwrap(), self.clone(), ) .await { - Ok(result) => Ok(serde_json::from_slice(&result) - .map_err(|e| OperationError::Internal(e.to_string()))?), + Ok(result) => Ok( + serde_json::from_slice(&serde_json::to_vec(&result).unwrap()) + .map_err(|e| OperationError::Internal(e.to_string()))?, + ), Err(err) => match err { OperationError::Internal(internal) => Err(OperationError::Internal(internal)), OperationError::Unhandled => Err(OperationError::Unhandled), @@ -121,14 +126,16 @@ impl ObjectBackend for DatabaseBackend { match handler .handle( &repository, - D::operation_name(), + operation, serde_json::from_value(serialized.clone()).unwrap(), self.clone(), ) .await { - Ok(result) => Ok(serde_json::from_slice(&result) - .map_err(|e| OperationError::Internal(e.to_string()))?), + Ok(result) => Ok( + serde_json::from_slice(&serde_json::to_vec(&result).unwrap()) + .map_err(|e| OperationError::Internal(e.to_string()))?, + ), Err(err) => match err { OperationError::Internal(internal) => Err(OperationError::Internal(internal)), OperationError::Unhandled => Err(OperationError::Unhandled), @@ -146,18 +153,34 @@ impl ObjectBackend for DatabaseBackend { if let Ok(object_request) = serde_json::from_value::(serialized.clone()) { - // No-op - let response = serde_json::to_string(&ObjectResponse(object_request.0)).unwrap(); - - info!("Target: {}", type_name::()); - info!("Meow: {}", response); - info!( - "Im just a neko! {:?}", - serde_json::from_str::(&response) - ); - - Ok(serde_json::from_str(&response) - .map_err(|e| OperationError::Internal(e.to_string()))?) + let result = self.get_object::(&object_request.0).await; + + let result = result + .map(|success| serde_json::to_vec(&success.object()).unwrap()) + .map_err(|err| match err { + OperationError::Operation(err) => { + OperationError::Operation(serde_json::to_vec(&err).unwrap()) + } + OperationError::Internal(internal) => OperationError::Internal(internal), + OperationError::Unhandled => OperationError::Unhandled, + }); + + match result { + Ok(result) => Ok( + serde_json::from_slice(&serde_json::to_vec(&result).unwrap()) + .map_err(|e| OperationError::Internal(e.to_string()))?, + ), + Err(err) => match err { + OperationError::Internal(internal) => { + Err(OperationError::Internal(internal)) + } + OperationError::Unhandled => Err(OperationError::Unhandled), + OperationError::Operation(err) => Err(OperationError::Operation( + serde_json::from_slice(&err) + .map_err(|e| OperationError::Internal(e.to_string()))?, + )), + }, + } } else { Err(OperationError::Unhandled) } diff --git a/giterated-models/src/error.rs b/giterated-models/src/error.rs index 62f6c71..b5d111e 100644 --- a/giterated-models/src/error.rs +++ b/giterated-models/src/error.rs @@ -21,7 +21,7 @@ pub enum GetValueError {} pub enum OperationError { #[error("the operation was handled but an error occured")] Operation(#[from] B), - #[error("an internal error occured")] + #[error("an internal error occured: {0}")] Internal(String), #[error("the operation was unhandled or unrecognized")] Unhandled, diff --git a/giterated-models/src/object.rs b/giterated-models/src/object.rs index 785d90d..1b648cb 100644 --- a/giterated-models/src/object.rs +++ b/giterated-models/src/object.rs @@ -38,6 +38,14 @@ impl<'b, B: ObjectBackend + Send + Sync + Clone, O: GiteratedObject> Object<'b, } } +impl Display + for Object<'_, O, B> +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.inner.fmt(f) + } +} + pub trait GiteratedObject: Send + Display + FromStr { fn object_name() -> &'static str; @@ -81,7 +89,7 @@ impl<'b, O: GiteratedObject + Clone + Debug, B: ObjectBackend> Object<'b, O, B> request: R, ) -> Result> { self.backend - .object_operation(self.inner.clone(), request) + .object_operation(self.inner.clone(), R::operation_name(), request) .await } } diff --git a/giterated-models/src/object/operations.rs b/giterated-models/src/object/operations.rs index 5b5605a..3e6aac0 100644 --- a/giterated-models/src/object/operations.rs +++ b/giterated-models/src/object/operations.rs @@ -25,6 +25,7 @@ pub enum ObjectRequestError { } #[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(transparent)] #[repr(transparent)] pub struct AnyObject(pub String); diff --git a/giterated-models/src/object_backend.rs b/giterated-models/src/object_backend.rs index abddbd8..4ae7897 100644 --- a/giterated-models/src/object_backend.rs +++ b/giterated-models/src/object_backend.rs @@ -11,7 +11,8 @@ pub trait ObjectBackend: Send + Sync + Sized + Clone { async fn object_operation( &self, object: O, - operation: D, + operation: &str, + payload: D, ) -> Result> where O: GiteratedObject + Debug, diff --git a/giterated-models/src/repository/mod.rs b/giterated-models/src/repository/mod.rs index 1864a32..ded072a 100644 --- a/giterated-models/src/repository/mod.rs +++ b/giterated-models/src/repository/mod.rs @@ -78,19 +78,13 @@ impl FromStr for Repository { fn from_str(s: &str) -> Result { let mut by_ampersand = s.split('@'); - let mut path_split = by_ampersand - .next() - .ok_or_else(|| RepositoryParseError)? - .split('/'); + let mut path_split = by_ampersand.next().ok_or(RepositoryParseError)?.split('/'); - let instance = Instance::from_str(by_ampersand.next().ok_or_else(|| RepositoryParseError)?) + let instance = Instance::from_str(by_ampersand.next().ok_or(RepositoryParseError)?) .map_err(|_| RepositoryParseError)?; - let owner = User::from_str(path_split.next().ok_or_else(|| RepositoryParseError)?) + let owner = User::from_str(path_split.next().ok_or(RepositoryParseError)?) .map_err(|_| RepositoryParseError)?; - let name = path_split - .next() - .ok_or_else(|| RepositoryParseError)? - .to_string(); + let name = path_split.next().ok_or(RepositoryParseError)?.to_string(); Ok(Self { instance, diff --git a/giterated-models/src/repository/operations.rs b/giterated-models/src/repository/operations.rs index 5a35493..377da45 100644 --- a/giterated-models/src/repository/operations.rs +++ b/giterated-models/src/repository/operations.rs @@ -7,7 +7,7 @@ use crate::{ operation::GiteratedOperation, }; -use super::{IssueLabel, Repository, RepositoryIssue, RepositoryTreeEntry}; +use super::{IssueLabel, Repository, RepositoryIssue, RepositoryTreeEntry, RepositoryView}; /// A request to get a repository's information. /// @@ -19,6 +19,14 @@ use super::{IssueLabel, Repository, RepositoryIssue, RepositoryTreeEntry}; /// - User Authorization /// - Potential User permissions checks #[derive(Clone, Debug, Serialize, Deserialize)] +pub struct RepositoryInfoRequest; + +impl GiteratedOperation for RepositoryInfoRequest { + type Success = RepositoryView; + type Failure = RepositoryError; +} + +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryIssuesCountRequest; impl GiteratedOperation for RepositoryIssuesCountRequest { @@ -80,10 +88,14 @@ impl GiteratedOperation for RepositoryFileInspectRequest { } impl Object<'_, Repository, B> { - pub async fn issues_count(&mut self) -> Result> { - self.request::(RepositoryIssuesCountRequest) + pub async fn info(&mut self) -> Result> { + self.request::(RepositoryInfoRequest) .await } + // pub async fn issues_count(&mut self) -> Result> { + // self.request::(RepositoryIssuesCountRequest) + // .await + // } pub async fn issue_labels( &mut self, diff --git a/giterated-models/src/user/mod.rs b/giterated-models/src/user/mod.rs index 16a0ab3..290510a 100644 --- a/giterated-models/src/user/mod.rs +++ b/giterated-models/src/user/mod.rs @@ -72,11 +72,8 @@ impl FromStr for User { } let mut colon_split = s.split(':'); - let username = colon_split - .next() - .ok_or_else(|| UserParseError)? - .to_string(); - let instance = Instance::from_str(colon_split.next().ok_or_else(|| UserParseError)?) + let username = colon_split.next().ok_or(UserParseError)?.to_string(); + let instance = Instance::from_str(colon_split.next().ok_or(UserParseError)?) .map_err(|_| UserParseError)?; Ok(Self { username, instance }) diff --git a/giterated-models/src/user/operations.rs b/giterated-models/src/user/operations.rs index 6f8bd7d..c81a7ff 100644 --- a/giterated-models/src/user/operations.rs +++ b/giterated-models/src/user/operations.rs @@ -6,7 +6,7 @@ use crate::{ object::Object, object_backend::ObjectBackend, operation::GiteratedOperation, - repository::Repository, + repository::RepositorySummary, }; use super::User; @@ -18,7 +18,7 @@ pub struct UserRepositoriesRequest { } impl GiteratedOperation for UserRepositoriesRequest { - type Success = Vec; + type Success = Vec; type Failure = UserError; } @@ -26,7 +26,7 @@ impl Object<'_, User, B> { pub async fn repositories( &mut self, instance: &Instance, - ) -> Result, OperationError> { + ) -> Result, OperationError> { self.request::(UserRepositoriesRequest { instance: instance.clone(), user: self.inner.clone(), diff --git a/giterated-models/src/user/values.rs b/giterated-models/src/user/values.rs index b83326a..7e47342 100644 --- a/giterated-models/src/user/values.rs +++ b/giterated-models/src/user/values.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use serde::{Deserialize, Serialize}; use crate::value::GiteratedObjectValue; @@ -18,6 +20,12 @@ impl GiteratedObjectValue for Bio { #[derive(Debug, Hash, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct DisplayName(pub String); +impl Display for DisplayName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.0) + } +} + impl GiteratedObjectValue for DisplayName { type Object = User;