prism3-core 0.1.0

Foundational utilities and language-level tools for Rust application development
Documentation

Prism3 Core

CircleCI Coverage Status Crates.io Rust License 中文文档

A comprehensive Rust utility library providing language-level fundamental tools and data type support for the Prism3 ecosystem.

Overview

Prism3 Core is designed to provide essential language-level utilities that are commonly needed across Rust applications. It offers robust argument validation, comprehensive data type definitions, and core utility functions that follow Rust idioms and best practices.

Features

🔧 Data Type System

  • Universal Data Type Enum: Comprehensive DataType enum supporting all basic Rust types and common third-party types
  • Compile-time Type Mapping: DataTypeOf trait for compile-time type-to-data-type queries
  • Serialization Support: Built-in JSON/YAML serialization for all data types
  • Type Validation: Runtime type checking and conversion utilities

🛡️ Argument Validation

  • Numeric Validation: Range checks, equality comparisons, and bounds validation
  • String Validation: Pattern matching, length constraints, and format validation
  • Collection Validation: Size limits, element constraints, and null checks
  • Option Validation: Null safety and optional value handling
  • Method Chaining: Fluent API design for readable validation chains

🎯 Core Utilities

  • Error Handling: Comprehensive error types with detailed context
  • State Validation: Application state checking and validation
  • Condition Checking: Flexible condition and assertion utilities

Installation

Add this to your Cargo.toml:

[dependencies]
prism3-core = "0.1.0"

Quick Start

Data Type Usage

use prism3_core::lang::{DataType, DataTypeOf};

// Get data type information
let data_type = DataType::Int32;
assert_eq!(data_type.as_str(), "int32");

// Compile-time type mapping
assert_eq!(i32::DATA_TYPE, DataType::Int32);
assert_eq!(String::DATA_TYPE, DataType::String);

// Serialization
let json = serde_json::to_string(&DataType::Float64).unwrap();
assert_eq!(json, "\"float64\"");

Argument Validation

use prism3_core::lang::argument::{
    NumericArgument, StringArgument, CollectionArgument, ArgumentResult
};
use regex::Regex;

fn process_user_input(
    age: i32,
    username: &str,
    tags: &[String],
) -> ArgumentResult<()> {
    // Numeric validation
    let age = age.require_in_closed_range("age", 0, 150)?;

    // String validation with chaining
    let username_pattern = Regex::new(r"^[a-zA-Z][a-zA-Z0-9_]{2,19}$").unwrap();
    let username = username
        .require_non_blank("username")?
        .require_match("username", &username_pattern)?;

    // Collection validation
    let tags = tags
        .require_non_empty("tags")?
        .require_length_at_most("tags", 10)?;

    println!("Age: {}, Username: {}, Tag count: {}", age, username, tags.len());
    Ok(())
}

State and Condition Checking

use prism3_core::lang::argument::{
    check_argument, check_state, check_bounds, ArgumentResult
};

fn process_data(value: i32, items: &[String]) -> ArgumentResult<()> {
    // Basic argument checking
    check_argument(value > 0, "value must be positive")?;

    // State validation
    check_state(!items.is_empty(), "items cannot be empty")?;

    // Bounds checking
    check_bounds(value, 1, 100, "value")?;

    Ok(())
}

Supported Data Types

Basic Types

  • Integers: i8, i16, i32, i64, i128, u8, u16, u32, u64, u128
  • Floats: f32, f64
  • Other: bool, char, String

Date/Time Types

  • Chrono Integration: NaiveDate, NaiveTime, NaiveDateTime, DateTime<Utc>

Big Number Types

  • Arbitrary Precision: BigInt, BigDecimal

API Reference

Data Types

Argument Validation

Core Functions

Error Handling

All validation functions return ArgumentResult<T>, which is an alias for Result<T, ArgumentError>. The ArgumentError type provides detailed error information including:

  • Error message
  • Parameter name
  • Expected vs actual values
  • Context information
use prism3_core::lang::argument::{ArgumentError, ArgumentResult};

match validate_input(value) {
    Ok(result) => println!("Validation passed: {:?}", result),
    Err(ArgumentError::InvalidArgument { param, message }) => {
        eprintln!("Invalid argument '{}': {}", param, message);
    }
}

Dependencies

  • serde: Serialization support
  • serde_json: JSON serialization
  • thiserror: Error handling
  • tracing: Logging support
  • bigdecimal: Arbitrary precision decimal arithmetic
  • chrono: Date and time handling
  • num-bigint: Big integer support
  • regex: Pattern matching

Testing & Code Coverage

This project maintains comprehensive test coverage with detailed validation of all functionality.

Coverage Metrics

Current test coverage statistics:

Module Region Coverage Line Coverage Function Coverage
collection.rs 100.00% 100.00% 100.00%
condition.rs 100.00% 100.00% 100.00%
error.rs 100.00% 100.00% 100.00%
numeric.rs 100.00% 100.00% 100.00%
option.rs 76.19% 84.09% 100.00%
string.rs 100.00% 100.00% 100.00%
data_type.rs 100.00% 100.00% 100.00%
pair.rs 100.00% 100.00% 100.00%
triple.rs 100.00% 100.00% 100.00%
Total 98.38% 98.99% 100.00%

Understanding Coverage Metrics

Why isn't option.rs at 100% Region Coverage?

The option.rs module shows 76.19% region coverage despite having 100% executable code coverage. This is due to a known characteristic of LLVM's coverage instrumentation:

LLVM Region Coverage Includes Non-Executable Code:

  • Trait definitions and signatures
  • Type parameter declarations
  • where clause constraints
  • Generic bounds
  • Empty lines between declarations

These declarative elements are assigned region IDs by LLVM but are not executable code. The actual implementation code in option.rs has 100% coverage (verified by examining the detailed report - no ^ markers indicating uncovered code).

Example:

pub trait OptionArgument<T> {              // ← Counted as region
    fn require_non_null(                   // ← Counted as region
        self,                              // ← Counted as region
        name: &str                         // ← Counted as region
    ) -> ArgumentResult<T>;                // ← Counted as region

    fn require_non_null_and<F>(            // ← Counted as region
        self, name: &str,
        predicate: F,
        error_msg: &str
    ) -> ArgumentResult<T>
    where                                  // ← Counted as region
        F: FnOnce(&T) -> bool;             // ← Counted as region
}

Why This Happens:

  • option.rs has ~88 lines of trait definitions with complex generic constraints
  • Simple modules like error.rs have fewer declarative regions
  • This is a known limitation in LLVM coverage (GitHub Issue rust#79417)
  • C++ projects using LLVM coverage face similar issues with templates

What Matters:

  • Function Coverage: 100% - All functions are tested
  • Line Coverage: 84.09% - High actual code coverage
  • Executable Code: 100% - All implementation logic is tested
  • ⚠️ Region Coverage: 76.19% - Includes non-executable declarations

Running Tests

# Run all tests
cargo test

# Run with coverage report
./coverage.sh

# Generate text format report
./coverage.sh text

# Generate detailed report for specific module
cargo llvm-cov test --text | grep -A 50 "option.rs"

Coverage Tool Limitations

The coverage statistics are generated using cargo-llvm-cov. When interpreting the results:

  1. Focus on Function and Line Coverage - These are the most meaningful metrics
  2. Region Coverage may be lower - Especially for modules with extensive trait definitions
  3. Verify with detailed reports - Check for ^ markers in uncovered regions
  4. Known LLVM issue - Non-executable declarations are counted as regions

For more details, see:

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

When contributing tests, note that achieving 100% region coverage is not always feasible for modules with extensive trait definitions. Focus on ensuring all executable code paths are tested.

Author

Hu Haixing - 3-Prism Co. Ltd.


For more information about the Prism3 ecosystem, visit our GitHub repository.