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>, 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(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> { 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(()) } }