Skip to main content

iso8583_core/
lib.rs

1//! # iso8583-core
2//!
3//! Production-ready ISO 8583 message parsing and generation library.
4//!
5//! ## Features
6//!
7//! - **Zero Allocation**: Static const tables, no runtime overhead
8//! - **SIMD Optimized**: Accelerated bitmap operations on x86_64 and aarch64
9//! - **no_std Compatible**: Works in embedded environments
10//! - **Type Safe**: Compile-time field validation
11//! - **High Performance**: Optimized for financial systems
12//!
13//! ## Quick Start
14//!
15//! ```rust
16//! use iso8583_core::*;
17//!
18//! # fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
19//! // Build a message
20//! let message = ISO8583Message::builder()
21//!     .mti(MessageType::AUTHORIZATION_REQUEST)
22//!     .field(Field::PrimaryAccountNumber, "4111111111111111")
23//!     .field(Field::ProcessingCode, "000000")
24//!     .field(Field::TransactionAmount, "000000010000")
25//!     .field(Field::SystemTraceAuditNumber, "123456")
26//!     .field(Field::LocalTransactionTime, "120000")
27//!     .field(Field::LocalTransactionDate, "0219")
28//!     .build()?;
29//!
30//! // Generate bytes
31//! let bytes = message.to_bytes();
32//!
33//! // Parse bytes
34//! let parsed = ISO8583Message::from_bytes(&bytes)?;
35//! # Ok(())
36//! # }
37//! ```
38//!
39//! ## Architecture
40//!
41//! This library uses several advanced techniques for production performance:
42//!
43//! 1. **Static Specification Tables**: Field definitions stored in const arrays
44//! 2. **Zero-Copy Parsing**: Borrows from input buffers where possible
45//! 3. **SIMD Bitmap Operations**: Vectorized field presence checking
46//! 4. **Compile-Time Validation**: Type system enforces correctness
47//!
48//! ## Feature Flags
49//!
50//! - `std` (default): Standard library support
51//! - `alloc`: Heap allocation (Vec, String)
52//! - `simd`: SIMD-accelerated bitmap operations
53//! - `serde`: JSON serialization support
54
55#![cfg_attr(not(feature = "std"), no_std)]
56#![cfg_attr(docsrs, feature(doc_cfg))]
57#![warn(missing_docs)]
58#![warn(rust_2018_idioms)]
59#![cfg_attr(not(feature = "simd"), forbid(unsafe_code))]
60
61// Core modules
62pub mod fields;
63pub mod spec;
64
65// Legacy field module (std only)
66#[cfg(feature = "std")]
67pub mod field;
68
69#[cfg(feature = "alloc")]
70pub mod bitmap_simd;
71
72#[cfg(feature = "alloc")]
73pub use bitmap_simd as bitmap;
74
75// Legacy modules (with std feature)
76#[cfg(feature = "std")]
77pub mod error;
78
79#[cfg(feature = "std")]
80pub mod mti;
81
82#[cfg(feature = "std")]
83pub mod encoding;
84
85#[cfg(feature = "std")]
86pub mod validation;
87
88#[cfg(feature = "std")]
89pub mod response_code;
90
91#[cfg(feature = "std")]
92pub mod processing_code;
93
94#[cfg(feature = "std")]
95pub mod utils;
96
97#[cfg(feature = "std")]
98pub mod message;
99
100// Re-exports for convenience
101pub use fields::IsoField;
102pub use spec::{DataType, FieldDefinition, Iso1987, IsoSpec, LengthType};
103
104#[cfg(feature = "alloc")]
105pub use bitmap::Bitmap;
106
107#[cfg(feature = "std")]
108pub use error::{ISO8583Error, Result};
109
110#[cfg(feature = "std")]
111pub use mti::{MessageClass, MessageFunction, MessageOrigin, MessageType};
112
113#[cfg(feature = "std")]
114pub use message::{ISO8583Message, MessageBuilder};
115
116#[cfg(feature = "std")]
117pub use response_code::{ResponseCategory, ResponseCode};
118
119#[cfg(feature = "std")]
120pub use processing_code::{AccountType, ProcessingCode, TransactionType};
121
122#[cfg(feature = "std")]
123pub use validation::Validator;
124
125// Legacy field enum (std only for compatibility)
126#[cfg(feature = "std")]
127pub use crate::field::Field;
128
129#[cfg(test)]
130mod tests {
131    use super::*;
132
133    #[test]
134    fn test_spec_lookup() {
135        // Verify static table works
136        let field2 = Iso1987::get_field(2).unwrap();
137        assert_eq!(field2.data_type, DataType::Numeric);
138        assert_eq!(field2.length_type, LengthType::Llvar);
139    }
140
141    #[cfg(feature = "alloc")]
142    #[test]
143    fn test_bitmap() {
144        let mut bitmap = Bitmap::new();
145        bitmap.set(2).unwrap();
146        assert!(bitmap.is_set(2));
147    }
148
149    #[cfg(feature = "std")]
150    #[test]
151    fn test_message_roundtrip() {
152        let message = ISO8583Message::builder()
153            .mti(MessageType::AUTHORIZATION_REQUEST)
154            .field(Field::PrimaryAccountNumber, "4111111111111111")
155            .field(Field::ProcessingCode, "000000")
156            .field(Field::TransactionAmount, "000000010000")
157            .field(Field::SystemTraceAuditNumber, "123456")
158            .field(Field::LocalTransactionTime, "120000")
159            .field(Field::LocalTransactionDate, "0219")
160            .build()
161            .unwrap();
162
163        let bytes = message.to_bytes();
164        let parsed = ISO8583Message::from_bytes(&bytes).unwrap();
165
166        assert_eq!(parsed.mti, MessageType::AUTHORIZATION_REQUEST);
167    }
168}