///|
/// How a data element obtains its encoded length.
pub(all) enum LengthKind {
Fixed
Llvar
Lllvar
} derive(Eq, Debug)
///|
/// How a variable-length prefix is represented.
pub(all) enum LengthEncoding {
AsciiLength
BcdLength
} derive(Eq, Debug)
///|
/// How field content is represented on the wire.
pub(all) enum ContentEncoding {
AsciiContent
BcdContent
BinaryContent
} derive(Eq, Debug)
///|
/// Validation class applied before a field is packed.
pub(all) enum DataKind {
Numeric
Alpha
Alphanumeric
AlphanumericSpecial
Track2Data
BinaryHex
AnyText
} derive(Eq, Debug)
///|
/// Direction used when a fixed field needs padding.
pub(all) enum PadDirection {
NoPadding
PadLeft
PadRight
} derive(Eq, Debug)
///|
/// One data-element definition in a packager profile.
pub(all) struct FieldSpec {
number : Int
name : String
length_kind : LengthKind
max_length : Int
min_length : Int
length_encoding : LengthEncoding
content_encoding : ContentEncoding
data_kind : DataKind
pad_direction : PadDirection
pad_char : UInt16
} derive(Eq, Debug)
///|
/// A field stored in a message. Values are unencoded canonical text.
pub(all) struct FieldEntry {
number : Int
value : String
} derive(Eq, Debug)
///|
/// Mutable message model used by pack and validation operations.
pub(all) struct IsoMessage {
mut mti : String
fields : Array[FieldEntry]
} derive(Debug)
///|
/// Ordered collection of field definitions.
pub(all) struct Packager {
name : String
specs : Array[FieldSpec]
} derive(Debug)
///|
/// A validation finding that can be rendered in stable logs.
pub(all) struct ValidationIssue {
code : String
field : Int
message : String
severity : String
} derive(Eq, Debug)
///|
/// Result of decoding with byte-consumption information.
pub(all) struct DecodeResult {
message : IsoMessage
consumed : Int
bitmap_bytes : Int
} derive(Debug)
///|
/// Create a fixed ASCII field definition.
pub fn fixed_ascii(
number : Int,
name : String,
length : Int,
kind : DataKind,
) -> FieldSpec {
{
number,
name,
length_kind: Fixed,
max_length: length,
min_length: length,
length_encoding: AsciiLength,
content_encoding: AsciiContent,
data_kind: kind,
pad_direction: NoPadding,
pad_char: ' ',
}
}
///|
/// Create a fixed numeric field left padded with zeroes.
pub fn fixed_numeric(number : Int, name : String, length : Int) -> FieldSpec {
{
number,
name,
length_kind: Fixed,
max_length: length,
min_length: 1,
length_encoding: AsciiLength,
content_encoding: AsciiContent,
data_kind: Numeric,
pad_direction: PadLeft,
pad_char: '0',
}
}
///|
/// Create an ASCII LLVAR field.
pub fn llvar_ascii(
number : Int,
name : String,
maximum : Int,
kind : DataKind,
) -> FieldSpec {
{
number,
name,
length_kind: Llvar,
max_length: maximum,
min_length: 0,
length_encoding: AsciiLength,
content_encoding: AsciiContent,
data_kind: kind,
pad_direction: NoPadding,
pad_char: ' ',
}
}
///|
/// Create an ASCII LLLVAR field.
pub fn lllvar_ascii(
number : Int,
name : String,
maximum : Int,
kind : DataKind,
) -> FieldSpec {
{
number,
name,
length_kind: Lllvar,
max_length: maximum,
min_length: 0,
length_encoding: AsciiLength,
content_encoding: AsciiContent,
data_kind: kind,
pad_direction: NoPadding,
pad_char: ' ',
}
}
///|
/// Create a binary field represented as hexadecimal text in the API.
pub fn binary_hex(
number : Int,
name : String,
maximum_bytes : Int,
variable : Bool,
) -> FieldSpec {
{
number,
name,
length_kind: if variable {
Lllvar
} else {
Fixed
},
max_length: maximum_bytes * 2,
min_length: if variable {
0
} else {
maximum_bytes * 2
},
length_encoding: AsciiLength,
content_encoding: BinaryContent,
data_kind: BinaryHex,
pad_direction: NoPadding,
pad_char: '0',
}
}