私はserde_jsonのラッパーを書こうとしています& RocketのFromData
は、サーバーと交換するJSON Iの一部を強く入力します。関数のローカル変数が十分に長生きしていません
extern crate serde_json;
extern crate rocket;
extern crate serde;
use serde::ser::Error;
use serde_json::Value;
use rocket::data::DataStream;
use rocket::outcome::IntoOutcome;
use std::io::Read;
static NULL: Value = serde_json::Value::Null;
pub struct ResponseJSON<'v> {
success: bool,
http_code: u16,
data: &'v serde_json::Value,
}
impl<'v> ResponseJSON<'v> {
pub fn ok() -> ResponseJSON<'v> {
ResponseJSON {
success: true,
http_code: 200,
data: &NULL,
}
}
pub fn http_code(mut self, code: u16) -> ResponseJSON<'v> {
self.http_code = code;
self
}
pub fn data(mut self, ref_data: &'v serde_json::Value) -> ResponseJSON<'v> {
self.data = ref_data;
self
}
pub fn from_serde_value(json: &'v serde_json::Value) -> ResponseJSON<'v> {
if !json["success"].is_null() {
ResponseJSON::ok()
.http_code(json["http_code"].as_u64().unwrap() as u16)
.data(json.get("data").unwrap_or(&NULL))
} else {
ResponseJSON::ok()
.data(json.pointer("").unwrap())
}
}
}
impl<'v> rocket::data::FromData for ResponseJSON<'v> {
type Error = serde_json::Error;
fn from_data(request: &rocket::Request, data: rocket::Data) -> rocket::data::Outcome<Self, serde_json::Error> {
if !request.content_type().map_or(false, |ct| ct.is_json()) {
println!("Content-Type is not JSON.");
return rocket::Outcome::Forward(data);
}
let data_from_reader = data.open().take(1<<20);
let value = serde_json::from_reader(data_from_reader);
let unwraped_value : Value = if value.is_ok() { value.unwrap() } else { Value::Null };
if !unwraped_value.is_null() {
Ok(ResponseJSON::from_serde_value(&unwraped_value)).into_outcome()
} else {
Err(serde_json::Error::custom("Unable to create JSON from reader")).into_outcome()
}
}
}
fn main() {
println!("it runs!");
}
コンパイラのエラー:私は次のコードをコンパイルすることはできません
data_from_reader
以来
Compiling tests v0.1.0 (file:///Users/bgbahoue/Projects.nosync/tests)
error: `unwraped_value` does not live long enough
--> src/main.rs:64:48
|
64 | Ok(ResponseJSON::from_serde_value(&unwraped_value)).into_outcome()
| ^^^^^^^^^^^^^^ does not live long enough
...
68 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'v as defined on the body at 53:114...
--> src/main.rs:53:115
|
53 | fn from_data(request: &rocket::Request, data: rocket::Data) -> rocket::data::Outcome<Self, serde_json::Error> {
| ___________________________________________________________________________________________________________________^
54 | | if !request.content_type().map_or(false, |ct| ct.is_json()) {
55 | | println!("Content-Type is not JSON.");
56 | | return rocket::Outcome::Forward(data);
... |
67 | | }
68 | | }
| |_____^
error: aborting due to previous error
を、value
とunwraped_value
がdata
から来た私は、コンパイラはそれがあったことを推測することができると思いました同じ生涯が、明らかにそうではありません。そのような場合には、私がそれを述べたり、何かすることができる方法はありますか?
pub fn from_reader<R, T>(rdr: R) -> Result<T>
where
R: Read,
T: DeserializeOwned,
fn open(self) -> DataStream
rocket::data::DataStream::take
:上記@LukasKalbertodtのコメントを1として
fn take(self, limit: u64) -> Take<Self>
について自分の考えを大好きだ、私のexplainationの100%を確認してくださいしかし、あなたの問題は、おそらくに沸く:[機能で作成した変数への参照を返すためにどのような方法がありますか?](HTTP ://stackoverflow.com/questions/32682876/is-there-any-way-to-return-a-reference-to-a-variable-created-in-a-function/32683309#32683309)答えは次のとおりです基本的にはありません。あなたの 'ResponseJson'はそれを借りる代わりに' serde_json :: Value'を所有する必要があります。あなたが時々借りたい、時にはそれを所有している場合は、['Cow'](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html)に興味があるかもしれません。 –
@LukasKalbertodtそこに行く。最初の行が見つかりません。 Trait(その場合はFormData)を実装するために、関数で作成された変数への参照を返すことに変わりはありません。変わったのは、私が基本的に新しく作成したResponseJSONを返すので、 'from_serde_value(&Value)'関数でそれを処理できることです。'from_data()'関数の場合にはあまり変わらないと思っていました – Boris
@LukasKalbertodtの提案によれば、ResponseJSONが 'serde_json :: Value'を所有していればコンパイルされます(構造体定義と関数シグネチャの中のすべての参照を削除します)。ディスカッション/アーカイブのための答えとしてそれを追加する – Boris