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)]
#[serde(untagged)]
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)]
pub struct UpdateQuery {
provenance: Option<String>,
@ -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<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 {
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 } => {