refactor: unify put input handling

This commit is contained in:
Tomáš Mládek 2023-04-24 19:14:42 +02:00
parent e30cd61c54
commit fd93e3dac8

View file

@ -324,21 +324,6 @@ pub async fn get_object(
}))) })))
} }
#[derive(Debug, Clone, Deserialize)]
pub struct InEntry {
pub entity: Option<Address>,
pub attribute: String,
pub value: EntryValue,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged, deny_unknown_fields)]
pub enum PutInput {
Entry(InEntry),
EntryList(Vec<Entry>),
Address { entity: InAddress },
}
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum InAddress { pub enum InAddress {
@ -369,6 +354,21 @@ impl TryInto<Address> for InAddress {
} }
} }
#[derive(Debug, Clone, Deserialize)]
pub struct InEntry {
pub entity: Option<InAddress>,
pub attribute: String,
pub value: EntryValue,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged, deny_unknown_fields)]
pub enum PutInput {
Entry(InEntry),
EntryList(Vec<InEntry>),
Address { entity: InAddress },
}
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct UpdateQuery { pub struct UpdateQuery {
provenance: Option<String>, provenance: Option<String>,
@ -390,56 +390,51 @@ pub async fn put_object(
debug!("PUTting {in_entry:?}"); debug!("PUTting {in_entry:?}");
let provenance = query.provenance.clone();
let process_inentry = move |in_entry: InEntry| -> Result<Entry> {
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 { match in_entry {
PutInput::Entry(in_entry) => { PutInput::Entry(in_entry) => {
if let Some(entity) = in_entry.entity { let entry = process_inentry(in_entry).map_err(ErrorBadRequest)?;
let entry = Entry { Ok(web::block::<_, _, anyhow::Error>(move || {
entity, Ok((
attribute: in_entry.attribute, Some(connection.insert_entry(entry.clone())?),
value: in_entry.value, Some(entry.entity),
provenance: match &query.provenance { ))
Some(s) => format!("API {}", s), })
None => "API".to_string(), .await
}, .map_err(ErrorInternalServerError)?)
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)?)
}
} }
PutInput::EntryList(entries) => { PutInput::EntryList(entries) => {
web::block(move || { web::block(move || {
connection.transaction::<_, anyhow::Error, _>(|| { connection.transaction::<_, anyhow::Error, _>(|| {
for entry in entries { for entry in entries {
connection.insert_entry(entry)?; connection.insert_entry(process_inentry(entry)?)?;
} }
Ok(()) Ok(())
}) })
}) })
.await .await
.map_err(ErrorInternalServerError)?; .map_err(ErrorBadRequest)?;
Ok((None, None)) Ok((None, None))
} }
PutInput::Address { entity: in_address } => { PutInput::Address { entity: in_address } => {