use crate::cli;
use crate::shared_logic;
use std::path::Path;
pub fn x_add_tag(path: &Path, data: &cli::Args) {
if !path.exists() {
eprintln!(
"Error: Couldn't find expected file: \"{}\"",
path.to_str().unwrap()
);
return;
}
let tag: String = if data.tag_varies {
shared_logic::convert_tag_characters(path, &data.tag)
} else {
data.tag.clone()
};
let mut path_xattrs = get_xattrs(path);
if path_xattrs.is_empty() {
if data.verbose {
println!("Adding \"{}\" to: \"{}\"...", tag, path.to_str().unwrap());
}
xattr::set(path, "user.xdg.tags", tag.as_bytes())
.map_err(|err| {
eprintln!(
"Couldn't set xattr for: \"{}\"\nerror: {}",
path.to_str().unwrap(),
err
);
})
.ok();
return;
}
if path_xattrs.contains(&tag) {
if data.verbose {
println!("Ignoring \"{}\"...", path.to_str().unwrap());
}
return;
}
if data.verbose {
println!("Adding \"{}\" to: \"{}\"...", tag, path.to_str().unwrap());
}
path_xattrs.push(tag);
let string_xattrs = path_xattrs.join(",");
xattr::set(path, "user.xdg.tags", string_xattrs.as_bytes())
.map_err(|err| {
eprintln!(
"Couldn't set xattr for: \"{}\"\nerror: {}",
path.to_str().unwrap(),
err
);
})
.ok();
}
pub fn x_remove_tag(path: &Path, data: &cli::Args) {
if !path.exists() {
eprintln!(
"Error: Couldn't find expected file: \"{}\"",
path.to_str().unwrap()
);
return;
}
let tag: String = if data.tag_varies {
shared_logic::convert_tag_characters(path, &data.tag)
} else {
data.tag.clone()
};
let mut path_xattrs = get_xattrs(path);
if path_xattrs.is_empty() || !path_xattrs.contains(&tag) {
if data.verbose {
println!("Ignoring: \"{}\"", path.to_str().unwrap());
}
return;
}
let index = path_xattrs.iter().position(|r| r == &tag).unwrap();
path_xattrs.remove(index);
if path_xattrs.is_empty() {
if data.verbose {
println!(
"Removing tag \"{}\" from path \"{}\"...",
tag,
path.to_str().unwrap()
);
}
xattr::remove(path, "user.xdg.tags")
.map_err(|err| {
eprintln!(
"Couldn't remove tag \"{}\" from path \"{}\"\nerror: {}",
tag,
path.to_str().unwrap(),
err
);
})
.ok();
} else {
let string_xattrs = path_xattrs.join(",");
if data.verbose {
println!(
"Removing tag \"{}\" from path \"{}\"...",
tag,
path.to_str().unwrap()
);
}
xattr::set(path, "user.xdg.tags", string_xattrs.as_bytes())
.map_err(|err| {
eprintln!(
"Couldn't remove tag \"{}\" from path \"{}\"\nerror: {}",
tag,
path.to_str().unwrap(),
err
);
})
.ok();
}
}
pub fn x_remove_all_tags(path: &Path, data: &cli::Args) {
if !path.exists() {
eprintln!(
"Error: Couldn't find expected file: \"{}\"",
path.to_str().unwrap()
);
return;
}
let path_xattrs = get_xattrs(path);
if path_xattrs.is_empty() {
if data.verbose {
println!("Ignoring: \"{}\"", path.to_str().unwrap());
}
return;
}
if data.verbose {
println!(
"Removing tag(s) {:?} from path \"{}\"...",
path_xattrs,
path.to_str().unwrap()
);
}
xattr::remove(path, "user.xdg.tags")
.map_err(|err| {
eprintln!(
"Couldn't remove tag {:?} from path \"{}\"\nerror: {}",
path_xattrs,
path.to_str().unwrap(),
err
);
})
.ok();
}
pub fn get_xattrs(path: &Path) -> Vec<String> {
let xattrs = xattr::list(path).unwrap();
let mut vector_of_xattr_values = vec![];
for attr in xattrs {
if attr.to_str().unwrap() == "user.xdg.tags" {
let byte_vector: &[u8] = &xattr::get(path, "user.xdg.tags").unwrap().unwrap();
let string = std::str::from_utf8(byte_vector).unwrap();
let split_string: Vec<&str> = string.split(',').collect();
for each_part in split_string {
vector_of_xattr_values.push(each_part.to_owned());
}
break;
}
}
vector_of_xattr_values
}