What Is the openlogi-core Crate in OpenLogi? The Foundation Library Explained
The openlogi-core crate is the foundational library of the OpenLogi project that contains all pure data structures, device models, and configuration logic without any platform-specific dependencies, enabling WebAssembly compilation and type-safe sharing across the entire ecosystem.
The OpenLogi project provides an open-source management layer for HID++ Logitech devices, utilizing a modular Rust architecture to separate concerns between data definitions and platform-specific I/O. The openlogi-core crate serves as the immutable base layer that defines what devices exist, what actions they can perform, and how user configurations are structured, ensuring that business logic remains portable and testable across all supported targets.
Core Responsibilities and Data Models
The crate organizes its functionality into distinct modules, each responsible for a specific domain of the device management logic. This separation allows downstream components to import exactly the types they need without pulling in unrelated functionality.
Device Model (src/device.rs)
The src/device.rs file defines the pure representation of HID++ devices supported by the system. This module contains the Device struct and associated types that describe hardware capabilities, brand information, and device-specific metadata without any reference to actual hardware I/O operations. Because these definitions live in openlogi-core, the GUI, agent, and configuration tools all reference identical device structures.
Action Catalog (src/action_ring.rs)
User interactions are organized into action rings, defined in src/action_ring.rs. This module describes the circular menu of actions that can be bound to device buttons, including icon names, labels, and action types. The ActionRing type provides methods like get(index) to retrieve specific actions, ensuring the UI and configuration layers remain synchronized when displaying available options to users.
Binding Definitions (src/binding/)
The src/binding/ module hierarchy contains exhaustive definitions for input mappings, including key combinations, gestures, and swipe actions. These pure data structures describe what a binding should do without implementing how the system listens for those inputs. By centralizing binding definitions here, openlogi-core ensures that configuration files, validation logic, and runtime execution all agree on the structure of user-defined shortcuts.
Configuration Format (src/config/)
User-editable TOML files are parsed using the types defined in src/config/. This includes the Settings struct and identity management logic that persists user preferences. The module provides platform-agnostic path resolution when the fs feature is enabled, allowing configurations to load from standard directories like $HOME/.config/openlogi/config.toml.
Platform Independence and WebAssembly Support
A critical architectural constraint of openlogi-core is its complete isolation from side effects and platform-specific code. All host-specific functionality—such as HID++ I/O, filesystem access, and locale negotiation—lives in sibling crates like openlogi-device, openlogi-hidpp, and openlogi-agent.
This design enables WebAssembly compilation, verified by the CI job "wasm (portable crates)". Platform-specific capabilities are accessed only through feature-gated modules:
fsfeature: Enablessrc/paths.rsfor filesystem path resolution and single-instance handlinglocalefeature: Enablessrc/locale.rsfor host-language negotiation
Because the core crate compiles without these features, it can target WebAssembly and other restricted environments where system calls are unavailable, while still providing the full data model for web-based configuration tools.
Integration Pattern: Why Every Crate Depends on openlogi-core
The dependency graph of OpenLogi flows strictly upward: every other component imports openlogi-core to share a single source of truth. This guarantees type safety across the entire codebase when evolving the data model.
Consider how the agent and GUI initialize application state:
// Load the user configuration (requires the `fs` feature)
use openlogi_core::config::Settings;
fn load_user_config() -> anyhow::Result<Settings> {
// `Settings::load` reads `$HOME/.config/openlogi/config.toml`
Settings::load()
}
// Create an application instance that holds the runtime state.
// The `app` module contains the high-level entry point used by both GUI and agent.
use openlogi_core::app::App;
use openlogi_core::device::Device;
fn start_app(devices: Vec<Device>) -> App {
// `App::new` builds the state from the list of discovered devices and the
// user configuration.
App::new(devices)
}
// Query the action ring for the icon to display in the UI.
use openlogi_core::action_ring::ActionRing;
fn get_icon_name(ring: &ActionRing, index: usize) -> Option<String> {
ring.get(index).map(|action| action.icon_name().to_string())
}
These patterns demonstrate that all business logic lives in openlogi-core while surrounding crates handle I/O, platform integration, and user interaction.
Key Source Files and Public API
The crate entry point at src/lib.rs controls public module re-exports, while internal organization follows strict domain boundaries:
| File | Purpose |
|---|---|
Cargo.toml |
Declares dependencies and feature flags (fs, locale) |
src/lib.rs |
Public module re-exports; crate entry point |
src/device.rs |
Pure representation of HID++ devices |
src/action_ring.rs |
Definition of the per-device actions ring |
src/binding/ |
Binding types (key combos, gestures, swipe actions) |
src/config/ |
TOML configuration schema and parsing logic |
src/app.rs |
High-level application state used by GUI and agent |
src/locale.rs |
Host-language negotiation (feature-gated) |
src/paths.rs |
Filesystem paths for config/storage (feature-gated) |
src/color.rs |
Shared color definitions |
src/brand.rs |
Brand information constants |
src/diagnostics.rs |
Diagnostic and debugging utilities |
Together, these files constitute the core data layer that powers the entire OpenLogi ecosystem, from command-line configuration to graphical device management.
Summary
-
openlogi-coreserves as the foundation crate containing all pure data structures and business logic for the OpenLogi project. -
It defines device models, action catalogs (
src/action_ring.rs), binding definitions (src/binding/), and configuration formats (src/config/) without platform-specific dependencies. -
The crate compiles to WebAssembly and portable targets because it isolates side effects into feature-gated modules (
fs,locale). -
Every other OpenLogi component imports this crate to ensure type safety and a single source of truth across the codebase.
-
Key integration points include
Settings::load()for configuration,App::new()for state initialization, andActionRingfor UI action definitions.
Frequently Asked Questions
Does openlogi-core handle HID++ communication directly?
No. According to the OpenLogi source code, openlogi-core intentionally contains no platform-specific code or hardware I/O. All HID++ communication, filesystem access, and locale negotiation live in sibling crates like openlogi-hidpp and openlogi-device, accessed only through feature-gated modules when enabled.
Why can openlogi-core compile to WebAssembly?
The crate compiles to WebAssembly because it maintains a strict separation between pure data structures and side effects. By placing filesystem paths (src/paths.rs) and locale handling (src/locale.rs) behind optional feature flags (fs and locale), the core library compiles without system dependencies, enabling the CI job "wasm (portable crates)" to verify WebAssembly targets.
How does openlogi-core ensure type safety across the OpenLogi project?
All components—from the GUI to the background agent—import their domain types exclusively from openlogi-core. This shared dependency means that changes to the Device struct in src/device.rs or the binding types in src/binding/ propagate compile-time verification to every consumer, preventing deserialization errors and logic mismatches between configuration and runtime.
What are the main feature flags available in openlogi-core?
The crate exposes two primary feature flags: fs, which enables filesystem path resolution and configuration loading via src/paths.rs, and locale, which enables host-language negotiation via src/locale.rs. Both are disabled by default to maintain portability, allowing the crate to function in sandboxed environments like browsers or embedded systems.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →