Skip to main content

decode_packed_decimal

Function decode_packed_decimal 

Source
pub fn decode_packed_decimal(
    data: &[u8],
    digits: u16,
    scale: i16,
    signed: bool,
) -> Result<SmallDecimal>
Expand description

Decode packed decimal (COMP-3) field with comprehensive error context

Decodes COMP-3 packed decimal format where each byte contains two decimal digits (nibbles), with the last nibble containing the sign. This function uses optimized fast paths for common enterprise data patterns.

§Arguments

  • data - Raw byte data containing the packed decimal
  • digits - Number of decimal digits in the field (1-18 supported)
  • scale - Number of decimal places (can be negative for scaling)
  • signed - Whether the field is signed (true) or unsigned (false)

§Returns

A SmallDecimal containing the decoded value

§Errors

Returns an error if the packed decimal data contains invalid nibbles. All errors include proper context information (record_index, field_path, byte_offset).

§Performance

This function uses specialized fast paths for common cases:

  • 1-5 byte fields: Direct decoding with minimal validation
  • Empty data: Immediate zero return
  • Digits > 18: Error (maximum supported precision)

§Examples

§Basic Positive Value

use copybook_codec::numeric::{decode_packed_decimal};

// "123" as COMP-3: [0x12, 0x3C] (12 positive, 3C = positive sign)
let data = [0x12, 0x3C];
let result = decode_packed_decimal(&data, 3, 0, true)?;
assert_eq!(result.to_string(), "123");

§Negative Value

use copybook_codec::numeric::{decode_packed_decimal};

// "-456" as COMP-3: [0x04, 0x56, 0xD] (456 negative)
let data = [0x04, 0x56, 0xD];
let result = decode_packed_decimal(&data, 3, 0, true)?;
assert_eq!(result.to_string(), "-456");

§Decimal Scale

use copybook_codec::numeric::{decode_packed_decimal};

// "12.34" with 2 decimal places: [0x12, 0x34, 0xC]
let data = [0x12, 0x34, 0xC];
let result = decode_packed_decimal(&data, 4, 2, true)?;
assert_eq!(result.to_string(), "12.34");

§Unsigned Field

use copybook_codec::numeric::{decode_packed_decimal};

// Unsigned "789": [0x07, 0x89, 0xF] (F = unsigned sign)
let data = [0x07, 0x89, 0xF];
let result = decode_packed_decimal(&data, 3, 0, false)?;
assert_eq!(result.to_string(), "789");

§Zero Value

use copybook_codec::numeric::{decode_packed_decimal};

// Zero: [0x00, 0x0C]
let data = [0x00, 0x0C];
let result = decode_packed_decimal(&data, 2, 0, true)?;
assert_eq!(result.to_string(), "0");

§See Also