index : sparkle-git.git

ascending towards madness

use std::{path::Path, vec};

use comrak::Options;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct AppConfig {
    /// Set the title and heading of the repository index page
    ///
    /// Default value: "Git repository browser"
    pub root_title: String,

    /// Set a subtitle for the repository index page
    ///
    /// Default value: `unset`
    pub root_description: String,

    /// Include some more info about example.com on the index page
    ///
    /// Default value: `unset`
    pub root_readme: String,

    /// Allow download of source tarballs
    ///
    /// Default value: `["tar.bz", "tar.bz2", "zip"]`
    pub snapshots: Vec<String>,

    /// Add a favicon
    ///
    /// Default value: `unset`
    pub favicon: String,

    /// Use a custom logo image
    ///
    /// Default value: `unset`
    pub logo: String,

    /// Alt text for the custom logo image
    ///
    /// Used as a fallback when `logo` is unset
    ///
    /// Default value: "🏡"
    pub logo_alt: String,

    /// Url loaded when clicking on the logo
    ///
    /// Default value: "/"
    pub logo_link: String,

    /// Allow http transport git clone
    ///
    /// Default value: `true`
    pub enable_http_clone: bool,

    /// Show extra links for each repository on the index page
    ///
    /// Default value: `false`
    pub enable_index_links: bool,

    /// Show owner on the index page
    ///
    /// Default value: `true`
    pub enable_index_owner: bool,

    /// Generate HTTPS clone urls
    ///
    /// Default value: `unset`
    pub clone_prefix: String,

    /// Generate SSH clone urls
    ///
    /// Default value: `unset`
    pub ssh_clone_prefix: String,

    /// Specifies the maximum number of commit message characters to display in "log" view.
    ///
    /// A value of "0" indicates no limit.
    ///
    /// Default value: "0"
    pub max_commit_message_length: usize,

    /// Specifies the maximum number of description characters to display on the repository index page.
    ///
    /// A value of "0" indicates no limit.
    ///
    /// Default value: "0"
    pub max_repo_desc_length: usize,
}

impl ::std::default::Default for AppConfig {
    fn default() -> Self {
        Self {
            root_title: String::from("Git repository browser"),
            root_description: String::new(),
            root_readme: String::new(),
            snapshots: vec![
                String::from("tar.gz"),
                String::from("tar.bz2"),
                String::from("zip"),
            ],
            favicon: String::new(),
            logo: String::new(),
            logo_alt: String::from("🏡"),
            logo_link: String::from("/"),
            enable_http_clone: true,
            enable_index_links: false,
            enable_index_owner: true,
            clone_prefix: String::new(),
            ssh_clone_prefix: String::new(),
            max_commit_message_length: 0,
            max_repo_desc_length: 0,
        }
    }
}

impl AppConfig {
    pub fn load(path: String) -> Self {
        confy::load_path(path).unwrap_or_default()
    }

    pub fn http_clone_enabled(&self) -> bool {
        (!self.clone_prefix.is_empty() || !self.ssh_clone_prefix.is_empty())
            && self.enable_http_clone
    }

    pub fn root_readme_is_valid(&self) -> bool {
        Path::new(&self.root_readme).try_exists().unwrap_or(false)
    }
}

pub struct ReadmeConfig;

impl ReadmeConfig {
    pub fn gfm() -> Options {
        // enable gfm extensions
        // https://github.github.com/gfm/
        let mut options = Options::default();
        options.extension.autolink = true;
        options.extension.footnotes = true;
        options.extension.strikethrough = true;
        options.extension.table = true;
        options.extension.tagfilter = true;
        options.extension.tasklist = true;

        options
    }
}