rustyasn

Crates.iorustyasn
lib.rsrustyasn
version0.7.4
created_at2025-07-14 19:07:55.008581+00
updated_at2025-07-14 19:07:55.008581+00
descriptionAbstract Syntax Notation One (ASN.1) encoding support for RustyFix
homepage
repositoryhttps://github.com/rusty-trading/rusty-fix-engine
max_upload_size
id1752195
size339,897
cognitive (cognitive-glitch)

documentation

https://docs.rs/rustyasn

README

RustyASN

Abstract Syntax Notation One (ASN.1) encoding support for the RustyFix FIX protocol implementation.

Features

  • Multiple encoding rules: BER, DER, OER
  • Zero-copy decoding where possible
  • Streaming support for continuous message processing
  • Type-safe ASN.1 schema compilation
  • High-performance implementation optimized for low-latency trading
  • Integration with RustyFix field types and dictionaries

Supported Encoding Rules

  • BER (Basic Encoding Rules) - Self-describing, flexible format
  • DER (Distinguished Encoding Rules) - Canonical subset of BER, deterministic encoding
  • OER (Octet Encoding Rules) - Byte-aligned, balance between efficiency and simplicity

Usage

Add to your Cargo.toml:

[dependencies]
rustyasn = "0.7.4"

Basic Encoding/Decoding

use rustyasn::{Config, Encoder, Decoder, EncodingRule};
use rustyfix_dictionary::Dictionary;
use std::sync::Arc;

fn basic_example() -> Result<(), Box<dyn std::error::Error>> {
    // Setup
    let dict = Arc::new(Dictionary::fix44()?);
    let config = Config::new(EncodingRule::DER);
    let encoder = Encoder::new(config.clone(), dict.clone());
    let decoder = Decoder::new(config, dict);

    // Encode a message
    let mut handle = encoder.start_message(
        "D",           // MsgType: NewOrderSingle
        "SENDER001",   // SenderCompID
        "TARGET001",   // TargetCompID
        1,             // MsgSeqNum
    );

    handle
        .add_string(11, "CL001")      // ClOrdID
        .add_string(55, "EUR/USD")    // Symbol
        .add_int(54, 1)               // Side (1=Buy)
        .add_uint(38, 1_000_000)      // OrderQty
        .add_string(52, "20240101-12:00:00"); // SendingTime

    let encoded = handle.encode()?;

    // Decode the message
    let decoded = decoder.decode(&encoded)?;
    assert_eq!(decoded.msg_type(), "D");
    assert_eq!(decoded.get_string(55), Some("EUR/USD".to_string()));
    
    Ok(())
}

Run the example: cargo run --example basic_usage

Streaming Decoder

For processing multiple messages from a continuous stream:

use rustyasn::{Config, DecoderStreaming, EncodingRule};
use rustyfix_dictionary::Dictionary;
use std::sync::Arc;

fn streaming_example() -> Result<(), Box<dyn std::error::Error>> {
    let dict = Arc::new(Dictionary::fix44()?);
    let config = Config::new(EncodingRule::DER);
    let mut decoder = DecoderStreaming::new(config, dict);

    // Simulate feeding data in chunks (as would happen from network/file)
    let data_chunk = vec![/* your message data */];
    decoder.feed(&data_chunk);
    
    // Process any complete messages that have been decoded
    while let Ok(Some(message)) = decoder.decode_next() {
        println!("Received: {} from {} (seq: {})", 
            message.msg_type(), 
            message.sender_comp_id(),
            message.msg_seq_num()
        );
    }
    
    Ok(())
}

Run the example: cargo run --example streaming_decoder

Configuration Profiles

use rustyasn::{Config, EncodingRule};

// Optimized for low-latency trading
let low_latency_config = Config::low_latency();  // Uses OER, skips validation

// Optimized for reliability and compliance
let high_reliability_config = Config::high_reliability();  // Uses DER, full validation

// Custom configuration
let mut custom_config = Config::new(EncodingRule::OER);
custom_config.max_message_size = 16 * 1024;  // 16KB limit
custom_config.enable_zero_copy = true;
custom_config.validate_checksums = false;    // Disable for performance

Run the example: cargo run --example configuration

Performance Considerations

  1. Encoding Rule Selection:

    • OER: Most compact of supported rules, best for low-latency
    • DER: Deterministic, best for audit trails
    • BER: Most flexible, larger size
  2. Zero-Copy Operations: Enable with config.enable_zero_copy = true

  3. Buffer Management: Pre-allocate buffers for streaming operations

  4. Validation: Disable checksum validation in low-latency scenarios

Integration with SOFH

RustyASN integrates with Simple Open Framing Header (SOFH) for message framing:

use rustyasn::EncodingRule;

// Map ASN.1 encoding rules to SOFH encoding types
fn map_asn1_to_sofh(rule: EncodingRule) -> EncodingType {
    match rule {
        EncodingRule::BER | EncodingRule::DER => EncodingType::Asn1BER,
        EncodingRule::OER => EncodingType::Asn1OER,
    }
}

Run the example: cargo run --example sofh_integration

Safety and Security

  • Maximum message size limits prevent DoS attacks
  • Recursion depth limits prevent stack overflow
  • Input validation for all field types
  • Safe parsing of untrusted input

License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Commit count: 0

cargo fmt