From cd767f25f8b0488aabd50dd2854b530454ed0c05 Mon Sep 17 00:00:00 2001 From: Yannik_Sc Date: Tue, 26 Nov 2024 09:30:30 +0100 Subject: [PATCH] Improve error reporting, Add some helper functions to implement api methods manually --- rust/src/api.rs | 36 ++++++++++++++++++++++++++++++++++-- rust/src/commit.rs | 6 ++++++ rust/src/config.rs | 10 ++++++---- rust/src/new_object.rs | 26 ++++++++++++++++++++++++-- 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/rust/src/api.rs b/rust/src/api.rs index fded75c7..07723586 100644 --- a/rust/src/api.rs +++ b/rust/src/api.rs @@ -27,6 +27,8 @@ pub struct NewObjectResponse { #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] pub struct CommitResponse { pub status: String, + #[serde(default)] + pub message: Option, } pub async fn query_objects( @@ -55,9 +57,22 @@ pub async fn new_object(servertype: impl Display) -> anyhow::Result anyhow::Result { let config = Config::build_from_environment()?; let response = request_api(COMMIT_ENDPOINT, serde_json::to_value(commit)?, config).await?; - let response = response.error_for_status()?; + let status = response.status(); + let body = response.json::().await?; - Ok(response.json().await?) + if status.is_client_error() || status.is_server_error() { + return Err(anyhow::anyhow!("Unable to process request").context(format!("{:?}", body))); + } + + if body.status == "error" { + return Err(anyhow::anyhow!( + "Error while committing {}", + body.message + .unwrap_or_else(|| String::from("Unknown commit error")) + )); + } + + Ok(body) } pub async fn request_api( @@ -149,6 +164,12 @@ fn calculate_app_id(token: &String) -> String { } impl Server { + pub fn clear(&mut self, attribute: impl ToString) -> anyhow::Result<&mut Self> { + self.attributes.clear(attribute.to_string()); + + Ok(self) + } + pub fn set( &mut self, attribute: impl ToString, @@ -264,6 +285,17 @@ impl Server { set } + + /// Rolls back the changes. + /// + /// Returns the reverted changes + pub fn rollback(&mut self) -> Changeset { + let old_changes = self.changeset(); + + self.changes = Changeset::default(); + + old_changes + } } impl QueryResponse { diff --git a/rust/src/commit.rs b/rust/src/commit.rs index ef33b3c4..0ee0e22a 100644 --- a/rust/src/commit.rs +++ b/rust/src/commit.rs @@ -172,6 +172,12 @@ impl Dataset { Self(Default::default()) } + pub fn clear(&mut self, name: impl ToString) -> &mut Self { + self.0.remove(&name.to_string()); + + self + } + pub fn set( &mut self, name: impl ToString, diff --git a/rust/src/config.rs b/rust/src/config.rs index 6516d487..02542a90 100644 --- a/rust/src/config.rs +++ b/rust/src/config.rs @@ -1,7 +1,6 @@ use std::fmt::{Debug, Formatter}; use std::path::Path; -use std::rc::Rc; -use std::sync::Mutex; +use std::sync::{Arc, Mutex}; use signature::Signer; @@ -24,7 +23,7 @@ pub struct Config { pub enum SshSigner { Agent( Box, - Box>>, + Box>>, ), Key(Box), } @@ -72,7 +71,7 @@ impl Config { return Ok(Some(SshSigner::Agent( Box::new(key), - Box::new(Rc::new(Mutex::new(client))), + Box::new(Arc::new(Mutex::new(client))), ))); } } @@ -120,3 +119,6 @@ impl Signer for SshSigner { } } } + +unsafe impl Send for SshSigner {} +unsafe impl Sync for SshSigner {} diff --git a/rust/src/new_object.rs b/rust/src/new_object.rs index 8278ed7f..f5449b0c 100644 --- a/rust/src/new_object.rs +++ b/rust/src/new_object.rs @@ -1,7 +1,7 @@ use std::ops::{Deref, DerefMut}; use crate::api::{commit_changes, new_object, NewObjectResponse, Server}; -use crate::commit::{AttributeValue, Changeset, Commit}; +use crate::commit::{AttributeValue, Changeset, Commit, Dataset}; use crate::query::Query; #[derive(Clone, Debug)] @@ -12,6 +12,18 @@ pub struct NewObject { } impl NewObject { + pub fn from_dataset(dataset: Dataset) -> Self { + Self { + object_id: None, + server: Server { + object_id: 0, + attributes: dataset, + changes: Default::default(), + }, + deferred_changes: Default::default(), + } + } + pub async fn request_new(servertype: impl ToString) -> anyhow::Result { let servertype = servertype.to_string(); let NewObjectResponse { result } = new_object(&servertype).await?; @@ -31,7 +43,7 @@ impl NewObject { servertype: impl ToString, hostname: impl ToString, ) -> anyhow::Result { - let mut new_object = Self::request_new(servertype).await?; + let mut new_object = Self::request_new(servertype.to_string()).await?; if let Ok(server) = Query::builder() .filter("hostname", hostname.to_string()) @@ -89,6 +101,16 @@ impl NewObject { Ok(server) } + /// + /// Gets the initial commit data and the follow-up commit of deferred changes + /// + pub fn get_commit(self) -> (Commit, Commit) { + ( + Commit::new().create(self.server.attributes), + Commit::new().update(self.deferred_changes), + ) + } + /// /// The deferred method allows you to pre-update the newly created object ///