use std::env;
use super::types::Portal;
use crate::file::FileType;
use strum::IntoEnumIterator;
use crate::git::Git;
use std::path::Path;
use log::{info, trace};
use miette::{Context, Error, IntoDiagnostic, Result};
use pipelight_error::{LibError, PipelightError};
impl Portal {
pub fn teleport(&mut self) -> Result<Self, PipelightError> {
let target = self.target.directory_path.clone().unwrap();
env::set_current_dir(target.clone())?;
info!("working directory changed to -> {:#?}", &target);
Ok(self.to_owned())
}
pub fn origin(&mut self) -> Result<Self, PipelightError> {
let target = self.origin.directory_path.clone().unwrap();
env::set_current_dir(target.clone())?;
info!("working directory changed to -> {:#?}", &target);
Ok(self.to_owned())
}
pub fn seed(&mut self, string: &str) -> Self {
self.seed = Some(string.to_owned());
self.to_owned()
}
pub fn search(&mut self) -> Result<Self, PipelightError> {
let seed = self.seed.clone();
if let Some(seed) = seed {
let mut path_portal = self.clone();
let mut file_portal = self.clone();
let mut prefix_portal = self.clone();
if path_portal.search_path().is_ok() {
*self = path_portal;
return Ok(self.to_owned());
} else if file_portal.search_file().is_ok() {
*self = file_portal;
return Ok(self.to_owned());
} else if prefix_portal.search_prefix().is_ok() {
*self = prefix_portal;
return Ok(self.to_owned());
} else {
return Err(PipelightError::LibError(LibError {
message: format!("Couldn't find a file with the provided seed: {:#?}", seed),
help: format!("Try creating a file that begins by {:#?}", seed),
}));
}
}
Ok(self.to_owned())
}
fn parent(&mut self) -> Result<Self, PipelightError> {
if !self.has_reached_root()? && self.current.directory_path.is_some() {
let current = self.current.directory_path.clone().unwrap();
let parent = Path::new(¤t).parent();
if parent.is_some() {
self.current.directory_path = Some(parent.unwrap().display().to_string());
return Ok(self.to_owned());
}
}
Err(PipelightError::LibError(LibError {
message: "Couldn't recurse higher in filesystem".to_owned(),
help: "Maybe you made a typo in filename".to_owned(),
}))
}
fn has_reached_root(&mut self) -> Result<bool, PipelightError> {
if Git::new().exists() {
let boolean = self.current.directory_path
== Some(
Git::new()
.repo
.unwrap()
.workdir()
.unwrap()
.to_str()
.unwrap()
.to_owned(),
);
Ok(boolean)
}
else {
Ok(self.current.directory_path == Some("/".to_owned()))
}
}
pub fn search_file(&mut self) -> Result<(), PipelightError> {
trace!("search file");
if self.seed.is_some() {
let name = self.seed.clone().unwrap();
let file_str = format!("{}/{}", self.current.directory_path.clone().unwrap(), name);
let path = Path::new(&file_str);
if path.is_dir() {
return Err(PipelightError::LibError(LibError {
message: format!("Couldn't find file {}", name),
help: "Maybe you made a typo in filename".to_owned(),
}));
}
if path.exists() {
self.target.file(path.display().to_string())?;
} else if self.parent().is_ok() {
self.search_file()?;
} else {
return Err(PipelightError::LibError(LibError {
message: format!("Couldn't find file {}", name),
help: "Maybe you made a typo in filename".to_owned(),
}));
}
}
Ok(())
}
pub fn search_path(&mut self) -> Result<(), PipelightError> {
trace!("search path");
let path_str = self.seed.clone();
if let Some(mut path_str) = path_str {
let mut path = Path::new(&path_str);
if path.is_relative() {
path_str = path.canonicalize()?.display().to_string();
path = Path::new(&path_str);
}
if path.extension().is_none() {
return Err(PipelightError::LibError(LibError {
message: format!("Couldn't find file at path {}", path_str),
help: "Maybe you made a typo in filename".to_owned(),
}));
}
if path.exists() {
self.target.file(path.display().to_string())?;
Ok(())
} else {
return Err(PipelightError::LibError(LibError {
message: format!("Couldn't find file at path {}", path_str),
help: "Maybe you made a typo in filename".to_owned(),
}));
}
} else {
return Err(PipelightError::LibError(LibError {
message: "No filepath were provided".to_owned(),
help: "Try giving a filepath".to_owned(),
}));
}
}
pub fn search_prefix(&mut self) -> Result<()> {
trace!("search prefix");
let seed = self.seed.clone();
let mut exists = false;
for file_type in FileType::iter() {
let extension = String::from(&file_type);
if self.seed.is_some() {
let path_str = format!(
"{}/{}.{}",
self.current.directory_path.clone().unwrap(),
self.seed.clone().unwrap(),
extension
)
.to_owned();
let path = Path::new(&path_str);
if path.exists() {
exists = true;
self.target.file(path.display().to_string())?;
break;
}
}
}
if !exists {
if self.parent().is_ok() {
self.search_prefix()?;
} else {
let msg = format!("Couldn't find file with seed {}", seed.unwrap());
return Err(Error::msg(msg));
}
}
Ok(())
}
}