use super::super::ct_fs;
use super::errors;
use super::has as proj_exists;
use super::ProjectFrame;
use std::{
fs::{File, OpenOptions},
io::{Read, Write},
path::PathBuf,
};
const PERSISTENT_FILE_NAME: &str = "./stored.ctstore";
fn store_path() -> errors::CtResult<PathBuf> {
Ok(ct_fs::default_path::conf_path()?.join(PERSISTENT_FILE_NAME))
}
fn clear_store_and_get_handle() -> errors::CtResult<File> {
OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(store_path()?)
.map_err(|e| e.into())
}
pub(crate) fn clear_store() -> errors::CtResult<()> {
clear_store_and_get_handle()?;
Ok(())
}
pub fn has_project() -> errors::CtResult<Option<String>> {
let path = store_path()?;
let mut file = if !path.exists() {
OpenOptions::new()
.write(true)
.read(true)
.create_new(true)
.open(path)?;
return Ok(None);
} else {
OpenOptions::new().read(true).open(path)?
};
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(if let Some(line) = contents.lines().next() {
if line.is_empty() {
None
} else if proj_exists(line)? {
Some(line.to_owned())
} else {
clear_store()?;
None
}
} else {
None
})
}
pub(crate) fn register(name: &str) -> errors::CtResult<()> {
if let Some(stored) = has_project()? {
if name == stored {
return Ok(());
}
}
let mut file = clear_store_and_get_handle()?;
file.write_all(name.as_bytes())?;
Ok(())
}
pub(crate) fn deregister(name: Option<&str>) -> errors::CtResult<()> {
if let Some(name) = name {
if let Some(stored) = has_project()? {
if stored != name {
return Ok(());
}
} else {
return Ok(());
}
}
clear_store()?;
Ok(())
}
pub(crate) fn validate() -> errors::CtResult<()> {
if let Some(name) = has_project()? {
let p = ProjectFrame::load_from_name(name.as_str())?;
if !p.is_open() {
clear_store()?;
}
};
Ok(())
}
pub(crate) fn delete_stored_if(name: &str) -> errors::CtResult<bool> {
if let Some(proj) = has_project()? {
if proj == name {
clear_store()?;
return Ok(true);
}
}
Ok(false)
}