Skip to content

Conversation

@AliAlimohammadi
Copy link
Contributor

@AliAlimohammadi AliAlimohammadi commented Jan 6, 2026

Description

This PR adds a comprehensive implementation of metric length unit conversion to the conversions module. The implementation supports conversions between nine metric length units ranging from meters to yottameters ($10^{24}$ meters).

Spelling Convention: This implementation uses American spellings (meter, kilometer, megameter, etc.) officially in all enum variants and documentation, following standard programming conventions and SI guidelines. However, the parser accepts both American AND British spellings for maximum compatibility and user-friendliness.

// Both spellings work seamlessly!
"megameter".parse::<MetricLengthUnit>()  // ✅ American (official)
"megametre".parse::<MetricLengthUnit>()  // ✅ British (also accepted)

Implementation Details

The implementation provides:

  1. MetricLengthUnit enum - Type-safe representation of length units (using American spellings)

    • Meter (m) - $10^{0}$
    • Kilometer (km) - $10^{3}$
    • Megameter (Mm) - $10^{6}$
    • Gigameter (Gm) - $10^{9}$
    • Terameter (Tm) - $10^{12}$
    • Petameter (Pm) - $10^{15}$
    • Exameter (Em) - $10^{18}$
    • Zettameter (Zm) - $10^{21}$
    • Yottameter (Ym) - $10^{24}$
  2. convert_metric_length(value: f64, from: MetricLengthUnit, to: MetricLengthUnit) -> f64

    • Type-safe conversion using enum variants
    • Direct computation using power-of-10 exponents
    • No runtime errors for valid enum values
  3. metric_length_conversion(value: f64, from_type: &str, to_type: &str) -> Result<f64, String>

    • String-based conversion for user-friendly API
    • Case-insensitive parsing
    • Handles both full names and abbreviations
    • Accepts both American and British spellings
    • Supports plural forms (e.g., "meters" and "meter")
    • Returns descriptive error messages for invalid units

Algorithm Details

The conversion uses the formula:

result = value × 10^(from_exponent - to_exponent)

Where each unit has an exponent representing its power of 10 relative to meters.

Example:

  • Converting 1 kilometer to meters: 1 × 10^(3-0) = 1000
  • Converting 1 meter to kilometers: 1 × 10^(0-3) = 0.001

Time Complexity: $O(1)$ - constant time conversion
Space Complexity: $O(1)$ - no additional space needed

Design Choices

  1. Type Safety: Using an enum instead of strings for the core API prevents runtime errors
  2. Dual API: Provides both type-safe (convert_metric_length) and string-based (metric_length_conversion) functions
  3. American Spellings Official: Uses American English in all enum variants and documentation per programming conventions
  4. Accepts Both Spellings: The FromStr implementation accepts both American ("meter") and British ("metre") spellings
  5. Flexible Parsing: Also accepts symbols, plurals, and any case
  6. Error Handling: Uses Result type for proper Rust error handling
  7. Standards Compliance: Uses proper SI prefix notation (Mm, Gm, etc.)
  8. Avoid Naming Conflicts: Named functions specifically to avoid conflicts with existing length_conversion module

Why American Spellings?

  1. Programming Convention: Most programming languages and libraries use American English
  2. SI Standard: The International System uses "meter" in official English documentation
  3. Developer Familiarity: American English is the de facto standard in software development
  4. Consistency: Aligns with Rust ecosystem conventions (color, center, etc.)
  5. But Still Flexible: Accepts British spellings to accommodate all users

Changes Made

  • ✅ Added src/conversions/order_of_magnitude_conversion.rs with complete implementation
  • ✅ Updated src/conversions/mod.rs to include and export the module
  • ✅ Implemented comprehensive unit tests (40+ tests) covering:
    • Unit exponent verification
    • Symbol representation
    • String parsing (full names, symbols, case-insensitive, plurals)
    • Both American and British spelling acceptance
    • Invalid input handling
    • All example conversions from Python version
    • Conversion reversibility tests
    • Edge cases (same unit conversion, large/small values)
    • Mixed spelling usage (American from, British to)
  • ✅ Added detailed documentation with examples for all public items
  • ✅ Included doctests demonstrating usage
  • ✅ Added module-level documentation explaining spelling policy

Type of Change

  • New conversion implementation
  • Documentation (docstrings and examples)
  • Tests (40+ comprehensive tests)

Testing

All tests pass successfully:

cargo test order_of_magnitude
cargo test --test conversions
cargo test --doc
cargo fmt --check
cargo clippy -- -D warnings

Test Coverage

40+ Unit Tests Including:

  • Exponent verification for all units
  • Symbol representation for all units
  • String parsing with American spellings
  • String parsing with British spellings (dedicated tests)
  • Verification that both spellings produce same result
  • String parsing with abbreviations
  • Case-insensitive parsing
  • Plural form handling (meters, kilometres, etc.)
  • Invalid input error handling
  • All conversion examples from Python version:
    • meter → kilometer: 0.001
    • meter → megameter: 1e-6
    • gigameter → meter: 1,000,000,000
    • gigameter → terameter: 0.001
    • petameter → terameter: 1000
    • petameter → exameter: 0.001
    • terameter → zettameter: 1e-9
    • yottameter → zettameter: 1000
  • Same-unit conversion
  • Large and small value conversions
  • Conversion reversibility for all unit pairs
  • British spellings in string API
  • Mixed spelling usage (American + British in same call)
  • Doctests for public API

Examples

use the_algorithms_rust::conversions::{metric_length_conversion, convert_metric_length, MetricLengthUnit};

// String-based API (flexible, user-friendly)
// American spellings
let km = metric_length_conversion(1000.0, "meter", "kilometer").unwrap();
assert_eq!(km, 1.0);

// British spellings - ALSO WORK!
let km = metric_length_conversion(1000.0, "metre", "kilometre").unwrap();
assert_eq!(km, 1.0);

// Mix them!
let result = metric_length_conversion(1.0, "megametre", "meter").unwrap();
assert_eq!(result, 1_000_000.0);

// Case insensitive and handles plurals
let result = metric_length_conversion(5.0, "METERS", "kilometers").unwrap();
assert_eq!(result, 0.005);

// Type-safe API (no runtime errors, uses American spellings officially)
let km = convert_metric_length(1000.0, MetricLengthUnit::Meter, MetricLengthUnit::Kilometer);
assert_eq!(km, 1.0);

// Use with parse() - accepts both spellings!
let unit: MetricLengthUnit = "gigameter".parse()?;  // American
let unit: MetricLengthUnit = "gigametre".parse()?;  // British - works too!

// Error handling
match metric_length_conversion(1.0, "wrongUnit", "meter") {
    Ok(_) => println!("Success"),
    Err(e) => println!("Error: {}", e),
}

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my implementation is correct
  • New and existing unit tests pass locally with my changes
  • I have checked my code with cargo fmt
  • I have checked my code with cargo clippy
  • I have documented the spelling convention clearly

Additional Context

This implementation is based on the Python version from TheAlgorithms/Python and follows Rust best practices:

Improvements over Python version:

  • Type Safety: Enum-based design prevents invalid unit combinations at compile time
  • Dual API: Both type-safe and string-based interfaces
  • Better Error Messages: Clear, descriptive error messages
  • No Magic Strings: Unit symbols defined as constants
  • Idiomatic Rust: Uses Result type, FromStr trait, pattern matching, and Rust conventions
  • More Comprehensive Tests: 40+ tests vs. just doctests
  • Display Trait: Units can be formatted with {} in strings
  • Copy Semantics: Efficient enum copying
  • Documentation: Full rustdoc with examples and spelling policy
  • Maximum Compatibility: Accepts both American and British spellings

Standards Compliance:

  • Uses proper SI prefixes and symbols
  • Follows metric system conventions
  • Accurate to floating-point precision
  • Uses American spellings per NIST and ISO standards in official API

Spelling Policy:

  • Official API uses American spellings (enum variants, documentation)
  • Parser accepts both American and British spellings for user convenience
  • Provides best of both worlds: consistency in code, flexibility for users

References

@AliAlimohammadi
Copy link
Contributor Author

@siriak, this is ready to be merged.

@codecov-commenter
Copy link

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.78%. Comparing base (38024b0) to head (d6d3d3d).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #986      +/-   ##
==========================================
- Coverage   95.83%   95.78%   -0.05%     
==========================================
  Files         356      356              
  Lines       23745    23787      +42     
==========================================
+ Hits        22755    22784      +29     
- Misses        990     1003      +13     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@siriak siriak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@siriak siriak merged commit 81e485e into TheAlgorithms:master Jan 6, 2026
7 checks passed
@AliAlimohammadi AliAlimohammadi deleted the add-order-of-magnitude-conversion branch January 6, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants