json
json copied to clipboard
Expose a way to read an io::Read into string and deserialize from the string
https://github.com/SergioBenitez/Rocket/pull/547 wants to do the following two steps but get a single serde_json::Error out, rather than an io::Error and a serde_json::Error.
let mut s = String::new();
data.read_to_string(&mut s)?;
let t = serde_json::from_str(&s)?;
One possible way to expose this would be relaxing the bound on serde_json::from_reader to accept some sealed trait that is implemented for all io::Read as well as for an adapter that indicates eager reading to string (naming tbd).
fn from_reader<R, T>(reader: R) -> Result<T>
where
R: Read2,
T: DeserializeOwned;
trait Read2: Sealed { /* ... */ }
impl<R> Read2 for R where R: io::Read { /* ... */ }
impl<R> Read2 for Adapter<R> where R: io::Read { /* ... */ }
struct Adapter<R>(R);
@dtolnay Extending from_reader like that would be great. Alternatively, you could add a secondary function so that the interface doesn't get so complicated. Two options are:
/// Reads all of `reader` into a `String` then deserialized into `T`.
fn from_reader_eager<R: io::Read, T: DeserializeOwned>(reader: R) -> Result<T>;
/// Reads at most `max` number of bytes into a `String` then deserialized into `T`.
fn from_reader_bounded<R: io::Read, T: DeserializeOwned>(reader: R, max: usize) -> Result<T>;
@dtolnay What do you think?
My feeling is that the use case of not being able to handle an io::Error is not common enough to deserve a top-level serde_json::from_reader_eager function. I would prefer to come up with some other alternatives that are "better hidden".
Can we just use #[doc(hidden)] on the function?
@messense @SergioBenitez to unblock things for Rocket I published from_reader_eager in a separate crate. Once we figure out the right API on the serde_json side we can update that implementation to use it. I invited Sergio as an owner.
@dtolnay Can we just copy that function into Rocket verbatim? Perhaps with a note in serde, similar to the json! macro, that Rocket is using this private method?
Yes that should be fine.