use crate::{Context, Handler}; use actix_web::{post, web, HttpResponse, Responder}; use serde::Deserialize; use serde_json::json; use verax::{RevId, Status, Tag, TokenPayload}; #[derive(Deserialize)] pub struct UpdateOperation { #[serde(default)] pub status: Option, #[serde(default)] pub tags: Option>, pub memo: String, pub update_token: Option, } struct Update { id: RevId, operation: UpdateOperation, } #[async_trait::async_trait] impl Handler for Update { type Ok = verax::Transaction; type Err = verax::Error; async fn handle(self, ledger: &Context) -> Result { let id = self.id; let memo = self.operation.memo; let update_token = self.operation.update_token; let id = if let Some(status) = self.operation.status { let transaction = ledger .ledger .change_status(id, status, memo.clone(), update_token.clone()) .await?; transaction.revision_id } else { id }; let id = if let Some(tags) = self.operation.tags { let transaction = ledger.ledger.set_tags(id, tags, memo, update_token).await?; transaction.revision_id } else { id }; ledger .ledger .get_transactions(verax::Filter { revisions: vec![id], limit: 1, ..Default::default() }) .await? .pop() .ok_or(verax::Error::TxNotFound) } } #[post("/{id}")] async fn handler( info: web::Path, item: web::Json, ctx: web::Data, ) -> impl Responder { let update = Update { id: info.into_inner(), operation: item.into_inner(), }; match update.handle(&ctx).await { Ok(tx) => HttpResponse::Accepted().json(tx), Err(err) => { HttpResponse::InternalServerError().json(json!({ "text": err.to_string(), "err": err})) } } }