Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/api/unyank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub(crate) async fn put(req: Request<State>) -> Result<Response, Error> {
));
}

state.index.unyank_record(name.as_str(), version.clone())?;
state.index.unyank_record(name.as_str(), &version)?;

let msg = format!("Unyanking crate `{0}#{1}`", name.as_str(), version);
state.index.commit_and_push(msg.as_str())?;
Expand Down
2 changes: 1 addition & 1 deletion src/api/yank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub(crate) async fn delete(req: Request<State>) -> Result<Response, Error> {
));
}

state.index.yank_record(name.as_str(), version.clone())?;
state.index.yank_record(name.as_str(), &version)?;

let msg = format!("Yanking crate `{0}#{1}`", name.as_str(), version);
state.index.commit_and_push(msg.as_str())?;
Expand Down
24 changes: 0 additions & 24 deletions src/config/index/cli.rs

This file was deleted.

24 changes: 0 additions & 24 deletions src/config/index/git2.rs

This file was deleted.

41 changes: 0 additions & 41 deletions src/config/index/mod.rs

This file was deleted.

7 changes: 3 additions & 4 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use std::convert::TryInto;
use std::net;

use serde::{Deserialize, Serialize};

/// Database configuration (`[database]` section).
pub mod database;
/// Index management strategy configuration (`[index]` section).
pub mod index;
/// Crate storage configuration (`[storage]` section).
pub mod storage;
/// Syntax-highlighting configurations (`[syntect.syntaxes]` and `[syntect.themes]` sections).
Expand All @@ -20,9 +19,9 @@ use crate::storage::Storage;
use crate::Repo;

use crate::config::database::DatabaseConfig;
use crate::config::index::IndexConfig;
use crate::config::storage::StorageConfig;
use crate::config::syntect::{SyntectConfig, SyntectState};
use crate::index::Config as IndexConfig;

#[cfg(feature = "frontend")]
pub use crate::config::frontend::*;
Expand Down Expand Up @@ -72,7 +71,7 @@ pub struct State {
impl From<Config> for State {
fn from(config: Config) -> State {
State {
index: config.index.into(),
index: config.index.try_into().unwrap(),
storage: config.storage.into(),
repo: Repo::new(&config.database),
syntect: config.syntect.into(),
Expand Down
10 changes: 5 additions & 5 deletions src/index/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ impl Indexer for CommandLineIndex {
self.tree.add_record(record)
}

fn alter_record<F>(&self, name: &str, version: Version, func: F) -> Result<(), Error>
where
F: FnOnce(&mut CrateVersion),
{
self.tree.alter_record(name, version, func)
fn yank_record(&self, name: &str, version: &Version) -> Result<(), Error> {
self.tree.yank(name, version)
}
fn unyank_record(&self, name: &str, version: &Version) -> Result<(), Error> {
self.tree.unyank(name, version)
}
}

Expand Down
181 changes: 90 additions & 91 deletions src/index/mod.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,62 @@
use semver::{Version, VersionReq};
use std::convert::TryFrom;
use std::path::PathBuf;

/// Index management through `git` shell command invocations.
pub mod cli;
mod models;
mod tree;

/// Index management using [**`libgit2`**][libgit2].
/// [libgit2]: https://libgit2.org
#[cfg(feature = "git2")]
pub mod git2;
use tree::Tree;
mod repository;
use repository::Repository;
use serde::{Deserialize, Serialize};

pub use models::{CrateDependency, CrateDependencyKind, CrateVersion};

use crate::error::Error;
use crate::index::cli::CommandLineIndex;

#[cfg(feature = "git2")]
use crate::index::git2::Git2Index;
pub struct Index {
repo: Repository,
tree: Tree,
}

/// The crate indexing management strategy type.
/// The configuration struct for the 'git2' index management strategy.
///
/// It represents which index management strategy is currently used.
pub enum Index {
/// Manages the crate index through the invocation of the "git" shell command.
CommandLine(CommandLineIndex),
/// Manages the crate index using [**`libgit2`**].
/// [libgit2]: https://libgit2.org
/// ```toml
/// [index]
/// type = "git2" | "command-line" # required
/// path = "crate-index" # required
/// ```
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
#[serde(rename_all = "kebab-case")]
pub enum Config {
#[cfg(feature = "git2")]
Git2(Git2Index),
Git2 {
path: PathBuf,
},
CommandLine {
path: PathBuf,
},
}

impl TryFrom<Config> for Index {
type Error = Error;
fn try_from(config: Config) -> Result<Self, Self::Error> {
let (path, repo) = match config {
Config::CommandLine { path } => {
let repo = Repository::new_cli(path.clone());
(path, repo)
}
#[cfg(feature = "git2")]
Config::Git2 { path } => {
let repo = Repository::new_git2(&path)?;
(path, repo)
}
};

let tree = Tree::new(path);

Ok(Self { repo, tree })
}
}

/// The required trait that any crate index management type must implement.
Expand All @@ -46,101 +75,71 @@ pub trait Indexer {
fn commit_and_push(&self, msg: &str) -> Result<(), Error>;
/// Adds a new crate record into the index.
fn add_record(&self, record: CrateVersion) -> Result<(), Error>;
/// Alters an index's crate version record with the passed-in function.
fn alter_record<F>(&self, name: &str, version: Version, func: F) -> Result<(), Error>
where
F: FnOnce(&mut CrateVersion);
/// Yanks a crate version.
fn yank_record(&self, name: &str, version: Version) -> Result<(), Error> {
self.alter_record(name, version, |krate| krate.yanked = Some(true))
}
fn yank_record(&self, name: &str, version: &Version) -> Result<(), Error>;
/// Un-yanks a crate version.
fn unyank_record(&self, name: &str, version: Version) -> Result<(), Error> {
self.alter_record(name, version, |krate| krate.yanked = Some(false))
}
fn unyank_record(&self, name: &str, version: &Version) -> Result<(), Error>;
}

impl Indexer for Index {
fn url(&self) -> Result<String, Error> {
match self {
Index::CommandLine(idx) => idx.url(),
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.url(),
}
self.repo.url()
}

fn refresh(&self) -> Result<(), Error> {
match self {
Index::CommandLine(idx) => idx.refresh(),
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.refresh(),
}
}

fn commit_and_push(&self, msg: &str) -> Result<(), Error> {
match self {
Index::CommandLine(idx) => idx.commit_and_push(msg),
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.commit_and_push(msg),
}
self.repo.refresh()
}

fn all_records(&self, name: &str) -> Result<Vec<CrateVersion>, Error> {
match self {
Index::CommandLine(idx) => idx.all_records(name),
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.all_records(name),
}
self.tree.all_records(name)
}

fn latest_record(&self, name: &str) -> Result<CrateVersion, Error> {
match self {
Index::CommandLine(idx) => idx.latest_record(name),
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.latest_record(name),
}
self.tree.latest_record(name)
}

fn match_record(&self, name: &str, req: VersionReq) -> Result<CrateVersion, Error> {
match self {
Index::CommandLine(idx) => idx.match_record(name, req),
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.match_record(name, req),
}
self.tree.match_record(name, req)
}
fn commit_and_push(&self, msg: &str) -> Result<(), Error> {
self.repo.commit_and_push(msg)
}

fn add_record(&self, record: CrateVersion) -> Result<(), Error> {
match self {
Index::CommandLine(idx) => idx.add_record(record),
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.add_record(record),
}
self.tree.add_record(record)
}

fn alter_record<F>(&self, name: &str, version: Version, func: F) -> Result<(), Error>
where
F: FnOnce(&mut CrateVersion),
{
match self {
Index::CommandLine(idx) => idx.alter_record(name, version, func),
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.alter_record(name, version, func),
}
fn yank_record(&self, name: &str, version: &Version) -> Result<(), Error> {
self.tree.yank(name, version)
}
fn unyank_record(&self, name: &str, version: &Version) -> Result<(), Error> {
self.tree.unyank(name, version)
}
}

fn yank_record(&self, name: &str, version: Version) -> Result<(), Error> {
match self {
Index::CommandLine(idx) => idx.yank_record(name, version),
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.yank_record(name, version),
#[cfg(test)]
mod tests {
use super::Config;
#[test]
fn from_config() {
#[cfg(feature = "git2")]
match toml::from_str(
r#"
type = "git2"
path = "crate-index"
"#,
)
.unwrap()
{
Config::Git2 { .. } => (),
Config::CommandLine { .. } => panic!("deserialization failed!"),
}
}

fn unyank_record(&self, name: &str, version: Version) -> Result<(), Error> {
match self {
Index::CommandLine(idx) => idx.unyank_record(name, version),
match toml::from_str(
r#"
type = "command-line"
path = "crate-index"
"#,
)
.unwrap()
{
#[cfg(feature = "git2")]
Index::Git2(idx) => idx.unyank_record(name, version),
Config::Git2 { .. } => panic!("deserialization failed!"),
Config::CommandLine { .. } => (),
}
}
}
Loading