rs-histver
A CLI tool and library for querying Rust historical release versions with local redb cache. Supports stable, beta, and nightly channels.
Installation
Or build from source:
Quick Start
# Sync stable releases to local cache
# Sync full stable history (all releases)
# Sync nightly releases from the last 30 days
# Sync beta releases from the last 14 days
# List cached releases
# List nightly releases
# Search releases
# Show cache statistics
Commands
Global Options
| Option | Description |
|---|---|
-h, --help |
Show help |
-V, --version |
Show version |
sync — Sync release data
Fetch release information from remote and cache to local redb database.
| Option | Default | Description |
|---|---|---|
-c, --channel <CHANNEL> |
stable |
Channel: stable / beta / nightly |
--full |
— | Use RELEASES.md data source (stable only, full history) |
-d, --days <DAYS> |
30 |
Probe recent N days of history (beta/nightly only) |
Data sources:
| Channel | Default source | --full source |
|---|---|---|
| stable | GitHub Releases API | RELEASES.md (full history) |
| beta | dist/YYYY-MM-DD/channel-rust-beta.toml date probing |
— |
| nightly | dist/YYYY-MM-DD/channel-rust-nightly.toml date probing |
— |
list — List cached releases
| Option | Default | Description |
|---|---|---|
-n, --limit <N> |
20 |
Maximum entries to display |
-c, --channel <CHANNEL> |
all | Filter by channel |
search — Search releases
Fuzzy match by version number or date.
| Argument/Option | Description |
|---|---|
<KEYWORD> |
Search keyword, e.g. 1.75 or 2024-06 |
-c, --channel <CHANNEL> |
Filter by channel |
info — Cache statistics
| Option | Description |
|---|---|
-c, --channel <CHANNEL> |
Filter by channel |
Database
The local cache uses redb with per-channel tables for efficient filtering:
rs_histver_stable— key: date, value: versionrs_histver_beta— key: date, value: versionrs_histver_nightly— key: date, value: version
Default path
Database file is automatically created at:
<executable_directory>/data/rs-histver.redb
No configuration file is needed. The data/ directory is created automatically on first use.
Database Modes
rs-histver supports two database modes, determined by the shared flag in DatabaseConfig:
| Mode | shared |
Trigger Condition | Database File | Table Prefix |
|---|---|---|---|---|
| Standalone (default) | false |
No db_file configured |
<data_dir>/rs-histver.redb |
rs_histver |
| Shared | true |
db_file is set |
<data_dir>/<db_file> |
Custom (recommended) |
Standalone Mode
Creates a dedicated rs-histver.redb file. This is the default behavior and requires no special configuration.
Triggered when:
- Using
Config::new()— default configuration - Using
Config::with_db_path(path)— custom path, always standalone - Using
ConfigBuilderwithoutdb_file()— even with customdata_dir() - config.toml without
[rs-histver.database].db_file
Shared Mode
Opens the host project's existing redb database file, using table_prefix to avoid table name collisions.
Triggered when:
db_fileis set viaConfigBuilder::db_file()method- config.toml contains
[rs-histver.database].db_filefield
Important: When db_file is set but table_prefix remains at its default value (rs_histver), a warning is printed to stderr to prevent potential table name collisions with other applications using the same database.
Automatic Fallback Behavior
Shared mode includes intelligent error recovery:
| Scenario | Behavior |
|---|---|
| Target file is not a valid redb database | Falls back to standalone mode, creates rs-histver.redb in same directory |
Database format version incompatible (UpgradeRequired) |
Deletes old file and recreates (standalone mode) |
Database file corrupted (StorageError::Corrupted) |
Falls back to standalone mode |
| Table does not exist during read | Returns empty result (not an error) |
Configuration via config.toml
When embedded in a host project, the database path can be read from the host's config.toml:
[]
# Supported variable substitution:
# $EXE_DIR — executable directory
# $HOME — user home directory
# ~/ — user home directory (shorthand)
= "$EXE_DIR/data"
[]
= "myapp.redb" # shared: open host's redb file
= "myapp_histver" # table names: myapp_histver_stable/beta/nightly
[]
= 30 # optional, default: 15 (seconds)
= 5 # optional, default: 10
- Without
db_file: standalone mode — creates<data_dir>/rs-histver.redb - With
db_file: shared mode — opens the host's redb file, usestable_prefixto avoid collisions - If
db_filepoints to a non-redb file, it automatically falls back to standalone mode
See Library Usage — Embedded in Host Project for code examples.
Note: If upgrading from v0.1.x, the database format has changed. The old database will be automatically recreated on first run.
Project Structure
src/
├── lib.rs # Library entry point (HistVer, Config, public API)
├── main.rs # CLI entry point
├── cli.rs # CLI module root
│ └── cli/
│ └── types.rs # Channel enum, Cli, Commands definitions
├── domain.rs # Domain module root
│ └── domain/
│ └── release.rs # RustRelease data model
├── infra.rs # Infrastructure module root
│ ├── infra/
│ │ ├── config.rs # Configuration (Config, DatabaseConfig, NetworkConfig)
│ │ ├── database.rs # Database access layer (Db, redb)
│ │ └── fetcher.rs # ReleaseFetcher trait + create_fetcher factory
│ └── infra/fetcher/
│ ├── http.rs # Shared HTTP client & TOML utilities
│ ├── stable.rs # StableFetcher (GitHub API / RELEASES.md)
│ ├── beta.rs # BetaFetcher (channel TOML probing)
│ └── nightly.rs # NightlyFetcher (channel TOML probing)
└── app.rs # Application module root
└── app/
├── handler.rs # App struct + business logic
└── display.rs # Table formatting utilities
API Documentation
Full API documentation is available on docs.rs.
Usage as a Library
Add to your Cargo.toml:
[]
= "0.2.1"
Standalone Usage
use ;
async
Embedded in Host Project
When embedded in a host project (e.g. Tauri app), the database path should be determined by the host's configuration. Use ConfigBuilder or Config::from_config_file() to achieve this.
Standalone mode (default):
Creates a dedicated rs-histver.redb file in data_dir.
use ;
let hv = new?;
Shared mode (host uses redb):
When the host project also uses redb, you can share the same database file. Configure db_file to point to the host's redb file, and table_prefix to avoid table name collisions.
use ;
// From config file
let hv = new?;
// Or programmatically
use ConfigBuilder;
let hv = new?;
If db_file points to a non-redb file, it automatically falls back to standalone mode (creates rs-histver.redb in the same directory).
Priority order:
Programmatic override (highest) → config.toml → hardcoded defaults (lowest)
db_path()overrides everything (complete file path, always standalone mode)db_file()enables shared mode, combined withdata_dir()data_dir()alone → standalone mode:<data_dir>/rs-histver.redbtable_prefix()/timeout()/max_concurrency()override config.toml values- Missing config file or fields fall back to defaults silently
Variable substitution in config.toml:
| Variable | Resolves to | Example (Windows) |
|---|---|---|
$EXE_DIR |
Executable directory | C:\Program Files\MyApp |
$HOME |
User home (%USERPROFILE% / $HOME) |
C:\Users\user |
~/ |
User home (same as $HOME) |
~/data → C:\Users\user\data |
Variable substitution only applies to paths read from config.toml. Programmatic data_dir() / db_path() accept resolved PathBuf values.
Design Patterns
- Strategy Pattern:
ReleaseFetchertrait — each channel implements its own fetch logic - Factory Method:
create_fetcher()— creates the appropriate fetcher based on channel name
License
Licensed under either of Apache License, Version 2.0 or MIT License at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.