rs-histver
A Rust library and CLI tool for querying historical release versions of the Rust programming language (stable, beta, nightly) via GitHub Releases API and rust-lang.org distribution server.
As a library: One function call, pure in-memory result, zero file-system side effects, minimal dependencies.
As a CLI: Terminal-based query tool with formatted table output (optional feature).
Table of Contents
- Features
- Installation
- Library Usage
- CLI Usage
- Architecture
- API Reference
- Data Sources
- Feature Flags
- Development
- License
Features
- Dual Mode: Use as a Rust library or standalone CLI tool
- Optional CLI: CLI dependencies (
clap,comfy-table) are optional — library users get minimal dependency footprint - Zero Side Effects: Library mode has no database, config file, or file system dependencies
- Multiple Channels: Query stable, beta, and nightly release channels
- Flexible Data Sources: GitHub API for recent releases, RELEASES.md for complete history
- Concurrent Fetching: Configurable concurrency control with semaphore-based rate limiting
- Type-Safe: Leverages Rust's type system for compile-time error prevention
- Well-Documented: Comprehensive inline documentation with examples
Installation
Library Only (Recommended)
Add to your Cargo.toml for minimal dependencies:
[]
= "0.4"
This installs only the library with no CLI dependencies (clap, comfy-table), resulting in:
- Smaller dependency tree
- Faster compilation
- Smaller binary size
Library + CLI Binary
To use both library and CLI tool:
[]
= { = "0.4", = ["cli"] }
Or install the CLI binary globally:
Or build from source:
Library Usage
Basic Example
use ;
async
Advanced Usage
use ;
use Duration;
async
Low-Level API
For advanced use cases, use the create_fetcher factory function and ReleaseFetcher trait directly:
use ;
async
CLI Usage
Quick Start
# Fetch stable releases (default: GitHub API, recent 30 days)
# Fetch full stable history from RELEASES.md
# Fetch nightly releases from the last 30 days
# Fetch beta releases from the last 14 days
Commands
| Command | Description |
|---|---|
fetch [-c CHANNEL] [--full] [-d DAYS] |
Fetch release data from remote source |
Options
| Option | Default | Description |
|---|---|---|
-c, --channel <CHANNEL> |
stable |
Release channel: stable, beta, or nightly |
--full |
false |
Use RELEASES.md for complete stable history |
-d, --days <DAYS> |
30 |
Days to probe for beta/nightly channels |
Examples
# Stable channel (GitHub API, ~1500 releases)
# Stable channel (RELEASES.md, complete history)
# Beta channel (probe last 30 days)
# Nightly channel (probe last 7 days)
Architecture
Project Structure
rs-histver/
├── src/
│ ├── lib.rs # Library entry point
│ ├── main.rs # CLI entry point (conditional)
│ ├── constants.rs # Centralized constants
│ ├── domain.rs # Domain models
│ │ └── release.rs # RustRelease struct
│ ├── options.rs # FetchOptions & NetworkConfig
│ ├── app/ # Application layer (CLI only)
│ │ ├── handler.rs # Business logic
│ │ └── display.rs # Table formatting
│ ├── cli/ # CLI layer (CLI only)
│ │ └── types.rs # Clap definitions
│ └── infra/ # Infrastructure layer
│ ├── fetcher.rs # ReleaseFetcher trait & factory
│ └── fetcher/
│ ├── stable.rs # Stable channel implementation
│ ├── beta.rs # Beta channel implementation
│ ├── nightly.rs # Nightly channel implementation
│ └── http.rs # HTTP client & utilities
└── Cargo.toml
Layered Architecture
┌─────────────────────────────────────────┐
│ CLI Layer (src/cli, src/main) │
│ - Argument parsing (clap) │
│ - Command routing │
│ - [Conditional: requires "cli" feature] │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Application Layer (src/app) │
│ - Business orchestration (handler) │
│ - Result presentation (display) │
│ - [Conditional: requires "cli" feature] │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Domain Layer (src/domain) │
│ - Core model (RustRelease) │
│ - [Always included] │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Infrastructure Layer (src/infra) │
│ - HTTP client (http) │
│ - Data fetching (fetcher) │
│ - Channel implementations │
│ - [Always included] │
└─────────────────────────────────────────┘
Conditional Compilation
The project uses Rust's feature flags for conditional compilation:
| Module | Condition | Included When |
|---|---|---|
src/app |
#[cfg(feature = "cli")] |
CLI feature enabled |
src/cli |
#[cfg(feature = "cli")] |
CLI feature enabled |
src/domain |
Always | All builds |
src/infra |
Always | All builds |
src/constants |
Always | All builds |
src/options |
Always | All builds |
Benefits:
- Library-only builds exclude CLI-specific code
- Smaller binary size for library users
- Faster compilation without CLI dependencies
- Zero overhead for pure library usage
Design Patterns
Strategy Pattern
The ReleaseFetcher trait defines a common interface for fetching release data, with each channel implementing its own strategy:
Factory Method
The create_fetcher() function creates the appropriate fetcher based on channel name:
Builder Pattern
FetchOptions and NetworkConfig use builder pattern for fluent configuration:
let opts = new
.full_history
.probe_days
.timeout
.max_concurrency;
API Reference
Core Functions
fetch_releases
pub async
Fetch Rust release data for a given channel.
Parameters:
channel: One of"stable","beta", or"nightly"opts: Query configuration (FetchOptions)
Returns:
Vec<RustRelease>sorted by date descending
Errors:
- Unknown channel name
- Network request failure
Structs
RustRelease
FetchOptions
Methods:
new()→ Create with defaultsfull_history(bool)→ Enable RELEASES.md modeprobe_days(u32)→ Set probe daystimeout(Duration)→ Set HTTP timeoutmax_concurrency(usize)→ Set concurrency limituser_agent(string)→ Set User-Agent
NetworkConfig
Methods:
new()→ Create with defaultstimeout_secs(u64)→ Set timeoutmax_concurrency(usize)→ Set concurrencyuser_agent(string)→ Set User-Agent
Traits
ReleaseFetcher
Factory Function
create_fetcher
Create a channel-specific fetcher.
Parameters:
channel: One of"stable","beta", or"nightly"full: Iftrue, stable fetcher uses RELEASES.mddays: Days to probe (beta/nightly only)
Returns:
Box<dyn ReleaseFetcher>for the specified channel
Data Sources
Stable Channel
| Mode | Source | Coverage |
|---|---|---|
| Default | GitHub Releases API | ~1500 releases (~10 years) |
--full |
RELEASES.md | Complete history (all releases) |
GitHub API:
- Endpoint:
https://api.github.com/repos/rust-lang/rust/releases - Pagination: 100 per page, max 15 pages
- Filters: Excludes drafts and prereleases
RELEASES.md:
- URL:
https://raw.githubusercontent.com/rust-lang/rust/master/RELEASES.md - Format: Parses
Version X.Y.Z (YYYY-MM-DD)lines
Beta Channel
- Source:
https://static.rust-lang.org/dist/{date}/channel-rust-beta.toml - Method: Date probing for recent N days
- Version extraction: Parses
[pkg.rust]section
Nightly Channel
- Source:
https://static.rust-lang.org/dist/{date}/channel-rust-nightly.toml - Method: Date probing for recent N days
- Version extraction: Parses
[pkg.rust]section
Feature Flags
Available Features
| Feature | Default | Dependencies | Description |
|---|---|---|---|
cli |
No | clap, comfy-table |
Enable CLI binary and terminal UI |
Usage Examples
Library Only (No CLI)
[]
= "0.4"
Dependencies included:
reqwest(HTTP client)serde(serialization)chrono(date handling)tokio(async runtime)anyhow(error handling)regex-lite(regex parsing)async-trait(trait support)
Dependencies excluded:
clap(CLI argument parser)comfy-table(table formatting)
Library + CLI
[]
= { = "0.4", = ["cli"] }
Additional dependencies:
clap(CLI argument parser)comfy-table(table formatting)
Conditional Compilation
When the cli feature is disabled:
| Excluded Modules | Reason |
|---|---|
src/app |
CLI-specific business logic |
src/cli |
CLI argument parsing |
src/main.rs |
Binary entry point |
Result:
- Smaller compiled library
- Faster build times
- No CLI-related code in final binary
Constants
All hardcoded values are centralized in src/constants.rs:
// Channel names
pub const CHANNEL_STABLE: &str = "stable";
pub const CHANNEL_BETA: &str = "beta";
pub const CHANNEL_NIGHTLY: &str = "nightly";
// Default configuration
pub const DEFAULT_PROBE_DAYS: u32 = 30;
pub const DEFAULT_TIMEOUT_SECS: u64 = 15;
pub const DEFAULT_MAX_CONCURRENCY: usize = 10;
// GitHub API
pub const GITHUB_PER_PAGE: u32 = 100;
pub const GITHUB_MAX_PAGES: u32 = 15;
// URLs
pub const GITHUB_RELEASES_API: &str = "https://api.github.com/repos/rust-lang/rust/releases";
pub const RELEASES_MD_URL: &str = "https://raw.githubusercontent.com/rust-lang/rust/master/RELEASES.md";
pub const STATIC_DIST_BASE_URL: &str = "https://static.rust-lang.org/dist";
Development
Requirements
- Rust 1.75 or later
- Cargo
Building
Library Only
Library + CLI
Testing
# Test library functionality
# Test with CLI features
Linting
# Check all features
# Check library only
Documentation
Publishing
Note: The published crate will include both library and CLI features, but users can choose which to enable.
Changelog
0.4.2
- Bug Fix: Replaced
rustlswithnative-tlsfor TLS implementation - Improvement: Use Windows SChannel / macOS SecureTransport for better network compatibility
- Bug Fix: Added
system-proxysupport to respect system proxy settings
0.4.1
- Bug Fix: Increased default HTTP timeout from 15s to 60s for better network compatibility
- New Feature: Added
--timeout/-tCLI parameter to customize HTTP request timeout - Improvement: Enhanced error message for RELEASES.md fetch failures to hint at network issues
0.4.0
- Breaking Change: Removed database and config file dependencies
- New Feature: Optional CLI via feature flags (
clifeature) - Library mode is now pure in-memory with zero file-system side effects
- CLI dependencies (
clap,comfy-table) are now optional - Library-only builds have minimal dependency footprint
- CLI mode simplified to fetch-and-display workflow
- Centralized all constants in
src/constants.rs - Improved error messages and documentation
- Added comprehensive inline documentation
- Conditional compilation for CLI-specific modules
0.3.0
- Initial public release
- Support for stable, beta, and nightly channels
- GitHub API and RELEASES.md data sources
- Concurrent fetching with semaphore control
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
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.
Acknowledgments
- Rust - The programming language this tool tracks
- GitHub API - For stable release data
- rust-lang.org - For beta/nightly channel data