blob: e720dbb506777b84a5118d980ead7ee1de2379bf [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
crate::repository::Repository,
parking_lot::RwLock,
std::{collections::HashMap, sync::Arc},
};
type ArcRepository = Arc<Repository>;
/// RepositoryManager is responsible for managing all the repositories in use by ffx.
pub struct RepositoryManager {
repositories: RwLock<HashMap<String, ArcRepository>>,
}
impl RepositoryManager {
/// Construct a new [RepositoryManager].
pub fn new() -> Arc<Self> {
Arc::new(Self { repositories: RwLock::new(HashMap::new()) })
}
/// Add a [Repository] to the [RepositoryManager].
pub fn add(&self, repo: ArcRepository) {
self.repositories.write().insert(repo.name().to_string(), repo);
}
/// Get a [Repository].
pub fn get(&self, repo_name: &str) -> Option<ArcRepository> {
self.repositories.read().get(repo_name).map(|repo| Arc::clone(repo))
}
/// Remove a [Repository] from the [RepositoryManager].
pub fn remove(&self, name: &str) -> bool {
self.repositories.write().remove(name).is_some()
}
/// Removes all [Repositories](Repository) from the [RepositoryManager].
pub fn clear(&self) {
self.repositories.write().clear();
}
/// Iterate through all [Repositories].
pub fn repositories<'a>(&'a self) -> impl std::iter::Iterator<Item = ArcRepository> + 'a {
let mut ret = self.repositories.read().values().map(Arc::clone).collect::<Vec<_>>();
ret.sort_unstable_by_key(|x| x.name().to_owned());
ret.into_iter()
}
}
#[cfg(test)]
mod test {
use {super::*, crate::test_utils::make_readonly_empty_repository};
const REPO_NAME: &str = "fake-repo";
#[fuchsia_async::run_singlethreaded(test)]
async fn test_add() {
let repo = make_readonly_empty_repository(REPO_NAME).await.unwrap();
let manager = RepositoryManager::new();
manager.add(Arc::new(repo));
assert_eq!(
manager.repositories().map(|x| x.name().to_owned()).collect::<Vec<_>>(),
vec![REPO_NAME.to_owned()]
);
}
#[fuchsia_async::run_singlethreaded(test)]
async fn test_remove() {
let repo = make_readonly_empty_repository(REPO_NAME).await.unwrap();
let manager = RepositoryManager::new();
manager.add(Arc::new(repo));
assert_eq!(
manager.repositories().map(|x| x.name().to_owned()).collect::<Vec<_>>(),
vec![REPO_NAME.to_owned()]
);
manager.remove(REPO_NAME);
assert!(manager.repositories().next().is_none());
}
#[fuchsia_async::run_singlethreaded(test)]
async fn test_clear() {
let repo1 = make_readonly_empty_repository("repo1").await.unwrap();
let repo2 = make_readonly_empty_repository("repo2").await.unwrap();
let manager = RepositoryManager::new();
manager.add(Arc::new(repo1));
manager.add(Arc::new(repo2));
manager.clear();
assert!(manager.repositories().next().is_none());
}
}