## 事象
[[Rocket]]でAPIテスト書く場合、以下のような関数を作る。
```rust
fn test<'a, T: serde::Deserialize<'a> + serde::Serialize>(
url: &str,
body: &'a str,
status_code: u16,
expected: &str,
) {
let rocket = rocket::ignite().mount(
"/",
routes![...],
);
let client = Client::new(rocket).expect("valid rocket instance");
let mut response = client.get(url).body(body).dispatch();
assert_eq!(response.status(), Status::from_code(status_code).unwrap());
let obj: T = serde_json::from_str(response.body_string().unwrap().as_ref()).unwrap();
assert_eq!(expected, serde_json::to_string_pretty(&obj).unwrap());
}
```
エラー。
```
temporary value dropped while borrowed [E0716] creates a temporary value which is freed while still in use
```
## 解決方法
[[ライフタイム]]の書き方を変える。[[高階トレイト境界]]を使う。
```diff
- fn test<'a, T: serde::Deserialize<'a> + serde::Serialize>(
+ fn test<'a, T: for<'de> serde::Deserialize<'de> + serde::Serialize>(
```
関数全体としては以下のようになる。
```rust
fn test<'a, T: for<'de> Deserialize<'de> + serde::Serialize>(
url: &str,
body: &'a str,
status_code: u16,
expected: &str,
) {
let rocket = rocket::ignite().mount(
"/",
routes![...],
);
let client = Client::new(rocket).expect("valid rocket instance");
let mut response = client.get(url).body(body).dispatch();
assert_eq!(response.status(), Status::from_code(status_code).unwrap());
let obj: T = serde_json::from_str(response.body_string().unwrap().as_ref()).unwrap();
assert_eq!(expected, serde_json::to_string_pretty(&obj).unwrap());
}
```
## 参考
- [serde\_json::from\_strでlife timeの問題が出た場合 \- Qiita](https://qiita.com/kzee/items/d01e6f3e00dfadb9a00b)