refactor: add upm application facade and module api
This commit is contained in:
parent
005d6ebfdb
commit
e2a01d3095
36 changed files with 1058 additions and 607 deletions
|
|
@ -11,4 +11,7 @@ path = "src/lib.rs"
|
|||
quick-xml.workspace = true
|
||||
reqwest.workspace = true
|
||||
serde.workspace = true
|
||||
upm-module-api = { path = "../upm-module-api" }
|
||||
|
||||
[dev-dependencies]
|
||||
upm-core = { path = "../upm-core" }
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
use crate::source::appimagehub::{
|
||||
AppImageHubError, AppImageHubTransport, resolve_appimagehub_item, resolve_appimagehub_item_with,
|
||||
};
|
||||
use upm_core::adapters::traits::{
|
||||
use upm_module_api::adapters::traits::{
|
||||
AdapterCapabilities, AdapterError, AdapterResolution, AdapterResolveOutcome, SourceAdapter,
|
||||
};
|
||||
use upm_core::app::providers::{ExternalAddProvider, ExternalAddResolution};
|
||||
use upm_core::app::query::resolve_query;
|
||||
use upm_core::domain::source::{ResolvedRelease, SourceKind, SourceRef};
|
||||
use upm_core::domain::update::{
|
||||
use upm_module_api::app::providers::{ExternalAddProvider, ExternalAddResolution};
|
||||
use upm_module_api::domain::source::{
|
||||
NormalizedSourceKind, ResolvedRelease, SourceInputKind, SourceKind, SourceRef,
|
||||
};
|
||||
use upm_module_api::domain::update::{
|
||||
ArtifactCandidate, ChannelPreference, UpdateChannelKind, UpdateStrategy,
|
||||
};
|
||||
|
||||
|
|
@ -58,7 +59,7 @@ impl SourceAdapter for AppImageHubAdapter {
|
|||
}
|
||||
|
||||
fn normalize(&self, query: &str) -> Result<SourceRef, AdapterError> {
|
||||
let source = resolve_query(query).map_err(|_| AdapterError::UnsupportedQuery)?;
|
||||
let source = resolve_appimagehub_query(query)?;
|
||||
if source.kind != SourceKind::AppImageHub {
|
||||
return Err(AdapterError::UnsupportedQuery);
|
||||
}
|
||||
|
|
@ -92,17 +93,17 @@ impl SourceAdapter for AppImageHubAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct AppImageHubAddProvider<'a, T: AppImageHubTransport + ?Sized> {
|
||||
transport: &'a T,
|
||||
pub struct AppImageHubAddProvider {
|
||||
transport: Box<dyn AppImageHubTransport>,
|
||||
}
|
||||
|
||||
impl<'a, T: AppImageHubTransport + ?Sized> AppImageHubAddProvider<'a, T> {
|
||||
pub fn new(transport: &'a T) -> Self {
|
||||
impl AppImageHubAddProvider {
|
||||
pub fn new(transport: Box<dyn AppImageHubTransport>) -> Self {
|
||||
Self { transport }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AppImageHubTransport + ?Sized> ExternalAddProvider for AppImageHubAddProvider<'_, T> {
|
||||
impl ExternalAddProvider for AppImageHubAddProvider {
|
||||
fn id(&self) -> &'static str {
|
||||
"appimagehub"
|
||||
}
|
||||
|
|
@ -113,11 +114,11 @@ impl<T: AppImageHubTransport + ?Sized> ExternalAddProvider for AppImageHubAddPro
|
|||
}
|
||||
|
||||
let adapter = AppImageHubAdapter;
|
||||
let resolution = match adapter.resolve_source_with(source, self.transport)? {
|
||||
let resolution = match adapter.resolve_source_with(source, self.transport.as_ref())? {
|
||||
AdapterResolveOutcome::Resolved(resolution) => resolution,
|
||||
AdapterResolveOutcome::NoInstallableArtifact { .. } => return Ok(None),
|
||||
};
|
||||
let Some(resolved_item) = resolve_appimagehub_item_with(source, self.transport)
|
||||
let Some(resolved_item) = resolve_appimagehub_item_with(source, self.transport.as_ref())
|
||||
.map_err(|error| AdapterError::ResolutionFailed(format!("{error:?}")))?
|
||||
else {
|
||||
return Ok(None);
|
||||
|
|
@ -161,3 +162,35 @@ fn render_appimagehub_error(error: &AppImageHubError) -> String {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_appimagehub_query(query: &str) -> Result<SourceRef, AdapterError> {
|
||||
let trimmed = query.trim();
|
||||
let id = if let Some(id) = trimmed.strip_prefix("appimagehub/") {
|
||||
id
|
||||
} else if let Some(id) = trimmed.strip_prefix("https://www.appimagehub.com/p/") {
|
||||
id
|
||||
} else if let Some(id) = trimmed.strip_prefix("http://www.appimagehub.com/p/") {
|
||||
id
|
||||
} else {
|
||||
return Err(AdapterError::UnsupportedQuery);
|
||||
};
|
||||
|
||||
if !id.chars().all(|ch| ch.is_ascii_digit()) {
|
||||
return Err(AdapterError::UnsupportedQuery);
|
||||
}
|
||||
|
||||
Ok(SourceRef {
|
||||
kind: SourceKind::AppImageHub,
|
||||
locator: format!("https://www.appimagehub.com/p/{id}"),
|
||||
input_kind: if trimmed.starts_with("appimagehub/") {
|
||||
SourceInputKind::AppImageHubShorthand
|
||||
} else {
|
||||
SourceInputKind::AppImageHubUrl
|
||||
},
|
||||
normalized_kind: NormalizedSourceKind::AppImageHub,
|
||||
canonical_locator: Some(id.to_owned()),
|
||||
requested_tag: None,
|
||||
requested_asset_name: None,
|
||||
tracks_latest: true,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,29 @@
|
|||
use crate::source::appimagehub::{
|
||||
AppImageHubSearchError, AppImageHubTransport, search_appimagehub_with,
|
||||
};
|
||||
use upm_core::app::search::{SearchProvider, SearchProviderError};
|
||||
use upm_core::domain::search::{SearchInstallStatus, SearchQuery, SearchResult};
|
||||
use upm_module_api::app::search::{SearchProvider, SearchProviderError};
|
||||
use upm_module_api::domain::search::{SearchInstallStatus, SearchQuery, SearchResult};
|
||||
|
||||
pub struct AppImageHubSearchProvider<'a, T: AppImageHubTransport + ?Sized> {
|
||||
transport: &'a T,
|
||||
pub struct AppImageHubSearchProvider {
|
||||
transport: Box<dyn AppImageHubTransport>,
|
||||
}
|
||||
|
||||
impl<'a, T: AppImageHubTransport + ?Sized> AppImageHubSearchProvider<'a, T> {
|
||||
pub fn new(transport: &'a T) -> Self {
|
||||
impl AppImageHubSearchProvider {
|
||||
pub fn new(transport: Box<dyn AppImageHubTransport>) -> Self {
|
||||
Self { transport }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AppImageHubTransport + ?Sized> SearchProvider for AppImageHubSearchProvider<'_, T> {
|
||||
impl SearchProvider for AppImageHubSearchProvider {
|
||||
fn search(&self, query: &SearchQuery) -> Result<Vec<SearchResult>, SearchProviderError> {
|
||||
let hits = search_appimagehub_with(&query.text, query.remote_limit, self.transport)
|
||||
.map_err(|error| {
|
||||
SearchProviderError::new("appimagehub", &render_appimagehub_search_error(&error))
|
||||
})?;
|
||||
let hits =
|
||||
search_appimagehub_with(&query.text, query.remote_limit, self.transport.as_ref())
|
||||
.map_err(|error| {
|
||||
SearchProviderError::new(
|
||||
"appimagehub",
|
||||
&render_appimagehub_search_error(&error),
|
||||
)
|
||||
})?;
|
||||
|
||||
let normalized_query = normalize_lookup(&query.text);
|
||||
let mut ranked_hits = hits
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::env;
|
||||
use std::time::Duration;
|
||||
|
||||
use upm_core::domain::source::SourceRef;
|
||||
use upm_module_api::domain::source::SourceRef;
|
||||
|
||||
const DEFAULT_APPIMAGEHUB_API_BASE: &str = "https://api.appimagehub.com/ocs/v1/content";
|
||||
const GLOBAL_FIXTURE_MODE_ENV: &str = "UPM_FIXTURE_MODE";
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ impl SearchProvider for StubProvider {
|
|||
|
||||
#[test]
|
||||
fn appimagehub_search_provider_maps_hits_to_install_ready_results() {
|
||||
let provider = AppImageHubSearchProvider::new(&FixtureAppImageHubTransport);
|
||||
let provider = AppImageHubSearchProvider::new(Box::new(FixtureAppImageHubTransport));
|
||||
|
||||
let results = provider.search(&SearchQuery::new("firefox")).unwrap();
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ fn appimagehub_search_provider_maps_hits_to_install_ready_results() {
|
|||
|
||||
#[test]
|
||||
fn appimagehub_hits_are_annotated_as_installed_by_canonical_id() {
|
||||
let provider = AppImageHubSearchProvider::new(&FixtureAppImageHubTransport);
|
||||
let provider = AppImageHubSearchProvider::new(Box::new(FixtureAppImageHubTransport));
|
||||
let installed = vec![AppRecord {
|
||||
stable_id: "firefox".to_owned(),
|
||||
display_name: "Firefox by Mozilla - Official AppImage Edition".to_owned(),
|
||||
|
|
@ -76,7 +76,7 @@ fn appimagehub_hits_are_annotated_as_installed_by_canonical_id() {
|
|||
#[test]
|
||||
fn search_can_merge_github_and_appimagehub_providers() {
|
||||
let github = GitHubSearchProvider::new(&FixtureGitHubTransport);
|
||||
let appimagehub = AppImageHubSearchProvider::new(&FixtureAppImageHubTransport);
|
||||
let appimagehub = AppImageHubSearchProvider::new(Box::new(FixtureAppImageHubTransport));
|
||||
let stub = StubProvider {
|
||||
hit: SearchResult {
|
||||
provider_id: "github".to_owned(),
|
||||
|
|
@ -131,7 +131,7 @@ fn appimagehub_adapter_resolves_installable_items_through_fixture_transport() {
|
|||
|
||||
#[test]
|
||||
fn appimagehub_add_provider_resolves_external_add_plan() {
|
||||
let provider = AppImageHubAddProvider::new(&FixtureAppImageHubTransport);
|
||||
let provider = AppImageHubAddProvider::new(Box::new(FixtureAppImageHubTransport));
|
||||
let source = resolve_query("appimagehub/2338455").unwrap();
|
||||
|
||||
let resolution = provider.resolve(&source).unwrap().unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue