#frequency #parser #units #clap #cli-parser

parse-frequency

A simple library to parse frequency strings into a frequency in Hz

2 stable releases

Uses new Rust 2024

new 2.0.0 Apr 20, 2025
1.1.0 Apr 19, 2025
1.0.0 Apr 19, 2025

#5 in #frequency

Download history 144/week @ 2025-04-14

144 downloads per month

MIT license

29KB
431 lines

parse-frequency

crates.io License Rust

A simple, no-nonsense Rust library for parsing frequency strings like "1.5GHz" or "100 kHz" into strongly-typed frequency values. Case insensitive, of course.

Supports serialization, deserialization, CLI parsing, and conversions between Hz, kHz, MHz, and GHz.

Features

  • Parse human-friendly strings like "1GHz", "2.5 MHz", or "42 kHz" into a Frequency type
  • Convert between Hz, kHz, MHz, and GHz with ease
  • Display implementation (e.g., "2.50 MHz")
  • Convert to std::time::Duration (period)
  • #[derive(Debug, Copy, Clone, ...)] with strong type guarantees
  • Send + Sync support for thread-safe usage in multithreaded environments
  • Optional support for the following features:

Example

use parse_frequency::Frequency;

fn main() {
    let cpu_clock = "3.6 GHz".parse::<Frequency>().unwrap();
    println!("CPU clock: {}", cpu_clock);

    let ns_per_cycle = cpu_clock.as_duration();
    println!("One clock cycle takes: {} ns", ns_per_cycle.as_nanos());
}

Installation

Add this to your Cargo.toml:

[dependencies]
parse-frequency = "2.0"

Enable optional features:

[dependencies.parse-frequency]
version = "1.0"
features = ["serde", "clap", "num-traits", "schemars", "time", "chrono"]

Quick Start

Parse from a string

use parse_frequency::Frequency;

let freq: Frequency = "2.5GHz".parse().unwrap();
assert_eq!(freq.as_hz(), 2_500_000_000);

Convert between units

use parse_frequency::{Frequency, KILOHERTZ};

let f = Frequency::from_khz(2000);
assert_eq!(f.as_mhz(), 2);
assert_eq!(f.as_hz(), 2 * KILOHERTZ * 1000);

Format for display

Note that due to the 2 digit precision limitation, the result is rounded when displaying.

let f = Frequency::from_mhz(1337);
println!("{f}"); // -> "1.34 GHz"

Derive a period as Duration

let f = Frequency::from_ghz(1);
let duration = f.as_duration();

assert_eq!(duration.as_nanos(), 1); // 1 GHz → 1 nanosecond period

Optional Integrations

parse-frequency a number of optional features that enable seamless integration with commonly used Rust libraries. Enable these via Cargo features.

serde

Enable the serde feature to serialize and deserialize Frequency as human-readable strings:

parse-frequency = { version = "...", features = ["serde"] }
use parse_frequency::Frequency;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Config {
    clock: Frequency,
}

This allows values like:

{
  "clock": "1.00 GHz"
}

clap

Enable the clap feature to use Frequency in CLI arguments:

parse-frequency = { version = "...", features = ["clap"] }
use clap::Parser;
use parse_frequency::Frequency;

#[derive(Parser)]
struct Args {
    /// Target frequency (e.g. "2.4GHz")
    #[arg(short, long)]
    frequency: Frequency,
}

enum-traits

Enable num-traits to use Frequency in generic numeric code (e.g. scientific, DSP, or math contexts):

parse-frequency = { version = "...", features = ["num-traits"] }

Implements:

  • Zero, One
  • Num, FromStrRadix
  • Mul, Div, Rem

Note: Arithmetic is defined in terms of absolute frequency values. Multiplying or dividing two Frequency values may not make semantic sense but is supported for compatibility.

chrono

Enable the chrono feature to convert a Frequency into a time period:

parse-frequency = { version = "...", features = ["chrono"] }
use parse_frequency::Frequency;

let freq = Frequency::from_ghz(1);
let period = freq.as_chrono_duration(); // chrono::Duration of 1 ns

Handles both low and high frequencies safely using nanosecond/picosecond precision.

time

Enable the time feature to convert a Frequency into a time::Duration:

parse-frequency = { version = "...", features = ["time"] }
use parse_frequency::Frequency;

let freq = Frequency::from_mhz(1);
let duration = freq.as_time_duration(); // time::Duration of 1000 ns

schemars

Enable the schemars feature to use Frequency with OpenAPI / JSON schema generation:

parse-frequency = { version = "...", features = ["schemars"] }
use parse_frequency::Frequency;
use schemars::JsonSchema;

#[derive(JsonSchema)]
struct Config {
    clock: Frequency,
}

Generates schema like:

{
  "type": "string",
  "format": "frequency",
  "description": "A frequency value like \"2.4 GHz\", \"100 kHz\", or \"440Hz\""
}

Constants

For convenience, the following constants are available:

use parse_frequency::{KILOHERTZ, MEGAHERTZ, GIGAHERTZ};

assert_eq!(KILOHERTZ, 1_000);
assert_eq!(MEGAHERTZ, 1_000_000);
assert_eq!(GIGAHERTZ, 1_000_000_000);

Error Handling

The Frequency::from_str and parse_frequency functions return a custom error enum:

match "bad input".parse::<Frequency>() {
    Ok(freq) => println!("Parsed: {freq}"),
    Err(e) => eprintln!("Failed: {e}"),
}

Example error variants:

  • Error::UnknownUnit("abc")
  • Error::InvalidValue("GHz")

Dependencies

~0–1MB
~17K SLoC