0

To check how to use serde_json::to_writer() and serde_json::from_reader() I use a very simple main(), no problem when I just write but a strange error when I add the reader Error: Error("EOF while parsing a value", line: 1, column: 0)

I just start to learn rust ...

use std::collections::HashMap;
use std::error::Error;
use std::fs::OpenOptions;
use std::io::BufReader;

fn main() -> Result<(), Box<dyn Error>> {
    let mut map: HashMap<String, String> = HashMap::new();
    map.insert("foo".to_string(), "bar".to_string());
    map.insert("hello".to_string(), "you".to_string());
    map.insert("to".to_string(), "you".to_string());
    println!("{:?}", map);

    let file = OpenOptions::new()
        .read(true)
        .write(true)
        .truncate(true)
        .open("foo_serde.json")?;
    // why does this work?

    serde_json::to_writer(&file, &map)?;
    let reader = BufReader::new(file);
    let output: HashMap<String, String> = serde_json::from_reader(reader)?;
    println!("{:?}", output);
    Ok(())
}
jfboisvieux
  • 157
  • 1
  • 5

1 Answers1

0

1. This code example does not work out-of-the-box: you're missing create(true) in OpenOptions. Otherwise, it expects the file to already exist.

    let file = OpenOptions::new()
        .create(true)
        .read(true)
        .write(true)
        .truncate(true)
        .open("foo_serde.json")?;

2. You are getting an "end-of-file" error, because files have a "cursor" that indicates what position to read or write at, and after writing, this cursor is at the end of the file. This can be observed by importing std::io::Seek, and executing:

    dbg!(file.stream_position().unwrap());

after you write to the file. The output is: [src/main.rs:22] file.stream_position().unwrap() = 38.

serde understandably fails, as it expects content, but there's nothing left to read past position 38.

To fix this, rewind the file to the start before creating BufReader and passing it to serde:

use std::io::{BufReader, Seek, SeekFrom};
// ...
fn main() -> Result<(), Box<dyn Error>> {
    // ...
    serde_json::to_writer(&file, &map)?;
    file.seek(SeekFrom::Start(0))?;
    let reader = BufReader::new(file);
    // ...
}
justinas
  • 6,287
  • 3
  • 26
  • 36