Skip to content

Conversation

@AliAlimohammadi
Copy link
Contributor

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 yottametres ($10^{24}$ meters).

Implementation Details

The implementation provides:

  1. MetricLengthUnit enum - Type-safe representation of length units

    • Meter (m) - $10^0$
    • Kilometer (km) - $10^{3}$
    • Megametre (Mm) - $10^{6}$
    • Gigametre (Gm) - $10^{9}$
    • Terametre (Tm) - $10^{12}$
    • Petametre (Pm) - $10^{15}$
    • Exametre (Em) - $10^{18}$
    • Zettametre (Zm) - $10^{21}$
    • Yottametre (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
    • 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. Flexible Parsing: Accepts multiple formats (full names, symbols, plurals, any case)
  4. Error Handling: Uses Result type for proper Rust error handling
  5. Standards Compliance: Uses proper SI prefix notation (Mm, Gm, etc.)
  6. Avoid Naming Conflicts: Named functions specifically to avoid conflicts with existing length_conversion module

Changes Made

  • ✅ Added src/conversions/order_of_magnitude_conversion.rs with complete implementation
  • ✅ Will update src/conversions/mod.rs to include and export the module
  • ✅ Implemented comprehensive unit tests covering:
    • Unit exponent verification
    • Symbol representation
    • String parsing (full names, symbols, case-insensitive, plurals)
    • Invalid input handling
    • Conversion reversibility tests
    • Edge cases (same unit conversion, large/small values)
  • ✅ Added detailed documentation with examples for all public items
  • ✅ Included doctests demonstrating usage

Type of Change

  • New conversion implementation
  • Documentation (docstrings and examples)
  • Tests

Testing

All tests pass successfully:

cargo test length
cargo test --doc length
cargo fmt --check
cargo clippy -- -D warnings

Test Coverage

Unit Tests (30+ tests)

  • Exponent verification for all units
  • Symbol representation for all units
  • String parsing with full names
  • String parsing with abbreviations
  • Case-insensitive parsing
  • Plural form handling
  • Invalid input error handling
  • All conversion examples from Python version:
    • meter → kilometer: 0.001
    • meter → megametre: 1e-6
    • gigametre → meter: 1,000,000,000
    • gigametre → terametre: 0.001
    • petametre → terametre: 1000
    • petametre → exametre: 0.001
    • terametre → zettametre: 1e-9
    • yottametre → zettametre: 1000
  • Same-unit conversion
  • Large and small value conversions
  • Conversion reversibility for all unit pairs
  • Doctests for public API

Examples

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

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

let meters = metric_length_conversion(1.0, "km", "m").unwrap();
assert_eq!(meters, 1000.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)
let km = convert_metric_length(1000.0, MetricLengthUnit::Meter, MetricLengthUnit::Kilometer);
assert_eq!(km, 1.0);

// 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
  • Any dependent changes have been merged and published

Additional Context

  • 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, pattern matching, and Rust conventions
  • More Comprehensive Tests: 30+ tests vs. just doctests
  • Display Trait: Units can be formatted with {} in strings
  • Copy Semantics: Efficient enum copying
  • Documentation: Full rustdoc with examples

Standards Compliance:

  • Uses proper SI prefixes and symbols
  • Follows metric system conventions
  • Accurate to floating-point precision

References

@AliAlimohammadi
Copy link
Contributor Author

@siriak, this is ready to be merged.

@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 98.61751% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.76%. Comparing base (35a5743) to head (2427b80).

Files with missing lines Patch % Lines
src/conversions/order_of_magnitude_conversion.rs 98.61% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #985      +/-   ##
==========================================
- Coverage   95.77%   95.76%   -0.02%     
==========================================
  Files         354      355       +1     
  Lines       23407    23624     +217     
==========================================
+ Hits        22419    22624     +205     
- Misses        988     1000      +12     

☔ 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.

@siriak siriak merged commit 38024b0 into TheAlgorithms:master Dec 31, 2025
7 checks passed
@AliAlimohammadi AliAlimohammadi deleted the add-order-of-magnitude-conversion branch December 31, 2025 22:43
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