繁体   English   中英

如何从Rocket端点返回State值?

[英]How to return a State value from a Rocket endpoint?

我将来自外部服务的数据存储在本地缓存中,我想创建一个端点来返回当前缓存中的数据。

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate rocket;

use rocket::{Route, State};
use rocket_contrib::json::Json;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct Post {
    pub title: String,
    pub body: String,
}

impl Post {
    pub fn new(title: String, body: String) -> Post {
        Post { title, body }
    }
}

pub struct Cache {
    pub posts: Vec<Post>,
}

impl Cache {
    pub fn new() -> Cache {
        let mut posts = vec![
            Post::new(String::from("Article1"), String::from("Blah")),
            Post::new(String::from("Article2"), String::from("Blah")),
            Post::new(String::from("Article3"), String::from("Blah")),
            Post::new(String::from("Article4"), String::from("Blah")),
            Post::new(String::from("Article5"), String::from("Blah")),
        ];

        Cache { posts }
    }
}

#[derive(Responder)]
pub enum IndexResponder {
    #[response(status = 200)]
    Found(Json<Vec<Post>>),
    #[response(status = 404)]
    NotFound(String),
}

#[get("/")]
pub fn index(cache: State<Cache>) -> IndexResponder {
    return IndexResponder::Found(Json(cache.posts));
}

fn main() {
    rocket::ignite()
        .mount("/", routes![index])
        .manage(Cache::new())
        .launch();
}

编译器抱怨:

error[E0507]: cannot move out of dereference of `rocket::State<'_, Cache>`
  --> src/main.rs:50:39
   |
50 |     return IndexResponder::Found(Json(cache.posts));
   |                                       ^^^^^^^^^^^ move occurs because value has type `std::vec::Vec<Post>`, which does not implement the `Copy` trait

cargo build --verbose输出

我的Cargo.toml文件:

[package]
name = "debug-project"
version = "0.1.0"
authors = ["Varkal <mail@example.com>"]
edition = "2018"

[dependencies]
rocket = "0.4.0"
rocket_contrib = "0.4.0"
serde = { version = "1.0.90", features = ["derive"] }
serde_json = "1.0.39"

一个非常简单的存储库来重现错误

您的端点不拥有该状态,因此无法返回拥有的Vec<Post> 从概念上讲,这是有道理的,因为如果您确实拥有它,那么下次调用端点时会出现什么值?

您可以做的最简单的事情是克隆数据:

#[get("/")]
pub fn index(cache: State<Cache>) -> IndexResponder {
    IndexResponder::Found(Json(cache.posts.clone()))
}

这将要求您实现Clone for Post ,或者可能更改您的状态以保存类似Arc

性能略高的解决方案是返回引用状态的切片。 这不需要克隆,但需要使用State::inner方法:

#[derive(Responder)]
pub enum IndexResponder<'a> {
    #[response(status = 200)]
    Found(Json<&'a [Post]>),
    #[response(status = 404)]
    NotFound(String),
}

#[get("/")]
pub fn index<'a>(cache: State<'a, Cache>) -> IndexResponder<'a> {
    IndexResponder::Found(Json(&cache.inner().posts))
}

也可以看看:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM