use anyhow::Result;
use futures::future::join_all;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use crate::api::deps_dev::{Client as DepsDevClient, PackageInfo, PackageRef};
use crate::api::github::{Client as GhClient, Repository};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct AdoptionRawData {
pub packages: Vec<PackageInfo>,
pub deps_dev_error: bool,
pub has_readme: bool,
pub readme_word_count: Option<usize>,
pub has_docs_dir: bool,
pub has_examples_dir: bool,
pub awesome_list_mentions: Vec<String>,
pub archived: bool,
}
pub async fn collect(
github: &GhClient,
deps_dev: &DepsDevClient,
owner: &str,
repo: &str,
_now: OffsetDateTime,
) -> Result<(Repository, AdoptionRawData)> {
let metadata = github.get_repo(owner, repo).await?;
let (packages, deps_dev_error) = match deps_dev.project_packages(owner, repo).await {
Ok(refs) => fetch_packages(deps_dev, &refs).await,
Err(_) => (Vec::new(), true),
};
let readme_fut = github.get_readme(owner, repo);
let docs_fut = github.file_exists(owner, repo, "docs");
let examples_fut = github.file_exists(owner, repo, "examples");
let (readme_result, docs_result, examples_result) =
tokio::try_join!(readme_fut, docs_fut, examples_fut)?;
let (has_readme, readme_word_count) = match readme_result {
Some(text) => {
let count = text.split_whitespace().count();
(true, Some(count))
},
None => (false, None),
};
let raw = AdoptionRawData {
packages,
deps_dev_error,
has_readme,
readme_word_count,
has_docs_dir: docs_result,
has_examples_dir: examples_result,
awesome_list_mentions: Vec::new(),
archived: metadata.archived,
};
Ok((metadata, raw))
}
async fn fetch_packages(deps_dev: &DepsDevClient, refs: &[PackageRef]) -> (Vec<PackageInfo>, bool) {
if refs.is_empty() {
return (Vec::new(), false);
}
let results = join_all(refs.iter().map(|r| deps_dev.package(&r.system, &r.name))).await;
let mut packages: Vec<PackageInfo> = Vec::with_capacity(results.len());
let mut had_error = false;
for r in results {
match r {
Ok(p) => packages.push(p),
Err(_) => had_error = true,
}
}
if had_error && packages.is_empty() {
return (Vec::new(), true);
}
(packages, false)
}