From 4eb59a01b751e3ade1b11c1772dd9b74cfee5313 Mon Sep 17 00:00:00 2001 From: p11 Date: Wed, 19 Jul 2023 21:10:56 +0200 Subject: [PATCH] Always save comments --- Cargo.lock | 7 ++++ Cargo.toml | 1 + src/main.rs | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 101 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 98f9ca4..e046a8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "data-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "405b47b778683e13f388382bf1fb59e54e1008a2e6d048fb2b63672632863c95" + [[package]] name = "formatting" version = "0.1.0" @@ -78,6 +84,7 @@ dependencies = [ name = "pukram-server" version = "0.1.0" dependencies = [ + "data-stream", "maud", "percent-encoding", "pukram2html", diff --git a/Cargo.toml b/Cargo.toml index 59f9ee2..0757c16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" percent-encoding = "2.3" maud = "0.25.0" pukram2html = { git = "https://gitlab.com/porky11/pukram2html" } +data-stream = "0.2.0" diff --git a/src/main.rs b/src/main.rs index dfdb1fc..703d5ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,10 +2,14 @@ use std::{ collections::{hash_map::Entry, HashMap}, env, fs::File, - io::{prelude::*, BufReader}, + io::{prelude::*, BufReader, Error, ErrorKind, Result}, net::{TcpListener, TcpStream}, }; +use data_stream::{ + collections::SizeSettings, default_settings::PortableSettings, from_stream, to_stream, + FromStream, ToStream, +}; use maud::html; use percent_encoding::percent_decode_str; use pukram2html::{convert, convert_extended, convert_subheader, Settings}; @@ -14,7 +18,12 @@ mod request; use request::Request; fn main() { - let mut context = Context::default(); + let mut context = File::open("context.dat") + .map(|mut file| { + from_stream::(&mut file) + .unwrap_or_else(|_| panic!("Context file corrupted. Delete or repair it!")) + }) + .unwrap_or_default(); let mut args = env::args(); args.next(); let address = args.next().unwrap_or("127.0.0.1:8080".to_string()); @@ -56,6 +65,81 @@ struct Context { infos: HashMap, SiteInfo>, } +impl ToStream for Context { + fn to_stream(&self, stream: &mut W) -> Result<()> { + S::size_to_stream(self.infos.len(), stream)?; + for (key, info) in &self.infos { + let key_bytes = key.as_bytes(); + S::size_to_stream(key_bytes.len(), stream)?; + stream.write_all(key_bytes)?; + + S::size_to_stream(info.comments.len(), stream)?; + for Comment { name, text } in &info.comments { + let name_bytes = name.as_bytes(); + S::size_to_stream(name_bytes.len(), stream)?; + stream.write_all(name_bytes)?; + + let text_bytes = text.as_bytes(); + S::size_to_stream(text_bytes.len(), stream)?; + stream.write_all(text_bytes)?; + } + + S::size_to_stream(info.visits, stream)?; + S::size_to_stream(info.up, stream)?; + S::size_to_stream(info.down, stream)?; + } + + Ok(()) + } +} + +impl FromStream for Context { + fn from_stream(stream: &mut R) -> Result { + let size = S::size_from_stream(stream)?; + let infos = (0..size) + .map(|_| { + let key_bytes = as FromStream>::from_stream(stream)?; + let key = std::str::from_utf8(&key_bytes) + .map_err(|e| Error::new(ErrorKind::InvalidData, e))? + .into(); + + let size = S::size_from_stream(stream)?; + let comments = (0..size) + .map(|_| { + let name_bytes = as FromStream>::from_stream(stream)?; + let name = std::str::from_utf8(&name_bytes) + .map_err(|e| Error::new(ErrorKind::InvalidData, e))? + .into(); + + let text_bytes = as FromStream>::from_stream(stream)?; + let text = std::str::from_utf8(&text_bytes) + .map_err(|e| Error::new(ErrorKind::InvalidData, e))? + .into(); + + Ok(Comment { name, text }) + }) + .collect::>>()?; + + let visits = S::size_from_stream(stream)?; + let up = S::size_from_stream(stream)?; + let down = S::size_from_stream(stream)?; + + Ok(( + key, + SiteInfo { + comments, + visits, + up, + down, + }, + )) + }) + .collect::>>()?; + + Ok(Self { infos }) + } +} + impl Context { fn handle_connection(&mut self, mut stream: TcpStream) { let Some(request) = Request::from(&stream) else { @@ -294,5 +378,12 @@ impl Context { let _ = writeln!(stream, "
"); let _ = writeln!(stream, "<< Back"); + + if let Ok(mut file) = File::create("context.dat") { + if to_stream::(self, &mut file).is_err() { + eprintln!("Error saving data!"); + eprintln!(); + } + } } }