from_reader
получает поток данных откуда-то (где-либо, где реализуется признак чтения) - он не хранит данные, то есть ничто не владеет данными, поэтому вы не можете иметь ссылку на эти данные в своей структуре. Другими словами, from_reader
принимает временный поток данных, поэтому ему необходимо место для хранения данных.
Дополнительным осложнением является то, что serde_yaml
(по крайней мере для версии 0.8.11) не поддержка десериализации нулевой копии:
https://docs.rs/serde_yaml/0.8.11/serde_yaml/fn.from_str.html
pub fn from_str<T>(s: &str) -> Result<T> where
T: DeserializeOwned,
...
В настоящее время YAML не поддерживает нулевую копию десериализация.
Сравните это, скажем, с serde_json
, что:
https://docs.rs/serde_json/1.0.50/serde_json/de/fn.from_str.html
pub fn from_str<'a, T>(s: &'a str) -> Result<T> where
T: Deserialize<'a>,
Итак, по крайней мере, с чем-то вроде serde_json
вы можете использовать from_str
из собственного буфера, и это позволит вам использовать ссылки в вашей структуре (но это не будет работать для serde_yaml
в настоящее время)
// Written with rustc 1.42.0 and
// [dependencies]
// serde = "1.0.105"
// serde_derive = "1.0.105"
// serde_json = "1.0.50"
use std::io::Read;
use serde_derive::Deserialize;
#[derive(Debug, Deserialize)]
pub struct SshConfig<'a> {
username: &'a str,
}
fn main() {
// Open file handle
let mut file = std::fs::File::open("example.json").unwrap();
// Read the data into a String, which stores (and thus owns) the data
let mut strbuf = String::new();
file.read_to_string(&mut strbuf).unwrap();
// Deserialize into struct, which references
let result: SshConfig = serde_json::from_str(&strbuf).unwrap();
println!("{:?}", result.username);
// Note that `result` is only valid as long as `strbuf` exists.
// i.e if `strbuf` goes out of scope or is moved to another function, we get an error. For example, the following would cause an error:
// std::mem::drop(strbuf); // Function which moves strbuf, not a referernce
// println!("{:?}", result.username); // Error
}
В зависимости от того, что именно вас беспокоит, это может быть менее эффективно, чем сохранение строки в вашей структуре (например, если example.json
имеет размер 1 МБ и вы извлекаете только одно поле - приведенный выше код будет хранить всю строку размером 1 МБ в памяти только для того, чтобы текст был доступен на несколько байтов).