5.2 KiB
Built-in Providers Migration — Design Spec
Goal
Move calculator, converter, and system from external .so plugins (owlry-plugins repo) to native providers compiled into owlry-core. Remove 3 plugin AUR packages (transitional), 4 meta AUR packages (already deleted). Update READMEs for both repos.
Architecture
The 3 plugins currently use the FFI plugin API (PluginVTable, PluginItem, etc.) and are loaded as .so files by NativePluginLoader. As built-in providers, they become native Rust modules inside owlry-core/src/providers/ implementing the existing Provider trait — same as ApplicationProvider and CommandProvider.
No changes to the plugin system itself. External plugins continue to work via .so loading.
Components
New modules in owlry-core
providers/calculator.rs— port of owlry-plugin-calculator (231 lines, depends onmeval)providers/converter/mod.rs— port of owlry-plugin-converter entry pointproviders/converter/parser.rs— query parsing (235 lines, no new deps)providers/converter/units.rs— unit definitions + conversion (944 lines, no new deps)providers/converter/currency.rs— ECB rate fetching (313 lines, depends onreqwestblocking +dirs+serde)providers/system.rs— port of owlry-plugin-system (257 lines, no new deps)
New owlry-core dependencies
meval— math expression evaluation (currently optional behindluafeature, make required)reqwestwithblockingfeature — ECB currency rate fetching (currently optional behindlua, make required)dirs— already a dependencyserde/serde_json— already dependencies
Modified files
owlry-core/src/providers/mod.rs— register the 3 new providers inProviderManager, honor config toggles, classify calculator+converter as dynamic providersowlry-core/Cargo.toml— movemevalandreqwestfrom optional to requiredowlry-core/src/config/mod.rs— addconverterconfig toggle (calculator and system already exist)
Provider classification
- Calculator → dynamic (queried per-keystroke via
query()) - Converter → dynamic (queried per-keystroke via
query()) - System → static (populated at
refresh(), returns fixed list of actions)
Provider Type IDs
Built-in providers use ProviderType::Plugin(String) with fixed IDs to maintain backward compatibility with the UI highlighting and filter system:
- Calculator:
ProviderType::Plugin("calc".into()) - Converter:
ProviderType::Plugin("conv".into()) - System:
ProviderType::Plugin("sys".into())
This ensures the UI's highlighting logic (matches!(id.as_str(), "calc" | "conv")) and CSS badge classes (.owlry-badge-calc, .owlry-badge-sys) continue to work without changes.
Config
Existing toggles in [providers]:
[providers]
calculator = true # already exists
system = true # already exists
converter = true # new — add with default true
When a toggle is false, the provider is not registered in ProviderManager at startup.
Currency Conversion
The converter's currency feature uses reqwest (blocking) to fetch ECB exchange rates with a 24-hour file cache at ~/.cache/owlry/ecb_rates.json. If the HTTP fetch fails (no network, timeout), currency conversion silently returns no results — unit conversion still works. This matches current plugin behavior.
AUR Changes
Main repo (owlry)
aur/owlry-core/PKGBUILD— bump version- Remove
aur/owlry-meta-*directories (4 dirs, already deleted from AUR)
Plugins repo (owlry-plugins)
- Remove crates:
owlry-plugin-calculator,owlry-plugin-converter,owlry-plugin-system - Remove AUR dirs:
aur/owlry-plugin-calculator,aur/owlry-plugin-converter,aur/owlry-plugin-systemfrom tracked files - Push transitional PKGBUILDs to the 3 AUR repos:
pkgname=owlry-plugin-calculator # (and converter, system)
pkgver=<last_version>
pkgrel=99
pkgdesc="Transitional package — calculator is now built into owlry-core"
arch=('any')
depends=('owlry-core>=<new_version>')
replaces=('owlry-plugin-calculator')
# No source, no build, no package body
Conflict prevention
When owlry-core gains built-in calculator/converter/system, users who have the old .so plugins installed will have both the built-in provider AND the .so plugin active — duplicate results. The daemon should detect this: if a built-in provider ID matches a loaded native plugin ID, skip the native plugin. Add this check in ProviderManager when registering native plugins.
README Updates
Main repo README
- Package table: remove separate plugin entries for calculator, converter, system — note them as built-in to owlry-core
- Remove meta package section entirely
- Update install examples (no need to install calculator/converter/system separately)
Plugins repo README
- Remove calculator, converter, system from plugin listing
- Add note that these 3 are built into owlry-core
Testing
- Port existing plugin tests directly — they test provider logic, not FFI wrappers
cargo test -p owlry-core --libcovers all 3 new providers- Add conflict detection test (built-in provider ID vs native plugin ID)
- Manual verification:
= 5+3(calc),20F(conv),20 euro to dollar(currency), system actions