the fastest way to test if to_string()
and to_writer()
returns the same
Look at the source code for to_string
:
let vec = try!(to_vec(value));
let string = unsafe {
// We do not emit invalid UTF-8.
String::from_utf8_unchecked(vec)
};
Ok(string)
Which calls to_vec
:
let mut writer = Vec::with_capacity(128);
try!(to_writer(&mut writer, value));
Ok(writer)
Stuck together, it's almost the same as your code:
let mut writer = Vec::with_capacity(128);
to_writer(&mut writer, value)?;
let string = unsafe {
// We do not emit invalid UTF-8.
String::from_utf8_unchecked(writer)
};
Ok(string)
It is more more efficient, however:
- it pre-allocates some space in the
Vec
- it avoids the
BufWriter
(as
Sven Marnach points out)
- it skips the UTF-8 validity checks
a pull-request for a BufWriter::buffer()
No, you cannot access the buffer of the BufWriter
until that pull request is merged and released — that's part of the reason that it's being added!
written to this writer
It does not seem like you fully understand the purpose of BufWriter
. It buffers data that you write to it, so that the underlying writer doesn't get it. The data in the buffer is data that the underlying writer hasn't seen. The pull request you cite will not help you.
In fact, you need to be sure to flush
the BufWriter
to ensure that no data remains in the buffer before you try to parse the underlying Vec
as a string. Thankfully, into_inner
is already doing that for you.
writer moves here
This is because Serde is following the "C-RW-VALUE" guideline: Generic reader/writer functions take R: Read
and W: Write
by value. You can avoid giving away ownership of the writer by using Write::by_ref
:
#[test]
fn write_to_json_test0() -> Result<(), io::Error> {
let json = Value::Number(42.into());
let buf = Vec::new();
let mut writer = BufWriter::new(buf);
serde_json::to_writer(writer.by_ref(), &json)?;
let s = String::from_utf8(writer.into_inner()?).unwrap();
assert_eq!(s, json.to_string());
Ok(())
}
This works because by_ref
returns a mutable reference to the writer, and there's a blanket implementation of Write
for any mutable reference to a type that itself implements Write
:
impl<'a, W: Write + ?Sized> Write for &'a mut W
by_ref
is just a convenience function to avoid the relatively strange syntax of taking a mutable reference explicitly. This pattern of by_ref
is repeated for Read
as well as Iterator
.
See also: