use std::sync::Arc;
use vs_core::{App, CoreError, InstalledVersion, UninstallResult};
use crate::model::{
AddSource, ScopeChoice, ToolRow, VersionRow, available_rows, installed_rows, merge_tool_rows,
};
#[derive(Clone)]
pub struct AppService {
core: Arc<App>,
}
impl AppService {
pub fn new(core: App) -> Self {
Self {
core: Arc::new(core),
}
}
pub fn tool_rows(&self) -> Result<Vec<ToolRow>, CoreError> {
let names = self
.core
.added_plugins()?
.into_iter()
.map(|entry| entry.name)
.collect::<Vec<_>>();
let statuses = self.core.current_tool_statuses()?;
Ok(merge_tool_rows(names, statuses))
}
pub fn installed_rows(&self, name: &str) -> Result<Vec<VersionRow>, CoreError> {
let installed = self
.core
.installed_versions_for_plugin(name)?
.into_iter()
.map(|v| v.version)
.collect::<Vec<_>>();
let current = self.core.current_tool(name)?.map(|c| c.version);
Ok(installed_rows(installed, current.as_deref()))
}
pub fn search_available(&self, name: &str, query: &str) -> Result<Vec<VersionRow>, CoreError> {
let args: Vec<String> = if query.is_empty() {
Vec::new()
} else {
vec![query.to_string()]
};
let found = self
.core
.search_versions(name, &args)?
.into_iter()
.map(|v| v.version)
.collect::<Vec<_>>();
let installed = self
.core
.installed_versions_for_plugin(name)?
.into_iter()
.map(|v| v.version)
.collect::<Vec<_>>();
Ok(available_rows(found, &installed))
}
pub fn install_with_progress(
&self,
name: &str,
version: &str,
on_progress: &vs_core::ProgressFn<'_>,
) -> Result<InstalledVersion, CoreError> {
self.core
.install_plugin_version(name, Some(version), Some(on_progress))
}
pub fn use_version(
&self,
name: &str,
version: &str,
scope: ScopeChoice,
) -> Result<InstalledVersion, CoreError> {
self.core
.use_tool(name, version, scope.to_use_scope(), false)
}
pub fn uninstall(&self, name: &str, version: &str) -> Result<UninstallResult, CoreError> {
self.core.uninstall_plugin_version(name, version)
}
pub fn registry_plugin_names(&self) -> Result<Vec<String>, CoreError> {
Ok(self
.core
.available_plugins()?
.into_iter()
.map(|entry| entry.name)
.collect())
}
pub fn add(&self, source: AddSource) -> Result<(), CoreError> {
match source {
AddSource::Registry { name } => {
self.core.add_plugin(Some(&name), None, None, None)?;
}
AddSource::Source {
source,
alias,
backend,
} => {
self.core.add_plugin(
None,
Some(source),
Some(backend.to_kind()),
alias.as_deref(),
)?;
}
}
Ok(())
}
pub fn update_plugin(&self, name: &str) -> Result<(), CoreError> {
self.core.update_plugin(name)?;
Ok(())
}
pub fn remove_plugin(&self, name: &str) -> Result<bool, CoreError> {
self.core.remove_plugin(name)
}
pub fn refresh_registry(&self) -> Result<usize, CoreError> {
self.core.update_registry()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn app_service_is_send_and_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<AppService>();
}
}