tagctl 1.2.1

Adds or removes tags to given paths inside square brackets or to extended attributes
Documentation
/*
Copyright (C) 2022  Kody VB
This file is part of Tagctl.

Tagctl is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option) any
later version.

Tagctl is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.

You should have received a copy of the GNU General Public License along with
Tagctl. If not, see <https://www.gnu.org/licenses/>.
*/

use chrono::{DateTime, Datelike, Local, Offset};
use std::{path::Path, time::UNIX_EPOCH};

pub fn convert_tag_characters(path: &Path, tag: &str) -> String {
    // Converts any special strings like %p to their values
    let mut new_tag: String = tag.to_owned();
    if new_tag.contains("%p") {
        let parent_dirname: String = path
            .parent()
            .unwrap()
            .file_name()
            .unwrap()
            .to_str()
            .unwrap()
            .to_owned();
        let split_tag: Vec<&str> = new_tag.split("%p").collect();
        if split_tag.is_empty() {
            new_tag = parent_dirname;
        } else {
            new_tag = split_tag.join(parent_dirname.as_str());
        }
    }

    if new_tag.contains("%y")
        || new_tag.contains("%m")
        || new_tag.contains("%d")
        || new_tag.contains("%w")
    {
        let timestamp = std::fs::metadata(path)
            .unwrap()
            .modified()
            .unwrap()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();
        let as_sec = i64::try_from(timestamp).ok().unwrap();
        let date_time_utc = DateTime::from_timestamp(as_sec, 0).unwrap().naive_utc();
        let local_timezone = Local::now().offset().fix();
        let date_time_local =
            DateTime::<Local>::from_naive_utc_and_offset(date_time_utc, local_timezone);

        if new_tag.contains("%y") {
            let split_tag: Vec<&str> = new_tag.split("%y").collect();
            if split_tag.is_empty() {
                new_tag = date_time_local.year().to_string();
            } else {
                new_tag = split_tag.join(date_time_local.year().to_string().as_str());
            }
        }

        if new_tag.contains("%m") {
            let split_tag: Vec<&str> = new_tag.split("%m").collect();
            if split_tag.is_empty() {
                new_tag = date_time_local.month().to_string();
            } else {
                new_tag = split_tag.join(date_time_local.month().to_string().as_str());
            }
        }

        if new_tag.contains("%d") {
            let split_tag: Vec<&str> = new_tag.split("%d").collect();
            if split_tag.is_empty() {
                new_tag = date_time_local.day().to_string();
            } else {
                new_tag = split_tag.join(date_time_local.day().to_string().as_str());
            }
        }

        if new_tag.contains("%w") {
            let split_tag: Vec<&str> = new_tag.split("%w").collect();
            if split_tag.is_empty() {
                new_tag = date_time_local.weekday().to_string();
            } else {
                new_tag = split_tag.join(date_time_local.weekday().to_string().as_str());
            }
        }
    }

    new_tag
}