teo_runtime/handler/default/
copy_or_create.rs1use key_path::path;
2use crate::value::Value;
3use crate::teon;
4use crate::response::Response;
5use crate::action::action::*;
6use crate::connection::transaction;
7use crate::request::Request;
8
9pub async fn copy_or_create(request: Request) -> teo_result::Result<Response> {
10 let action = COPY | SINGLE | ENTRY;
11 let value: Value = request.transaction_ctx().run_transaction(move |ctx: transaction::Ctx| {
12 let request = request.clone();
13 let model = request.transaction_ctx().namespace().model_at_path(&request.handler_match().unwrap().path()).unwrap().clone();
14 async move {
15 let include = request.body_value()?.get("include");
16 let select = request.body_value()?.get("select");
17 let object = ctx.find_unique_internal(&model, request.body_value()?, true, action, Some(request.clone()), path![]).await?;
18 match object {
19 Some(object) => {
20 let copy = request.body_value()?.get("copy");
21 let value = object.copied_value();
22 let new = ctx.new_object_with_teon_and_path(&model, &teon!({}), &path![], action, Some(request.clone())).await?;
23 new.update_teon(&value).await?;
24 if let Some(copy) = copy {
25 new.set_teon_with_path(copy, &path!["copy"]).await?;
26 }
27 new.save_with_session_and_path(&path!["copy"]).await?;
28 let refreshed = new.refreshed(include, select).await?;
29 refreshed.to_teon_internal(&path!["data"]).await
30 }
31 None => {
32 let create = request.body_value()?.get("create");
33 let new = ctx.new_object_with_teon_and_path(&model, &teon!({}), &path![], action, Some(request.clone())).await?;
34 if let Some(create) = create {
35 new.set_teon_with_path(create, &path!["create"]).await?;
36 }
37 new.save_with_session_and_path(&path!["create"]).await?;
38 let refreshed = new.refreshed(include, select).await?;
39 refreshed.to_teon_internal(&path!["data"]).await
40 }
41 }
42 }
43 }).await?;
44 Ok(Response::data(value))
45}