arch_toolkit/index/mod.rs
1//! Index module for package database queries and management.
2//!
3//! This module provides functionality for querying and managing package database information:
4//!
5//! - **Installed Package Queries** - Query installed packages using `pacman -Q*` commands
6//! - **Explicit Package Tracking** - Track explicitly installed packages with different modes
7//! - **Official Repository Queries** - Search and query official Arch Linux repositories
8//! - **Index Fetching** - Fetch official package index from pacman or Arch Packages API
9//!
10//! # Features
11//!
12//! This module requires the `index` feature flag to be enabled:
13//!
14//! ```toml
15//! [dependencies]
16//! arch-toolkit = { version = "0.2", features = ["index"] }
17//! ```
18//!
19//! For fuzzy search functionality, enable the `fuzzy-search` feature:
20//!
21//! ```toml
22//! [dependencies]
23//! arch-toolkit = { version = "0.2", features = ["index", "fuzzy-search"] }
24//! ```
25//!
26//! For API fallback when pacman is unavailable, enable the `aur` feature:
27//!
28//! ```toml
29//! [dependencies]
30//! arch-toolkit = { version = "0.2", features = ["index", "aur"] }
31//! ```
32//!
33//! # Examples
34//!
35//! ## Query Installed Packages
36//!
37//! ```no_run
38//! use arch_toolkit::index::{get_installed_packages, is_installed};
39//! use std::collections::HashSet;
40//!
41//! // Direct query without caching
42//! let packages = get_installed_packages().unwrap();
43//! println!("Found {} installed packages", packages.len());
44//!
45//! // Check if a package is installed
46//! if is_installed("vim", Some(&packages)) {
47//! println!("vim is installed");
48//! }
49//! ```
50//!
51//! ## Use Cache for Multiple Queries
52//!
53//! ```no_run
54//! use arch_toolkit::index::{refresh_installed_cache, is_installed};
55//! use std::collections::HashSet;
56//!
57//! let mut cache = HashSet::new();
58//! refresh_installed_cache(Some(&mut cache)).unwrap();
59//!
60//! // Now use cache for fast lookups
61//! for package in ["vim", "git", "python"] {
62//! if is_installed(package, Some(&cache)) {
63//! println!("{} is installed", package);
64//! }
65//! }
66//! ```
67//!
68//! ## Async Cache Refresh
69//!
70//! ```no_run
71//! use arch_toolkit::index::refresh_installed_cache_async;
72//! use std::collections::HashSet;
73//!
74//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
75//! let mut cache = HashSet::new();
76//! let packages = refresh_installed_cache_async(Some(&mut cache)).await?;
77//! println!("Refreshed cache with {} packages", packages.len());
78//! # Ok(())
79//! # }
80//! ```
81//!
82//! ## Query Explicit Packages
83//!
84//! ```no_run
85//! use arch_toolkit::index::{refresh_explicit_cache, is_explicit, InstalledPackagesMode};
86//! use std::collections::HashSet;
87//!
88//! let mut cache = HashSet::new();
89//! // Get all explicitly installed packages
90//! refresh_explicit_cache(InstalledPackagesMode::AllExplicit, Some(&mut cache)).unwrap();
91//!
92//! // Check if a package is explicitly installed
93//! if is_explicit("vim", InstalledPackagesMode::AllExplicit, Some(&cache)) {
94//! println!("vim is explicitly installed");
95//! }
96//!
97//! // Get only leaf packages (not required by others)
98//! let leaf_packages = refresh_explicit_cache(InstalledPackagesMode::LeafOnly, None).unwrap();
99//! println!("Found {} leaf packages", leaf_packages.len());
100//! ```
101//!
102//! ## Search Official Packages
103//!
104//! ```no_run
105//! use arch_toolkit::index::{fetch_official_index_async, search_official};
106//!
107//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
108//! // Fetch the official index
109//! let index = fetch_official_index_async().await?;
110//!
111//! // Search for packages (substring matching)
112//! let results = search_official(&index, "vim", false);
113//! for result in results {
114//! println!("{}: {}", result.package.name, result.package.version);
115//! }
116//!
117//! // Fuzzy search (requires fuzzy-search feature)
118//! let fuzzy_results = search_official(&index, "rg", true);
119//! for result in fuzzy_results {
120//! println!("{} (score: {:?})", result.package.name, result.fuzzy_score);
121//! }
122//! # Ok(())
123//! # }
124//! ```
125//!
126//! ## Get All Official Packages
127//!
128//! ```no_run
129//! use arch_toolkit::index::{all_official, fetch_official_index};
130//!
131//! let index = fetch_official_index()?;
132//! let all_packages = all_official(&index);
133//! println!("Found {} official packages", all_packages.len());
134//! # Ok::<(), arch_toolkit::error::ArchToolkitError>(())
135//! ```
136//!
137//! ## Persist the Index to Disk
138//!
139//! ```no_run
140//! use arch_toolkit::index::{fetch_official_index, load_from_disk, save_to_disk};
141//! use std::path::Path;
142//!
143//! let path = Path::new("official_index.json");
144//!
145//! // Load a cached index, falling back to a fresh fetch
146//! let index = load_from_disk(path).or_else(|_| fetch_official_index())?;
147//!
148//! // Save the index for the next session
149//! save_to_disk(&index, path)?;
150//! # Ok::<(), arch_toolkit::error::ArchToolkitError>(())
151//! ```
152
153mod explicit;
154mod fetch;
155mod installed;
156mod mirrors;
157mod persist;
158mod query;
159mod refresh;
160
161// Re-export types from types module
162pub use crate::types::index::{
163 IndexQueryResult, InstalledPackagesMode, MirrorDiscoveryLimits, MirrorInfo, OfficialIndex,
164 OfficialPackage,
165};
166
167// Re-export installed functions
168pub use installed::{
169 get_installed_packages, is_installed, refresh_installed_cache, refresh_installed_cache_async,
170};
171
172// Re-export explicit functions
173pub use explicit::{is_explicit, refresh_explicit_cache, refresh_explicit_cache_async};
174
175// Re-export query functions
176pub use query::{all_official, search_official};
177
178// Re-export caller-client mirror discovery and pure mirrorlist generation
179pub use mirrors::{
180 ARCH_MIRROR_STATUS_URL, MAX_MIRRORLIST_BYTES, fetch_arch_mirrors, fetch_mirrors_from,
181 generate_mirrorlist,
182};
183
184// Re-export cancellable background refresh
185pub use refresh::{IndexRefreshHandle, spawn_index_refresh};
186
187// Re-export fetch functions
188#[cfg(feature = "index")]
189pub use fetch::{
190 detect_enabled_repos, detect_enabled_repos_from, fetch_official_index,
191 fetch_official_index_async, fetch_official_index_for_repos,
192 fetch_official_index_for_repos_async,
193};
194
195// Re-export persist functions
196pub use persist::{load_from_disk, load_from_disk_or_default, save_to_disk};
197#[cfg(feature = "index")]
198pub use persist::{load_from_disk_async, save_to_disk_async};