From fd93e3dac86e886666197cb52655d9b9c7612e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Ml=C3=A1dek?= Date: Mon, 24 Apr 2023 19:14:42 +0200 Subject: [PATCH] refactor: unify put input handling --- server/src/routes.rs | 101 ++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 53 deletions(-) diff --git a/server/src/routes.rs b/server/src/routes.rs index c29fc6a..c55a793 100644 --- a/server/src/routes.rs +++ b/server/src/routes.rs @@ -324,21 +324,6 @@ pub async fn get_object( }))) } -#[derive(Debug, Clone, Deserialize)] -pub struct InEntry { - pub entity: Option
, - pub attribute: String, - pub value: EntryValue, -} - -#[derive(Debug, Clone, Deserialize)] -#[serde(untagged, deny_unknown_fields)] -pub enum PutInput { - Entry(InEntry), - EntryList(Vec), - Address { entity: InAddress }, -} - #[derive(Debug, Clone, Deserialize)] #[serde(untagged)] pub enum InAddress { @@ -369,6 +354,21 @@ impl TryInto
for InAddress { } } +#[derive(Debug, Clone, Deserialize)] +pub struct InEntry { + pub entity: Option, + pub attribute: String, + pub value: EntryValue, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(untagged, deny_unknown_fields)] +pub enum PutInput { + Entry(InEntry), + EntryList(Vec), + Address { entity: InAddress }, +} + #[derive(Deserialize)] pub struct UpdateQuery { provenance: Option, @@ -390,56 +390,51 @@ pub async fn put_object( debug!("PUTting {in_entry:?}"); + let provenance = query.provenance.clone(); + let process_inentry = move |in_entry: InEntry| -> Result { + if let Some(entity) = in_entry.entity { + Ok(Entry { + entity: entity.try_into()?, + attribute: in_entry.attribute, + value: in_entry.value, + provenance: match &provenance { + Some(s) => format!("API {}", s), + None => "API".to_string(), + }, + timestamp: chrono::Utc::now().naive_utc(), + }) + } else { + Entry::try_from(&InvariantEntry { + attribute: in_entry.attribute, + value: in_entry.value, + }) + } + }; + match in_entry { PutInput::Entry(in_entry) => { - if let Some(entity) = in_entry.entity { - let entry = Entry { - entity, - attribute: in_entry.attribute, - value: in_entry.value, - provenance: match &query.provenance { - Some(s) => format!("API {}", s), - None => "API".to_string(), - }, - timestamp: chrono::Utc::now().naive_utc(), - }; - - Ok(web::block::<_, _, anyhow::Error>(move || { - Ok(( - Some(connection.insert_entry(entry.clone())?), - Some(entry.entity), - )) - }) - .await - .map_err(ErrorInternalServerError)?) - } else { - let invariant = Entry::try_from(&InvariantEntry { - attribute: in_entry.attribute, - value: in_entry.value, - }) - .map_err(ErrorInternalServerError)?; - - Ok(web::block::<_, _, anyhow::Error>(move || { - Ok(( - Some(connection.insert_entry(invariant.clone())?), - Some(invariant.entity), - )) - }) - .await - .map_err(ErrorInternalServerError)?) - } + let entry = process_inentry(in_entry).map_err(ErrorBadRequest)?; + Ok(web::block::<_, _, anyhow::Error>(move || { + Ok(( + Some(connection.insert_entry(entry.clone())?), + Some(entry.entity), + )) + }) + .await + .map_err(ErrorInternalServerError)?) } PutInput::EntryList(entries) => { web::block(move || { connection.transaction::<_, anyhow::Error, _>(|| { for entry in entries { - connection.insert_entry(entry)?; + connection.insert_entry(process_inentry(entry)?)?; } Ok(()) }) }) .await - .map_err(ErrorInternalServerError)?; + .map_err(ErrorBadRequest)?; + Ok((None, None)) } PutInput::Address { entity: in_address } => {