Browse Source

write some code

xenua 2 years ago
parent
commit
b133eb4b0a
  1. 120
      src/main.rs

120
src/main.rs

@ -1,7 +1,6 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
ffi::OsString, fs::{read_to_string, DirBuilder, File},
fs::{DirBuilder, File},
io::{self, BufRead}, io::{self, BufRead},
net::SocketAddr, net::SocketAddr,
path::PathBuf, path::PathBuf,
@ -43,21 +42,70 @@ pub enum Error {
Metadata, Metadata,
#[error("some shit missing: {0}")] #[error("some shit missing: {0}")]
ShitMissing(String), ShitMissing(String),
#[error("filesystem error")]
FS,
} }
struct TextPaste { struct TextPaste {
pub text: String, pub text: String,
pub meta: HashMap<String, String>, pub meta: TextMeta,
}
struct TextMeta {
language: Option<String>,
}
impl TextMeta {
pub fn parse(from: &str) -> Result<Self, Error> {
let mut map = HashMap::new();
from.lines()
.map(|line| line.trim())
.filter(|line| line.len() > 0)
.map(|line| {
line.split_once(": ")
.ok_or(Error::Metadata)
.map(|(k, v)| map.insert(k.to_string(), v.to_string()))
});
// meh, this prolly doesnt perform well but idc its only init code
Ok(Self {
language: map.remove("language"),
})
}
} }
struct FileMeta { struct FileMeta {
file_name: String, file_name: String,
} }
impl FileMeta {
pub fn parse(from: &str) -> Result<Self, Error> {
let map = from
.lines()
.map(|line| line.trim())
.filter(|line| line.len() > 0)
.map(|line| line.split_once(": ").ok_or(Error::Metadata))
.collect::<Result<HashMap<_, _>, Error>>()?;
let file_name = map.remove("file_name").ok_or(Error::Metadata)?.to_string();
Ok(Self { file_name })
}
}
struct UserData { struct UserData {
username: String, pub username: String,
pw_hash: String, pub pw_hash: String,
is_admin: bool, pub is_admin: bool,
}
impl UserData {
pub fn parse(line: &str, is_admin: bool) -> Result<Self, Error> {
let (username, pw_hash) = line.split_once(": ").ok_or(Error::Metadata)?;
Ok(Self {
username: username.trim().to_string(),
pw_hash: pw_hash.trim().to_string(),
is_admin,
})
}
} }
struct DataStorage { struct DataStorage {
@ -90,7 +138,7 @@ impl DataStorage {
self.load_files()?; self.load_files()?;
self.load_users()?; self.load_users()?;
todo!() Ok(())
} }
fn ensure_folder_structure(&self) -> Result<(), Error> { fn ensure_folder_structure(&self) -> Result<(), Error> {
@ -114,7 +162,7 @@ impl DataStorage {
for line in io::BufReader::new(f).lines() { for line in io::BufReader::new(f).lines() {
line?; line?;
let (id, url) = line?.split_once(": ").expect("invalid redirect format"); let (id, url) = line?.split_once(": ").ok_or(Error::Metadata)?;
self.redirects self.redirects
.insert(id.trim().to_string(), url.trim().to_string()); .insert(id.trim().to_string(), url.trim().to_string());
// if there's a better way to do this let me know // if there's a better way to do this let me know
@ -126,8 +174,18 @@ impl DataStorage {
fn load_text(&mut self) -> Result<(), Error> { fn load_text(&mut self) -> Result<(), Error> {
for thing in std::fs::read_dir(self.base_dir.join(TEXT_DIR)).expect("fs error") { for thing in std::fs::read_dir(self.base_dir.join(TEXT_DIR)).expect("fs error") {
let dir_entry = thing?; // i'm so good at naming things let dir_entry = thing?; // i'm so good at naming things
let f = File::open(dir_entry.path())?; let id = dir_entry.file_name().into_string().or(Err(Error::FS))?;
let reader = io::BufReader::new(f); let (raw_metadata, text) = read_to_string(dir_entry.path())?
.split_once("---")
.expect("invalid text format");
let meta = TextMeta::parse(raw_metadata)?;
self.text.insert(
id,
TextPaste {
text: text.to_string(),
meta,
},
);
} }
Ok(()) Ok(())
} }
@ -135,19 +193,14 @@ impl DataStorage {
fn load_files(&mut self) -> Result<(), Error> { fn load_files(&mut self) -> Result<(), Error> {
for thing in std::fs::read_dir(self.base_dir.join(FILE_DIR)).expect("fs error") { for thing in std::fs::read_dir(self.base_dir.join(FILE_DIR)).expect("fs error") {
let dir_entry = thing?; // i'm so good at naming things let dir_entry = thing?; // i'm so good at naming things
let filename = dir_entry.file_name().into_string().expect("fucked up OS string"); let filename = dir_entry
if filename .file_name()
.ends_with(".meta") .into_string()
{ .expect("fucked up OS string");
if filename.ends_with(".meta") {
let id = filename.trim_end_matches(".meta").to_string(); let id = filename.trim_end_matches(".meta").to_string();
let f = File::open(dir_entry.path())?; let raw_metadata = read_to_string(dir_entry.path())?;
let reader = io::BufReader::new(f); let metadata = FileMeta::parse(raw_metadata.as_str())?;
let raw_metadata = HashMap::new();
for line in reader.lines() {
let (k, v) = line?.split_once(": ").expect("invalid metadata");
raw_metadata.insert(k.trim().to_string(), v.trim().to_string());
}
let metadata = Self::parse_file_meta(raw_metadata)?;
self.files.insert(id, metadata); self.files.insert(id, metadata);
} }
} }
@ -158,21 +211,26 @@ impl DataStorage {
fn assert_all_files_present(&self) -> Result<(), Error> { fn assert_all_files_present(&self) -> Result<(), Error> {
let files_folder = self.base_dir.join(FILE_DIR); let files_folder = self.base_dir.join(FILE_DIR);
for (id, _) in self.files.into_iter() { for (id, _) in self.files.into_iter() {
files_folder.join(id).try_exists().map_err(|_| Error::ShitMissing(id)); files_folder
.join(id)
.try_exists()
.or(Err(Error::ShitMissing(id)))?;
} }
Ok(()) Ok(())
} }
fn parse_file_meta(raw: HashMap<String, String>) -> Result<FileMeta, Error> {
let file_name = raw.get("file_name").ok_or(Error::Metadata)?.to_owned();
Ok(FileMeta { file_name })
}
fn load_users(&mut self) -> Result<(), Error> { fn load_users(&mut self) -> Result<(), Error> {
todo!() let is_admin = true;
for line in read_to_string(self.base_dir.join(USERS_FILE))?.lines() {
if line.starts_with("---") {
is_admin = false;
break;
}
let user = UserData::parse(line, is_admin)?;
self.users.insert(user.username, user);
}
Ok(())
} }
} }
struct AppState { struct AppState {

Loading…
Cancel
Save