

actix-webのexampleをダウンロードしてmongodbの機能を確かめていました。  
<https://github.com/actix/examples>  
初めからinsertとfindはありましたが、updateがなかったので自分で実装してテストしてみましたが、うまく動きません。

main関数

[code]

    //! Example code for using MongoDB with Actix.
    mod model;
    #[cfg(test)]
    mod test;
    
    use actix_web::{get, post, web, App, HttpResponse, HttpServer};
    use model::User;
    use mongodb::{bson::doc, options::IndexOptions, Client, Collection, IndexModel};
    use mongodb::options::UpdateOptions;
    
    const DB_NAME: &str = "myApp";
    const COLL_NAME: &str = "users";
    
    /// Adds a new user to the "users" collection in the database.
    #[post("/add_user")]
    async fn add_user(client: web::Data<Client>, form: web::Form<User>) -> HttpResponse {
        let collection = client.database(DB_NAME).collection(COLL_NAME);
        let result = collection.insert_one(form.into_inner(), None).await;
        match result {
            Ok(_) => HttpResponse::Ok().body("user added"),
            Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
        }
    }
    
    /// Gets the user with the supplied username.
    #[get("/get_user/{username}")]
    async fn get_user(client: web::Data<Client>, id: web::Path<String>) -> HttpResponse {
        let id: i32 = id.into_inner().parse::<i32>().unwrap();
        let collection: Collection<User> = client.database(DB_NAME).collection(COLL_NAME);
        match collection
            .find_one(doc! { "id": &id }, None)
            .await
        {
            Ok(Some(user)) => HttpResponse::Ok().json(user),
            Ok(None) => {
                HttpResponse::NotFound().body(format!("No user found with username {id}"))
            }
            Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
        }
        
    }
    /// Change the user with the supplied query and value.
    #[post("/update_user/{filter}/{update}")]
    async fn update_user(
        client: web::Data<Client>,
        filter: web::Path<String>,
        update: web::Path<String>,
    ) -> HttpResponse {
    
    
        println!("1");
        let filter = doc! { "name": filter.into_inner() };
        println!("2");
        let update: mongodb::bson::Document = doc! { "$set": { "last_name": update.into_inner() } };
        println!("3");
    
        let collection: Collection<User> = client.database(DB_NAME).collection(COLL_NAME);
        println!("4");
        let update_options = UpdateOptions::default();
        
        let result = collection.update_one(filter, update, update_options).await;
        println!("{:?}",result);
    
        match result {
            Ok(_) => HttpResponse::Ok().body("User updated"),
            Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
        }
    }
    
    /// Creates an index on the "username" field to force the values to be unique.
    async fn create_username_index(client: &Client) {
        let options = IndexOptions::builder().unique(true).build();
        let model = IndexModel::builder()
            .keys(doc! { "username": 1 })
            .options(options)
            .build();
        client
            .database(DB_NAME)
            .collection::<User>(COLL_NAME)
            .create_index(model, None)
            .await
            .expect("creating an index should succeed");
    }
    
    #[actix_web::main]
    async fn main() -> std::io::Result<()> {
        let uri = std::env::var("MONGODB_URI").unwrap_or_else(|_| "mongodb://localhost:27017".into());
    
        let client = Client::with_uri_str(uri).await.expect("failed to connect");
        create_username_index(&client).await;
    
        HttpServer::new(move || {
            App::new()
                .app_data(web::Data::new(client.clone()))
                .service(add_user)
                .service(get_user)
                .service(update_user)
        })
        .bind(("127.0.0.1", 8080))?
        .run()
        .await
    }
    
[/code]

テスト関数

[code]

    use actix_web::{
        test::{call_and_read_body, call_and_read_body_json, init_service, TestRequest},
        web::Bytes,
    };
    use mongodb::Client;
    //use rand::Rng;
    use chrono::Utc;
    use mongodb::options::UpdateModifications;
    use mongodb::bson::Document;
    
    
    use crate::model::QueryForUpdateValue;
    
    use super::*;
    
    #[actix_web::test]
    //#[ignore = "requires MongoDB instance running"]
    async fn test() {
        let uri = std::env::var("MONGODB_URI").unwrap_or_else(|_| "mongodb://localhost:27017".into());
    
        let client = Client::with_uri_str(uri).await.expect("failed to connect");
    
        // Clear any data currently in the users collection.
        client
            .database(DB_NAME)
            .collection::<User>(COLL_NAME)
            .drop(None)
            .await
            .expect("drop collection should succeed");
    
        let app = init_service(
            App::new()
                .app_data(web::Data::new(client))
                .service(add_user)
                .service(get_user),
        )
        .await;
        
        for i in 0..1{
            let text = Utc::now().format("%Y年%m月%d日 %H時%M分%S秒 %f").to_string();
            let user = User {
                id:i,
                first_name: "Jane".into(),
                last_name: "Doe".into(),
                username: "janedoe".into(),
                email: "example@example.com".into(),
                time:text.into()
            };
    
            let req = TestRequest::post()
                .uri("/add_user")
                .set_form(&user)
                .to_request();
    
            let response = call_and_read_body(&app, req).await;
            assert_eq!(response, Bytes::from_static(b"user added"));
        }
        
        for i in 0..1{
    
        
            let req = TestRequest::get()
                .uri(&format!("/get_user/{}", i))
                .to_request();
    
            let response: User = call_and_read_body_json(&app, req).await;
            println!("{:?}{:?}",response,Utc::now().format("%Y年%m月%d日 %H時%M分%S秒 %f").to_string());
            //assert_eq!(response, user);
        }
        
        let name="Jane".to_string();
        let LastName="ddd".to_string();
    
        let req=TestRequest::post()
            .uri(&format!("/update_user/{}/{}",name,LastName))
            .to_request();
        let responce:String=call_and_read_body_json(&app,req).await;
    }
    
[/code]

エラーメッセージ

[code]

    running 1 test
    User { id: 0, first_name: "Jane", last_name: "Doe", username: "janedoe", email: "example@example.com", time: "2023年10月13日 15時59分14秒 795429800" }"2023年10月13日 15時59分14秒 855553600"
    thread 'test::test' panicked at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\actix-web-4.4.0\src\test\test_utils.rs:328:49:
    called `Result::unwrap()` on an `Err` value: Error("EOF while parsing a value", line: 1, column: 0)
    stack backtrace:
       0: std::panicking::begin_panic_handler
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365/library\std\src\panicking.rs:597
       1: core::panicking::panic_fmt
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365/library\core\src\panicking.rs:72
       2: core::result::unwrap_failed
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365/library\core\src\result.rs:1652
       3: enum2$<core::result::Result<alloc::string::String,alloc::boxed::Box<dyn$<core::error::Error>,alloc::alloc::Global> > >::unwrap<alloc::string::String,alloc::boxed::Box<dyn$<core::error::Error>,alloc::alloc::Global> >
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365\library\core\src\result.rs:1077
       4: actix_web::test::test_utils::call_and_read_body_json::async_fn$0<actix_web::app_service::AppInitService<actix_web::app_service::AppRouting,actix_http::body::boxed::BoxBody>,actix_http::body::boxed::BoxBody,alloc::string::String>
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\actix-web-4.4.0\src\test\test_utils.rs:328
       5: mongodb::test::test::async_block$0
                 at .\src\test.rs:77
       6: tokio::task::local::impl$8::poll::closure$0<enum2$<mongodb::test::test::async_block_env$0> >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\task\local.rs:949
       7: tokio::task::local::impl$2::with::closure$0<enum2$<core::task::poll::Poll<tuple$<> > >,tokio::task::local::impl$8::poll::closure_env$0<enum2$<mongodb::test::test::async_block_env$0> > >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\task\local.rs:686
       8: std::thread::local::LocalKey<tokio::task::local::LocalData>::try_with<tokio::task::local::LocalData,tokio::task::local::impl$2::with::closure_env$0<enum2$<core::task::poll::Poll<tuple$<> > >,tokio::task::local::impl$8::poll::closure_env$0<enum2$<mongodb::
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365\library\std\src\thread\local.rs:270
       9: std::thread::local::LocalKey<tokio::task::local::LocalData>::with<tokio::task::local::LocalData,tokio::task::local::impl$2::with::closure_env$0<enum2$<core::task::poll::Poll<tuple$<> > >,tokio::task::local::impl$8::poll::closure_env$0<enum2$<mongodb::test
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365\library\std\src\thread\local.rs:246
      10: tokio::task::local::LocalSet::with<enum2$<core::task::poll::Poll<tuple$<> > >,tokio::task::local::impl$8::poll::closure_env$0<enum2$<mongodb::test::test::async_block_env$0> > >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\task\local.rs:669
      11: tokio::task::local::impl$8::poll<enum2$<mongodb::test::test::async_block_env$0> >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\task\local.rs:939
      12: tokio::task::local::impl$2::run_until::async_fn$0<enum2$<mongodb::test::test::async_block_env$0> >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\task\local.rs:575
      13: core::future::future::impl$1::poll<ref_mut$<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_block_env$0> > > > >
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365\library\core\src\future\future.rs:125
      14: tokio::runtime::scheduler::current_thread::impl$8::block_on::closure$0::closure$0::closure$0<core::pin::Pin<ref_mut$<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_block_env$0> > > > > >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\current_thread\mod.rs:665  
      15: tokio::runtime::coop::with_budget
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\coop.rs:107
      16: tokio::runtime::coop::budget
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\coop.rs:73
      17: tokio::runtime::scheduler::current_thread::impl$8::block_on::closure$0::closure$0<core::pin::Pin<ref_mut$<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_block_env$0> > > > > >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\current_thread\mod.rs:665  
      18: tokio::runtime::scheduler::current_thread::Context::enter<enum2$<core::task::poll::Poll<tuple$<> > >,tokio::runtime::scheduler::current_thread::impl$8::block_on::closure$0::closure_env$0<core::pin::Pin<ref_mut$<enum2$<tokio::task::local::impl$2::run_until
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\current_thread\mod.rs:410  
      19: tokio::runtime::scheduler::current_thread::impl$8::block_on::closure$0<core::pin::Pin<ref_mut$<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_block_env$0> > > > > >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\current_thread\mod.rs:664  
      20: tokio::runtime::scheduler::current_thread::impl$8::enter::closure$0<tokio::runtime::scheduler::current_thread::impl$8::block_on::closure_env$0<core::pin::Pin<ref_mut$<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test:
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\current_thread\mod.rs:743  
      21: tokio::runtime::context::scoped::Scoped<enum2$<tokio::runtime::scheduler::Context> >::set<enum2$<tokio::runtime::scheduler::Context>,tokio::runtime::scheduler::current_thread::impl$8::enter::closure_env$0<tokio::runtime::scheduler::current_thread::impl$8:
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\context\scoped.rs:40
      22: tokio::runtime::context::set_scheduler::closure$0<tuple$<alloc::boxed::Box<tokio::runtime::scheduler::current_thread::Core,alloc::alloc::Global>,enum2$<core::option::Option<tuple$<> > > >,tokio::runtime::scheduler::current_thread::impl$8::enter::closure_e
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\context.rs:176
      23: std::thread::local::LocalKey<tokio::runtime::context::Context>::try_with<tokio::runtime::context::Context,tokio::runtime::context::set_scheduler::closure_env$0<tuple$<alloc::boxed::Box<tokio::runtime::scheduler::current_thread::Core,alloc::alloc::Global>,
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365\library\std\src\thread\local.rs:270
      24: std::thread::local::LocalKey<tokio::runtime::context::Context>::with<tokio::runtime::context::Context,tokio::runtime::context::set_scheduler::closure_env$0<tuple$<alloc::boxed::Box<tokio::runtime::scheduler::current_thread::Core,alloc::alloc::Global>,enum
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365\library\std\src\thread\local.rs:246
      25: tokio::runtime::context::set_scheduler<tuple$<alloc::boxed::Box<tokio::runtime::scheduler::current_thread::Core,alloc::alloc::Global>,enum2$<core::option::Option<tuple$<> > > >,tokio::runtime::scheduler::current_thread::impl$8::enter::closure_env$0<tokio:
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\context.rs:176
      26: tokio::runtime::scheduler::current_thread::CoreGuard::enter<tokio::runtime::scheduler::current_thread::impl$8::block_on::closure_env$0<core::pin::Pin<ref_mut$<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_b
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\current_thread\mod.rs:743  
      27: tokio::runtime::scheduler::current_thread::CoreGuard::block_on<core::pin::Pin<ref_mut$<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_block_env$0> > > > > >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\current_thread\mod.rs:652  
      28: tokio::runtime::scheduler::current_thread::impl$0::block_on::closure$0<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_block_env$0> > > >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\current_thread\mod.rs:175  
      29: tokio::runtime::context::runtime::enter_runtime<tokio::runtime::scheduler::current_thread::impl$0::block_on::closure_env$0<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_block_env$0> > > >,tuple$<> >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\context\runtime.rs:65
      30: tokio::runtime::scheduler::current_thread::CurrentThread::block_on<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_block_env$0> > > >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\scheduler\current_thread\mod.rs:167  
      31: tokio::runtime::runtime::Runtime::block_on<enum2$<tokio::task::local::impl$2::run_until::async_fn_env$0<enum2$<mongodb::test::test::async_block_env$0> > > >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\runtime\runtime.rs:347
      32: tokio::task::local::LocalSet::block_on<enum2$<mongodb::test::test::async_block_env$0> >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\tokio-1.32.0\src\task\local.rs:536
      33: actix_rt::runtime::Runtime::block_on<enum2$<mongodb::test::test::async_block_env$0> >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\actix-rt-2.9.0\src\runtime.rs:138
      34: actix_rt::system::SystemRunner::block_on<enum2$<mongodb::test::test::async_block_env$0> >
                 at C:\Users\shinj\.cargo\registry\src\index.crates.io-6f17d22bba15001f\actix-rt-2.9.0\src\system.rs:245
      35: mongodb::test::test
                 at .\src\test.rs:16
      36: mongodb::test::test::closure$0
                 at .\src\test.rs:16
      37: core::ops::function::FnOnce::call_once<mongodb::test::test::closure_env$0,tuple$<> >
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365\library\core\src\ops\function.rs:250
      38: core::ops::function::FnOnce::call_once
                 at /rustc/5ae769f06bbe2afc50cde219757a5915e61ba365/library\core\src\ops\function.rs:250
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    test test::test ... FAILED
    
    failures:
    
    failures:
        test::test
    
    test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 41.96s
    
    error: test failed, to rerun pass `-p mongodb --bin mongodb`
    
     *  The terminal process "C:\Users\shinj\.cargo\bin\cargo.exe 'test', '--package', 'mongodb:1.0.0', '--bin', 'mongodb', '--', 'test::test', '--exact', '--nocapture'" terminated with exit code: 101. 
     *  Terminal will be reused by tasks, press any key to close it.
    
[/code]


CC BY-SA 4.0
2023-10-13T16:04:56.097
96489
2023-10-13T23:36:24.877
2023-10-13T23:36:24.877
14101
60106
question
rust mongodb
rustでmongoのドライバーを使用してますがうまくいきません。