move to rocket + refactor
This commit is contained in:
parent
b0e80dd3e8
commit
b8caa43972
11 changed files with 686 additions and 886 deletions
1258
Cargo.lock
generated
1258
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -4,18 +4,16 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
actix-web = "4.4.1"
|
||||
chrono = "0.4.38"
|
||||
env_logger = "0.10.1"
|
||||
futures = "0.3.30"
|
||||
log = "0.4.20"
|
||||
maud = "0.25.0"
|
||||
mdq = { git = "https://git.hydrar.de/mdtools/mdq", version = "0.3.0" }
|
||||
mdq = { git = "https://git.hydrar.de/mdtools/mdq" }
|
||||
mongodb = "2.8.0"
|
||||
rocket = { version = "0.5.1", features = ["json"] }
|
||||
rocket_cors = "0.6.0"
|
||||
serde = { version = "1.0.195", features = ["derive"] }
|
||||
serde_json = "1.0.111"
|
||||
serde_yaml = "0.9.34"
|
||||
tokio = { version = "1.35.1", features = ["full"] }
|
||||
toml = "0.8.8"
|
||||
uuid = { version = "1.8.0", features = ["v4"] }
|
||||
web-base = "0.2.2"
|
||||
|
|
3
rocket.toml
Normal file
3
rocket.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
[default]
|
||||
address = "0.0.0.0"
|
||||
port = 8080
|
|
@ -1,4 +1,4 @@
|
|||
use mongodb::{bson::doc, ClientSession};
|
||||
use mongodb::bson::doc;
|
||||
|
||||
use crate::get_mongo;
|
||||
|
||||
|
@ -16,8 +16,7 @@ impl InventoryCache {
|
|||
.return_document(mongodb::options::ReturnDocument::After)
|
||||
.build();
|
||||
|
||||
let result = db
|
||||
.database("cdb")
|
||||
db.database("cdb")
|
||||
.collection::<mongodb::bson::Document>("cache")
|
||||
.find_one_and_update(doc! { "_id": "inventory"}, update, options)
|
||||
.await
|
||||
|
@ -51,8 +50,7 @@ impl InventoryCache {
|
|||
.return_document(mongodb::options::ReturnDocument::After)
|
||||
.build();
|
||||
|
||||
let result = db
|
||||
.database("cdb")
|
||||
db.database("cdb")
|
||||
.collection::<mongodb::bson::Document>("cache")
|
||||
.find_one_and_update(doc! { "_id": "inventory"}, update, options)
|
||||
.await
|
||||
|
|
|
@ -49,7 +49,7 @@ impl ItemDB {
|
|||
let mongodb = get_mongo!();
|
||||
|
||||
for item in &index.documents {
|
||||
let item = ItemEntry::new(item.clone());
|
||||
let item = ItemEntry::new(item);
|
||||
item.init_db(&mongodb).await;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ impl ItemDB {
|
|||
self.index
|
||||
.documents
|
||||
.iter()
|
||||
.map(|x| ItemEntry::new(x.clone()))
|
||||
.map(ItemEntry::new)
|
||||
.find(|x| x.name == item)?,
|
||||
))
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ impl ItemDB {
|
|||
pub fn items(&self) -> Vec<String> {
|
||||
let mut ret = vec![];
|
||||
for item in &self.index.documents {
|
||||
let item = ItemEntry::new(item.clone());
|
||||
let item = ItemEntry::new(item);
|
||||
ret.push(item.name);
|
||||
}
|
||||
ret
|
||||
|
|
17
src/item.rs
17
src/item.rs
|
@ -32,7 +32,7 @@ pub struct ItemEntry {
|
|||
}
|
||||
|
||||
impl ItemEntry {
|
||||
pub fn new(doc: mdq::Document) -> Self {
|
||||
pub fn new(doc: &mdq::Document) -> Self {
|
||||
let name = std::path::Path::new(&doc.path)
|
||||
.file_stem()
|
||||
.unwrap()
|
||||
|
@ -56,13 +56,12 @@ impl ItemEntry {
|
|||
.as_mapping()
|
||||
.unwrap()
|
||||
.get("variants")
|
||||
.unwrap()
|
||||
.as_mapping()
|
||||
.unwrap()
|
||||
.map(|x| x.as_mapping().unwrap().clone())
|
||||
.unwrap_or_default()
|
||||
{
|
||||
variants.insert(
|
||||
variant_name.as_str().unwrap().to_string(),
|
||||
Variant::from_yml(variant, variant_name.as_str().unwrap(), &name),
|
||||
Variant::from_yml(&variant, variant_name.as_str().unwrap(), &name),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -111,15 +110,15 @@ pub struct Item {
|
|||
}
|
||||
|
||||
impl Item {
|
||||
pub fn new(item: ItemEntry) -> Self {
|
||||
pub const fn new(item: ItemEntry) -> Self {
|
||||
Self { item }
|
||||
}
|
||||
|
||||
pub async fn get_variants(&self) -> Vec<String> {
|
||||
pub fn get_variants(&self) -> Vec<String> {
|
||||
self.item.variants.keys().cloned().collect()
|
||||
}
|
||||
|
||||
pub async fn variant(&self, variant: &str) -> Option<Variant> {
|
||||
self.item.variants.get(variant).map(|x| x.clone())
|
||||
pub fn variant(&self, variant: &str) -> Option<Variant> {
|
||||
self.item.variants.get(variant).cloned()
|
||||
}
|
||||
}
|
||||
|
|
55
src/main.rs
55
src/main.rs
|
@ -1,4 +1,5 @@
|
|||
use actix_web::{get, HttpRequest, Responder};
|
||||
use rocket::routes as route;
|
||||
use rocket::{http::Method, launch};
|
||||
|
||||
mod cache;
|
||||
mod db;
|
||||
|
@ -22,31 +23,35 @@ mod variant;
|
|||
// ░████▀░░░▀▀█████▄▄▄▄█████████▄░░
|
||||
// ░░▀▀░░░░░░░░░▀▀██████▀▀░░░▀▀██░░
|
||||
|
||||
#[get("/")]
|
||||
pub(crate) async fn index(r: HttpRequest) -> impl Responder {
|
||||
let itemdb: &actix_web::web::Data<db::ItemDB> = r.app_data().unwrap();
|
||||
let content = "";
|
||||
web_base::func::build_site(&r, "Index", &content)
|
||||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
env_logger::init();
|
||||
#[launch]
|
||||
async fn rocket() -> _ {
|
||||
let cors = rocket_cors::CorsOptions {
|
||||
allowed_origins: rocket_cors::AllowedOrigins::all(),
|
||||
allowed_methods: vec![Method::Get, Method::Post, Method::Options]
|
||||
.into_iter()
|
||||
.map(From::from)
|
||||
.collect(),
|
||||
allowed_headers: rocket_cors::AllowedHeaders::all(),
|
||||
allow_credentials: true,
|
||||
..Default::default()
|
||||
}
|
||||
.to_cors()
|
||||
.expect("error creating CORS options");
|
||||
|
||||
let itemdb = db::ItemDB::new("./itemdb").await;
|
||||
let itemdb = actix_web::web::Data::new(itemdb);
|
||||
|
||||
web_base::map!(web_base::Site::new(), |app: actix_web::App<_>| {
|
||||
app.app_data(itemdb.clone())
|
||||
.service(index)
|
||||
.service(routes::item::supply_route) // /supply
|
||||
.service(routes::item::item_variants_page) // /item/{item_id}/variants
|
||||
.service(routes::item::get_items_route) // /items
|
||||
.service(routes::item::demand_route) // /demand
|
||||
.service(routes::item::supply_log_route) // /item/{item_id}/{variant_id}/supply
|
||||
.service(routes::item::demand_log_route) // /item/{item_id}/{variant_id}/demand
|
||||
})
|
||||
.bind(("0.0.0.0".to_string(), 8080))?
|
||||
.run()
|
||||
.await
|
||||
rocket::build()
|
||||
.mount(
|
||||
"/",
|
||||
route![
|
||||
routes::item::get_items_route,
|
||||
routes::item::item_variants_page,
|
||||
routes::item::supply_log_route,
|
||||
routes::item::demand_log_route,
|
||||
routes::item::supply_route,
|
||||
routes::item::demand_route,
|
||||
],
|
||||
)
|
||||
.manage(itemdb)
|
||||
.attach(cors)
|
||||
}
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
use actix_web::post;
|
||||
use actix_web::{get, HttpRequest, HttpResponse, Responder};
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use rocket::{get, post};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::item;
|
||||
use crate::routes::bad_req;
|
||||
use crate::db::ItemDB;
|
||||
use crate::variant::Variant;
|
||||
|
||||
macro_rules! get_itemdb {
|
||||
($req:expr) => {{
|
||||
let itemdb: &actix_web::web::Data<crate::db::ItemDB> = $req.app_data().unwrap();
|
||||
itemdb
|
||||
}};
|
||||
use super::{api_error, ApiError, FallibleApiResponse};
|
||||
|
||||
pub fn item_does_not_exist_error() -> ApiError {
|
||||
api_error("The item does not exist")
|
||||
}
|
||||
|
||||
pub fn item_does_not_exist_error() -> actix_web::Error {
|
||||
bad_req("The item does not exist")
|
||||
}
|
||||
|
||||
pub fn variant_does_not_exist_error() -> actix_web::Error {
|
||||
bad_req("The item does not exist")
|
||||
pub fn variant_does_not_exist_error() -> ApiError {
|
||||
api_error("The item does not exist")
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -28,24 +24,20 @@ pub struct DemandForm {
|
|||
price: String,
|
||||
}
|
||||
|
||||
#[post("/demand")]
|
||||
pub async fn demand_route(
|
||||
req: HttpRequest,
|
||||
f: actix_web::web::Form<DemandForm>,
|
||||
) -> actix_web::Result<impl Responder> {
|
||||
let itemdb = get_itemdb!(req);
|
||||
#[post("/demand", data = "<f>")]
|
||||
pub async fn demand_route(f: Json<DemandForm>) -> FallibleApiResponse {
|
||||
let uuid = Variant::demand(
|
||||
&f.uuid,
|
||||
f.price
|
||||
.clone()
|
||||
.try_into()
|
||||
.map_err(|_| bad_req("Price malformed"))?,
|
||||
.map_err(|()| api_error("Price malformed"))?,
|
||||
&f.destination,
|
||||
)
|
||||
.await
|
||||
.ok_or_else(|| bad_req("Demand failed"))?;
|
||||
.ok_or_else(|| api_error("Demand failed"))?;
|
||||
|
||||
Ok(actix_web::HttpResponse::Ok().json(serde_json::json!({"uuid": uuid})))
|
||||
Ok(json!({"uuid": uuid}))
|
||||
}
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct SupplyForm {
|
||||
|
@ -56,18 +48,13 @@ pub struct SupplyForm {
|
|||
origin: String,
|
||||
}
|
||||
|
||||
#[post("/supply")]
|
||||
pub async fn supply_route(
|
||||
req: HttpRequest,
|
||||
form: actix_web::web::Form<SupplyForm>,
|
||||
) -> actix_web::Result<impl Responder> {
|
||||
let itemdb = get_itemdb!(req);
|
||||
#[post("/supply", data = "<form>")]
|
||||
pub async fn supply_route(form: Json<SupplyForm>, itemdb: &State<ItemDB>) -> FallibleApiResponse {
|
||||
println!("{form:?}");
|
||||
let variant = itemdb
|
||||
.get_item(&form.item)
|
||||
.ok_or_else(item_does_not_exist_error)?
|
||||
.variant(&form.variant)
|
||||
.await
|
||||
.ok_or_else(variant_does_not_exist_error)?;
|
||||
|
||||
let transaction_id = variant
|
||||
|
@ -76,72 +63,63 @@ pub async fn supply_route(
|
|||
form.price
|
||||
.clone()
|
||||
.try_into()
|
||||
.map_err(|_| bad_req("Price malformed"))?,
|
||||
.map_err(|()| api_error("Price malformed"))?,
|
||||
&form.origin,
|
||||
)
|
||||
.await;
|
||||
|
||||
Ok(actix_web::HttpResponse::Ok().json(serde_json::json!({"uuid": transaction_id})))
|
||||
Ok(json!({"uuid": transaction_id}))
|
||||
}
|
||||
|
||||
#[get("/items")]
|
||||
pub async fn get_items_route(r: HttpRequest) -> impl Responder {
|
||||
let itemdb = get_itemdb!(r);
|
||||
pub fn get_items_route(itemdb: &State<ItemDB>) -> serde_json::Value {
|
||||
let items = itemdb.items();
|
||||
actix_web::HttpResponse::Ok().json(serde_json::json!({"items": items}))
|
||||
json!({"items": items})
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct AddVariantForm {
|
||||
pub variant: String,
|
||||
pub amount: usize,
|
||||
}
|
||||
#[get("/item/<item_id>/variants")]
|
||||
pub fn item_variants_page(item_id: &str, itemdb: &State<ItemDB>) -> FallibleApiResponse {
|
||||
let item = itemdb
|
||||
.get_item(item_id)
|
||||
.ok_or_else(item_does_not_exist_error)?;
|
||||
let variants = item.get_variants();
|
||||
|
||||
#[get("/item/{item_id}/variants")]
|
||||
pub async fn item_variants_page(r: HttpRequest) -> actix_web::Result<impl Responder> {
|
||||
let id = r.match_info().query("item_id");
|
||||
let itemdb = get_itemdb!(r);
|
||||
let item = itemdb.get_item(id).ok_or_else(item_does_not_exist_error)?;
|
||||
let variants = item.get_variants().await;
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({
|
||||
"item": id,
|
||||
Ok(json!({
|
||||
"item": item_id,
|
||||
"variants": variants
|
||||
})))
|
||||
}))
|
||||
}
|
||||
|
||||
#[get("/item/{item_id}/{variant_id}/supply")]
|
||||
pub async fn supply_log_route(r: HttpRequest) -> actix_web::Result<impl Responder> {
|
||||
let itemdb = get_itemdb!(r);
|
||||
let item_id = r.match_info().query("item_id");
|
||||
let variant_id = r.match_info().query("variant_id");
|
||||
|
||||
#[get("/item/<item_id>/<variant_id>/supply")]
|
||||
pub async fn supply_log_route(
|
||||
item_id: &str,
|
||||
variant_id: &str,
|
||||
itemdb: &State<ItemDB>,
|
||||
) -> FallibleApiResponse {
|
||||
let variant = itemdb
|
||||
.get_item(item_id)
|
||||
.ok_or_else(item_does_not_exist_error)?
|
||||
.variant(variant_id)
|
||||
.await
|
||||
.ok_or_else(variant_does_not_exist_error)?;
|
||||
|
||||
let transactions = variant.supply_log().await;
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!(transactions)))
|
||||
Ok(json!(transactions))
|
||||
}
|
||||
|
||||
#[get("/item/{item_id}/{variant_id}/demand")]
|
||||
pub async fn demand_log_route(r: HttpRequest) -> actix_web::Result<impl Responder> {
|
||||
let itemdb = get_itemdb!(r);
|
||||
let item_id = r.match_info().query("item_id");
|
||||
let variant_id = r.match_info().query("variant_id");
|
||||
|
||||
#[get("/item/<item_id>/<variant_id>/demand")]
|
||||
pub async fn demand_log_route(
|
||||
item_id: &str,
|
||||
variant_id: &str,
|
||||
itemdb: &State<ItemDB>,
|
||||
) -> FallibleApiResponse {
|
||||
let variant = itemdb
|
||||
.get_item(item_id)
|
||||
.ok_or_else(item_does_not_exist_error)?
|
||||
.variant(variant_id)
|
||||
.await
|
||||
.ok_or_else(variant_does_not_exist_error)?;
|
||||
|
||||
let transactions = variant.demand_log().await;
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!(transactions)))
|
||||
Ok(json!(transactions))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
use rocket::response::status::BadRequest;
|
||||
use serde_json::json;
|
||||
|
||||
pub mod item;
|
||||
|
||||
pub fn bad_req(msg: &'static str) -> actix_web::Error {
|
||||
actix_web::error::ErrorBadRequest(msg)
|
||||
type ApiError = BadRequest<serde_json::Value>;
|
||||
type FallibleApiResponse = Result<serde_json::Value, ApiError>;
|
||||
|
||||
fn api_error(msg: &str) -> ApiError {
|
||||
BadRequest(json!({
|
||||
"error": msg
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@ pub enum TransactionType {
|
|||
Normal(Transaction),
|
||||
}
|
||||
|
||||
impl TransactionType {
|
||||
pub fn from(b: mongodb::bson::Document) -> Self {
|
||||
if let Ok(kind) = b.get_str("kind") {
|
||||
impl From<mongodb::bson::Document> for TransactionType {
|
||||
fn from(value: mongodb::bson::Document) -> Self {
|
||||
if let Ok(kind) = value.get_str("kind") {
|
||||
if kind == "batch" {
|
||||
return Self::Batch(BatchTransaction::from(b));
|
||||
return Self::Batch(value.into());
|
||||
}
|
||||
}
|
||||
Self::Normal(Transaction::from(b))
|
||||
Self::Normal(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,12 +40,14 @@ impl Transaction {
|
|||
"_id": &self.uuid,
|
||||
"item": &self.item,
|
||||
"variant": &self.variant,
|
||||
"price": self.price.as_bson(),
|
||||
"price": Into::<mongodb::bson::Bson>::into(self.price.clone()),
|
||||
"origin": &self.origin,
|
||||
"timestamp": self.timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<mongodb::bson::Document> for Transaction {
|
||||
fn from(b: mongodb::bson::Document) -> Self {
|
||||
let uuid = b.get_str("oid").unwrap().to_string();
|
||||
let item = b.get_str("item").unwrap().to_string();
|
||||
|
@ -64,6 +66,19 @@ impl Transaction {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Transaction> for mongodb::bson::Document {
|
||||
fn from(value: Transaction) -> Self {
|
||||
mongodb::bson::doc! {
|
||||
"_id": &value.uuid,
|
||||
"item": &value.item,
|
||||
"variant": &value.variant,
|
||||
"price": Into::<mongodb::bson::Bson>::into(value.price),
|
||||
"origin": &value.origin,
|
||||
"timestamp": value.timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BatchTransaction {
|
||||
pub uuid: String,
|
||||
pub transactions: Vec<String>,
|
||||
|
@ -76,27 +91,32 @@ impl BatchTransaction {
|
|||
transactions,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_doc(&self) -> mongodb::bson::Document {
|
||||
mongodb::bson::doc! {
|
||||
"_id": &self.uuid,
|
||||
"kind": "batch",
|
||||
"transactions": &self.transactions
|
||||
}
|
||||
}
|
||||
|
||||
fn from(b: mongodb::bson::Document) -> Self {
|
||||
let uuid = b.get_str("_id").unwrap().to_string();
|
||||
let transactions = b
|
||||
impl From<mongodb::bson::Document> for BatchTransaction {
|
||||
fn from(value: mongodb::bson::Document) -> Self {
|
||||
let uuid = value.get_str("_id").unwrap().to_string();
|
||||
let transactions = value
|
||||
.get_array("transactions")
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.iter()
|
||||
.map(|x| x.as_str().unwrap().to_string())
|
||||
.collect();
|
||||
|
||||
Self { uuid, transactions }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BatchTransaction> for mongodb::bson::Document {
|
||||
fn from(value: BatchTransaction) -> Self {
|
||||
mongodb::bson::doc! {
|
||||
"_id": value.uuid,
|
||||
"kind": "batch",
|
||||
"transactions": value.transactions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Price {
|
||||
pub value: f64,
|
||||
|
@ -119,11 +139,13 @@ impl Price {
|
|||
currency: currency.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_bson(&self) -> mongodb::bson::Bson {
|
||||
impl From<Price> for mongodb::bson::Bson {
|
||||
fn from(value: Price) -> Self {
|
||||
mongodb::bson::bson!({
|
||||
"value": self.value,
|
||||
"currency": self.currency.clone()
|
||||
"value": value.value,
|
||||
"currency": value.currency
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,7 @@ impl Variant {
|
|||
.as_mapping()
|
||||
.unwrap()
|
||||
.get("amount")
|
||||
.map(|x| x.as_u64().unwrap())
|
||||
.unwrap_or(1),
|
||||
.map_or(1, |x| x.as_u64().unwrap()),
|
||||
depends: json
|
||||
.as_mapping()
|
||||
.unwrap()
|
||||
|
@ -43,11 +42,11 @@ impl Variant {
|
|||
.map(|x| {
|
||||
x.as_sequence()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.iter()
|
||||
.map(|x| x.as_str().unwrap().to_string())
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or(Vec::new()),
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,14 +103,10 @@ impl Variant {
|
|||
|
||||
// check if supply transaction exists
|
||||
let supply_t = cdb_col!(db, "supply");
|
||||
if supply_t
|
||||
.find_one(doc! { "_id": uuid }, None)
|
||||
supply_t
|
||||
.find_one(doc! { "_id": uuid}, None)
|
||||
.await
|
||||
.unwrap()
|
||||
.is_none()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
.unwrap()?;
|
||||
|
||||
// todo : demand batch
|
||||
|
||||
|
@ -122,7 +117,7 @@ impl Variant {
|
|||
doc! {
|
||||
"_id": uuid,
|
||||
"destination": destination,
|
||||
"price": price.as_bson()
|
||||
"price": Into::<mongodb::bson::Bson>::into(price)
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -163,7 +158,7 @@ impl Variant {
|
|||
}
|
||||
|
||||
for transaction in &transactions {
|
||||
let r = col.insert_one(transaction.as_doc(), None).await.unwrap();
|
||||
col.insert_one(transaction.as_doc(), None).await.unwrap();
|
||||
|
||||
// update cache
|
||||
InventoryCache::push(&transaction.uuid).await;
|
||||
|
@ -177,8 +172,12 @@ impl Variant {
|
|||
BatchTransaction::new(transactions.iter().map(|x| x.uuid.clone()).collect());
|
||||
let col: mongodb::Collection<mongodb::bson::Document> =
|
||||
db.database("cdb").collection("transactions_batch");
|
||||
col.insert_one(batch.as_doc(), None).await.unwrap();
|
||||
batch.uuid
|
||||
let batch_uuid = batch.uuid.clone();
|
||||
|
||||
col.insert_one(Into::<mongodb::bson::Document>::into(batch), None)
|
||||
.await
|
||||
.unwrap();
|
||||
batch_uuid
|
||||
};
|
||||
|
||||
ret_uuid
|
||||
|
|
Loading…
Reference in a new issue