summary refs log blame commit diff stats
path: root/src/data/kinds.rs
blob: f9dd14f2303e078f70ea6ee98478dbbf724b6bb9 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                                                              

                               






                           



                                                                               
                         
                                                             

                                     





                                         





                                                   
                                                             

                                    





                                          





                                                     
                                                             



                                                                             
             
                                     
                 
                                                                   









































































































                                                                                















                                             
                                                             
                           
                                
                    
                       
                
                          



                        
                                                             
                        









                                                     



                                             
                                 








                                      
// 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/>.

//! Kinds of data for use with `DataSource`.

use std::collections::BTreeSet;

use arcstr::ArcStr;

use url::Url;

use super::Kind;
use super::OverridableKind;

// InstanceTitle and InstanceBaseUrl are all pub because there's nothing else
// they could be, nothing else to add to them, etc. They're as API-stable as it
// gets.

/// Title of an instance.
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
pub struct InstanceTitle(pub String);

impl From<String> for InstanceTitle {
    fn from(s: String) -> InstanceTitle {
        InstanceTitle(s)
    }
}

impl Kind for InstanceTitle {
    /// A source may only have one `InstanceTitle`.
    type Values = Option<Self>;
}

/// URL of an instance.
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
pub struct InstanceBaseUrl(pub Url);

impl From<Url> for InstanceBaseUrl {
    fn from(url: Url) -> InstanceBaseUrl {
        InstanceBaseUrl(url)
    }
}

impl Kind for InstanceBaseUrl {
    /// A source may only have one `InstanceBaseUrl`.
    type Values = Option<Self>;
}

/// URL of a repo list.
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
pub struct RepoListUrl {
    // `Url` is actually fairly expensive, but we don't usually have a lot of
    // `RepoListUrl` around. Additionally these are generally unique.
    /// The actual URL that references a repo list.
    url: Url,
    /// Whether this entry is active.
    active: bool,
    /// Whether this repo list is allowed to have negative entries.
    allow_negative_entries: bool,
}

impl RepoListUrl {
    /// Creates a new `RepoListUrl` for the given [`Url`].
    ///
    /// The resulting `RepoListUrl` is active by default, and, if the `Url` is
    /// a `file://` URL, also allows negative entries.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```rust
    /// use ganarchy::data::kinds::RepoListUrl;
    /// use url::Url;
    ///
    /// let remote_repo_list = RepoListUrl::new_for({
    ///     Url::parse("https://example.org").unwrap()
    /// });
    /// assert!(!remote_repo_list.allows_negative_entries());
    ///
    /// let local_repo_list = RepoListUrl::new_for({
    ///     Url::parse("file:///etc/xdg/ganarchy/repos.toml").unwrap()
    /// });
    /// assert!(local_repo_list.allows_negative_entries());
    /// ```
    pub fn new_for(url: Url) -> RepoListUrl {
        RepoListUrl {
            allow_negative_entries: url.scheme() == "file",
            url: url,
            active: true,
        }
    }

    /// Returns whether negative entries are allowed for this `RepoListUrl`.
    pub fn allows_negative_entries(&self) -> bool {
        self.allow_negative_entries
    }

    /// Forbids negative entries for this `RepoListUrl`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use ganarchy::data::kinds::RepoListUrl;
    /// use url::Url;
    ///
    /// let mut local_repo_list = RepoListUrl::new_for({
    ///     Url::parse("file:///etc/xdg/ganarchy/repos.toml").unwrap()
    /// });
    /// assert!(local_repo_list.allows_negative_entries());
    /// local_repo_list.forbid_negative_entries();
    /// assert!(!local_repo_list.allows_negative_entries());
    /// ```
    pub fn forbid_negative_entries(&mut self) {
        self.allow_negative_entries = false;
    }

    /// Activates this `RepoListUrl`.
    pub fn activate(&mut self) {
        self.active = true;
    }

    /// Deactivates this `RepoListUrl`.
    pub fn deactivate(&mut self) {
        self.active = false;
    }

    /// Returns whether this `RepoListUrl` is active.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use ganarchy::data::kinds::RepoListUrl;
    /// use url::Url;
    ///
    /// let mut local_repo_list = RepoListUrl::new_for({
    ///     Url::parse("file:///etc/xdg/ganarchy/repos.toml").unwrap()
    /// });
    /// assert!(local_repo_list.is_active());
    /// local_repo_list.deactivate();
    /// assert!(!local_repo_list.is_active());
    /// local_repo_list.activate();
    /// assert!(local_repo_list.is_active());
    /// ```
    pub fn is_active(&self) -> bool {
        self.active
    }

    /// Returns the `Url` associated with this `RepoListUrl`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use ganarchy::data::kinds::RepoListUrl;
    /// use url::Url;
    ///
    /// let remote_repo_list = RepoListUrl::new_for({
    ///     Url::parse("https://example.org").unwrap()
    /// });
    /// assert_eq!("https://example.org/", remote_repo_list.get_url().as_ref());
    /// ```
    pub fn get_url(&self) -> &Url {
        &self.url
    }
}

impl Kind for RepoListUrl {
    /// A source may have many `RepoListUrl`.
    type Values = Vec<Self>;
}

impl OverridableKind for RepoListUrl {
    type Key = Url;

    fn as_key(&self) -> &Self::Key {
        &self.url
    }
}

/// The key for a [`ProjectFork`].
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
pub struct ProjectForkKey {
    /// The project's commit ID.
    project: ArcStr,
    /// The fork's URL.
    url: ArcStr,
    /// The fork's branch.
    branch: ArcStr,
}

/// A fork of a project.
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
pub struct ProjectFork {
    /// The fork.
    key: ProjectForkKey,
    /// Whether this entry is active.
    active: bool,
    /// Whether this entry is local to this instance.
    local: bool,
}

impl ProjectFork {
    //pub fn new_for(
}

impl Kind for ProjectFork {
    /// A source may have many `ProjectFork`.
    type Values = BTreeSet<Self>;
}

impl OverridableKind for ProjectFork {
    type Key = ProjectForkKey;

    fn as_key(&self) -> &Self::Key {
        &self.key
    }
}