update.rs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. use crate::{Context, Handler};
  2. use actix_web::{post, web, HttpResponse, Responder};
  3. use serde::Deserialize;
  4. use serde_json::json;
  5. use verax::{RevId, Status, Tag, TokenPayload};
  6. #[derive(Deserialize)]
  7. pub struct UpdateOperation {
  8. #[serde(default)]
  9. pub status: Option<Status>,
  10. #[serde(default)]
  11. pub tags: Option<Vec<Tag>>,
  12. pub memo: String,
  13. pub update_token: Option<TokenPayload>,
  14. }
  15. struct Update {
  16. id: RevId,
  17. operation: UpdateOperation,
  18. }
  19. #[async_trait::async_trait]
  20. impl Handler for Update {
  21. type Ok = verax::Transaction;
  22. type Err = verax::Error;
  23. async fn handle(self, ledger: &Context) -> Result<Self::Ok, Self::Err> {
  24. let id = self.id;
  25. let memo = self.operation.memo;
  26. let update_token = self.operation.update_token;
  27. let id = if let Some(status) = self.operation.status {
  28. let transaction = ledger
  29. .ledger
  30. .change_status(id, status, memo.clone(), update_token.clone())
  31. .await?;
  32. transaction.revision_id
  33. } else {
  34. id
  35. };
  36. let id = if let Some(tags) = self.operation.tags {
  37. let transaction = ledger.ledger.set_tags(id, tags, memo, update_token).await?;
  38. transaction.revision_id
  39. } else {
  40. id
  41. };
  42. ledger
  43. .ledger
  44. .get_transactions(verax::Filter {
  45. revisions: vec![id],
  46. limit: 1,
  47. ..Default::default()
  48. })
  49. .await?
  50. .pop()
  51. .ok_or(verax::Error::TxNotFound)
  52. }
  53. }
  54. #[post("/{id}")]
  55. async fn handler(
  56. info: web::Path<RevId>,
  57. item: web::Json<UpdateOperation>,
  58. ctx: web::Data<Context>,
  59. ) -> impl Responder {
  60. let update = Update {
  61. id: info.into_inner(),
  62. operation: item.into_inner(),
  63. };
  64. match update.handle(&ctx).await {
  65. Ok(tx) => HttpResponse::Accepted().json(tx),
  66. Err(err) => {
  67. HttpResponse::InternalServerError().json(json!({ "text": err.to_string(), "err": err}))
  68. }
  69. }
  70. }