// 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 . //! 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 for InstanceTitle { fn from(s: String) -> InstanceTitle { InstanceTitle(s) } } impl Kind for InstanceTitle { /// A source may only have one `InstanceTitle`. type Values = Option; } /// URL of an instance. #[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)] pub struct InstanceBaseUrl(pub Url); impl From for InstanceBaseUrl { fn from(url: Url) -> InstanceBaseUrl { InstanceBaseUrl(url) } } impl Kind for InstanceBaseUrl { /// A source may only have one `InstanceBaseUrl`. type Values = Option; } /// 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; } 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; } impl OverridableKind for ProjectFork { type Key = ProjectForkKey; fn as_key(&self) -> &Self::Key { &self.key } }