summary refs log blame commit diff stats
path: root/src/util.rs
blob: 0b96bde51d17411934ef92ccf58f5db2f837e7bb (plain) (tree)











































































































                                                                               
// This file is part of GAnarchy - decentralized development hub
// Copyright (C) 2021  Soni L.
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program 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 Affero General Public License for more details.
// 
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

//! Some utilities.

/// A helper for checking if a name is fit for a certain purpose.
pub enum NamePurpose {
    /// A `CacheRepo` is the main SHA-1 git repo, used as a cache.
    CacheRepo,
    /// A `CacheRepo64` is the main SHA-2 git repo, used as a cache.
    CacheRepo64,
    /// A `WorkRepo` is a SHA-1 Git repo that isn't the main repo, used for
    /// fetching from remote branches.
    WorkRepo,
    /// A `WorkRepo64` is a SHA-1 Git repo that isn't the main repo, used for
    /// fetching from remote branches.
    WorkRepo64,
    /// A `CacheBranch` is a main branch in the main repo, used as a cache.
    CacheBranch,
    /// A `CacheFetchHead` is a work branch in the main repo, used for fetching
    /// from a work repo.
    CacheFetchHead,
    /// A `WorkBranch` is a branch in a work repo, used for fetching from
    /// remote branches.
    WorkBranch,
    /// A `Commit` is a 160-bit SHA-1 hash, 40 characters long.
    Commit,
    /// A `Commit64` is a 256-bit SHA-2 hash, 64 characters long.
    Commit64,
}

impl NamePurpose {
    /// Checks if the given name is fit for this purpose.
    pub fn is_fit(&self, name: &str) -> bool {
        use NamePurpose::*;
        /// Checks if the value is within the range '0'..='9'.
        fn is_digit(c: char) -> bool {
            c.is_ascii_digit()
        }
        /// Checks if the value is within the ranges '0'..='9' or 'a'..='f'.
        fn is_hex(c: char) -> bool {
            // numbers aren't lowercase, unfortunately.
            c.is_ascii_hexdigit() && !c.is_ascii_uppercase()
        }
        match self {
            CacheRepo => name == "ganarchy-cache.git",
            CacheRepo64 => name == "ganarchy-cache64.git",
            WorkRepo => {
                // "ganarchy-fetch-[0-9][0-9]*\.git"
                Some(name)
                    .and_then(|x| x.strip_prefix("ganarchy-fetch-"))
                    .and_then(|x| x.strip_suffix(".git"))
                    .and_then(|x| x.strip_prefix(is_digit))
                    .map(|x| x.trim_matches(is_digit))
                    == Some("")
            },
            WorkRepo64 => {
                // "ganarchy-fetch-[0-9][0-9]*\.git"
                Some(name)
                    .and_then(|x| x.strip_prefix("ganarchy-fetch64-"))
                    .and_then(|x| x.strip_suffix(".git"))
                    .and_then(|x| x.strip_prefix(is_digit))
                    .map(|x| x.trim_matches(is_digit))
                    == Some("")
            },
            CacheBranch => {
                // "gan[0-9a-f]{64}"
                (0..64)
                    .try_fold(name, |x, _| x.strip_suffix(is_hex))
                    == Some("gan")
            },
            CacheFetchHead => {
                // CacheBranch + "-[0-9]*[0-9]"
                name.strip_suffix(is_digit)
                    .map(|x| x.trim_end_matches(is_digit))
                    .and_then(|x| x.strip_suffix("-"))
                    .filter(|x| CacheBranch.is_fit(x))
                    .is_some()
            },
            WorkBranch => CacheBranch.is_fit(name), // same as CacheBranch
            Commit => {
                // "[0-9a-f]{40}"
                (0..40)
                    .try_fold(name, |x, _| x.strip_suffix(is_hex))
                    == Some("")
            },
            Commit64 => {
                // "[0-9a-f]{64}"
                (0..64)
                    .try_fold(name, |x, _| x.strip_suffix(is_hex))
                    == Some("")
            },
        }
    }
}