nextsync-rust/src/store/object/tree.rs

120 lines
3.4 KiB
Rust

use crate::utils::into::IntoPathBuf;
use crate::store::object::object::Obj;
use crate::store::object::update_dates;
use crate::store::object::object::ObjMethods;
use std::fs::{self, File, OpenOptions};
use std::io::{self, BufRead, BufReader, Write};
pub struct Tree {
pub obj: Obj,
pub buf_reader: Option<BufReader<File>>,
is_head: bool,
}
impl Tree {
pub fn new(obj: Obj) -> Self {
Tree {
obj,
buf_reader: None,
is_head: false,
}
}
pub fn from_head() -> Self {
Tree {
obj: Obj::from_head(),
buf_reader: None,
is_head: true,
}
}
pub fn from_path<S>(r_path: S) -> Tree where S: IntoPathBuf {
Tree {
obj: Obj::from_path(r_path.into()),
buf_reader: None,
is_head: false,
}
}
pub fn read(&mut self) {
if self.buf_reader.is_none() {
if let Ok(file) = File::open(self.get_obj_path()) {
self.buf_reader = Some(BufReader::new(file));
// skip first line (declaration) if is not head
if !self.is_head {
let mut line = String::new();
self.buf_reader.as_mut().unwrap().read_line(&mut line);
}
}
}
}
pub fn has_changes(&mut self) -> bool {
todo!();
return true;
}
pub fn next(&mut self) -> Option<Box<dyn ObjMethods>> {
self.read();
//if let Some(ref mut file) = self.buf_reader {
// let mut line = String::new();
// match file.read_line(&mut line) {
// Ok(0) => Ok(None), // End of file
// Ok(_) => Ok(Some(line.trim_end().len())), // Return length of line
// Err(e) => Err(e),
// }
//} else {
// Ok(None) // If file is None, return None
//}
match self.buf_reader {
Some(ref mut file) => {
let mut line = String::new();
match file.read_line(&mut line) {
Ok(0) => None,
Ok(_) => Some(Obj::from_line(line, Some(self.get_relative_file_path()))),
Err(e) => {
eprintln!("tree::next: failed to read next line: {}", e);
None
}
}
},
None => None
}
}
pub fn create(&self, date: &str, up_parent: bool) -> io::Result<()> {
// add tree reference to parent
let _ = self.add_ref_to_parent();
// create tree object
let content = format!("{} {}", self.get_name(), date);
// create parent dir if needed
let mut obj_path = self.get_obj_path();
obj_path.pop();
if !obj_path.exists() {
fs::create_dir_all(obj_path)?;
}
// open ref file
let mut file = OpenOptions::new()
.create_new(true)
.write(true)
.open(self.get_obj_path())?;
// update date for all parent
// if up_parent {
// if let Err(err) = update_dates(self.get_relative_file_path(), date) {
// eprintln!("err: updating parent date of {}: {}", self.get_relative_file_path().display(), err);
// }
// }
writeln!(file, "{}", content)?;
Ok(())
}
}