Siriusmart
Siriusmart

Reputation: 197

Cannot write file without appending to it

I am trying to write to a json file but it kepts appending to the files instead of overwriting it, even when I set append to false

What did i do wrong? thx

use serde::{Deserialize, Serialize};
use serde_json::{json, Map, Value};
use sha2::{Digest, Sha256};
use std::{error::Error, fs::{OpenOptions}, io::prelude::*};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Session {
    username: String,
    hashed_ip: String,
    session_id: String,
    expires_at: u64,
}

impl Session {
    pub fn add(&self) -> Result<(), Box<dyn Error>> {
        let session_path = "./storage/sessions/current_sessions.json";
        let mut file = OpenOptions::new()
            .write(true)
            .read(true)
            .append(false)
            .open(session_path)?;
        let mut file_content = String::new();
        file.read_to_string(&mut file_content)?;
        let sessions_value = serde_json::from_str(&file_content)?;
        let mut sessions;
        if let Value::Object(map) = sessions_value {
            sessions = map;
        } else {
            sessions = Map::new();
        }
        let clean = SessionClean::from_session(self);
        sessions.insert(self.session_id.clone(), serde_json::to_value(clean)?);
        println!("{}", Value::Object(sessions.clone()).to_string());
        file.write_all(Value::Object(sessions.clone()).to_string().as_str().as_bytes())?;
        file.flush()?;
        Ok(())
    }
}

Expected result be:

{"some_session_id":{"expires_at":1646583038,"hashed_ip":"1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d","username":"Someone"}}

Instead this happened:

{}{"some_session_id":{"expires_at":1646583038,"hashed_ip":"1ea442a134b2a184bd5d40104401f2a37fbc09ccf3f4bc9da161c6099be3691d","username":"Someone"}}

heres the whole code: https://github.com/Siriusmart/siribot-registry

Upvotes: 2

Views: 988

Answers (1)

Netwave
Netwave

Reputation: 42756

You are reading the file before writing it. That makes the cursor to be located at the end of the file. You would have to set it to the initial position before writing. For example using Seek::rewind

Example from the documentation:

use std::io::{Read, Seek, Write};
use std::fs::OpenOptions;

let mut f = OpenOptions::new()
    .write(true)
    .read(true)
    .create(true)
    .open("foo.txt").unwrap();

let hello = "Hello!\n";
write!(f, "{}", hello).unwrap();
f.rewind().unwrap();

let mut buf = String::new();
f.read_to_string(&mut buf).unwrap();
assert_eq!(&buf, hello);

Upvotes: 3

Related Questions