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