Skip to main content

Crate hdm_am

Crate hdm_am 

Source
Expand description

Client for the Armenian fiscal cash register (HDM) protocol.

Specification: State Revenue Committee of Armenia (ՀՀՊԵԿ), “ՀՍԿԻՉ - ԴՐԱՄԱՐԿՂԱՅԻՆ ՄԵՔԵՆԱՅԻ ԻՆՏԵԳՐՈՒՄԸ ԱՐՏԱՔԻՆ (ԱՌԵՎՏՐԱՅԻՆ) ԾՐԱԳՐԵՐԻ ՀԵՏ”, version 0.7.3 (April 2025). The original Armenian PDF and an English translation are checked in under docs/.

§Example

use hdm_am::{Client, Decimal, InMemorySeq, PrintMode, PrintReceiptRequest};
use std::net::TcpStream;
use std::time::Duration;

let mut tcp = TcpStream::connect("192.168.1.50:9000")?;
tcp.set_read_timeout(Some(Duration::from_secs(50)))?;
tcp.set_write_timeout(Some(Duration::from_secs(50)))?;

let mut client = Client::new(tcp, "hdm-password", InMemorySeq::default());
client.login(1, "1234")?;

let receipt = client.print_receipt(PrintReceiptRequest {
    mode: PrintMode::Simple,
    paid_amount: Decimal::from(1000),
    paid_amount_card: Decimal::ZERO,
    partial_amount: Decimal::ZERO,
    pre_payment_amount: Decimal::ZERO,
    dep: Some(1),
    partner_tin: None,
    use_ext_pos: false,
    payment_system: None,
    rrn: None,
    terminal_id: None,
    e_marks: vec![],
    items: vec![],
})?;

println!("fiscal number: {}", receipt.fiscal);

§Versions and forward compatibility

Three version axes are easy to confuse, so the crate keeps them separate:

  • Wire framing version — the byte in the request header (PROTOCOL_VERSION). Frozen at 05 since spec v0.5 (2017); one framing covers the whole live protocol.
  • Spec (document) version — which manual revision the operation/field set follows (SPEC_VERSION, currently 0.7.3). This is what grows over time.
  • Crate version — ordinary semver; not coupled to the spec version (the mapping lives in the changelog, not the version number).

The crate targets the current 0.7.x line and is built to tolerate newer devices without code changes:

  • Responses are forward-compatible. They are #[non_exhaustive], never use #[serde(deny_unknown_fields)], and put #[serde(default)] on later-added fields — so a newer firmware that returns extra fields still deserialises cleanly. Preserve this when adding ops.
  • Requests track a spec revision exactly. They are ordinary (exhaustive) structs, so a new request field introduced by a future spec is a breaking change shipped in a major release — a deliberate signal that the targeted SPEC_VERSION moved.

docs/history/ holds the full version lineage (v0.3–v0.7.3) and a runbook for adopting a new spec.

Re-exports§

pub use client::Client;
pub use error::CryptoError;
pub use error::Error;
pub use error::ServerErrorKind;
pub use error::VendorErrorKind;
pub use format::DEFAULT_WIDTH;
pub use format::ReceiptLayout;
pub use format::ReceiptLine;
pub use format::format_receipt;
pub use operations::CashInOutRequest;
pub use operations::DateTimeRequest;
pub use operations::DateTimeResponse;
pub use operations::DepartmentInfo;
pub use operations::DiscountKind;
pub use operations::EmptyResponse;
pub use operations::FiscalReportKind;
pub use operations::FiscalReportRequest;
pub use operations::GetReturnableReceiptRequest;
pub use operations::HdmTimeSyncRequest;
pub use operations::ListOpsAndDepsRequest;
pub use operations::ListOpsAndDepsResponse;
pub use operations::Operation;
pub use operations::OperatorInfo;
pub use operations::OperatorLoginRequest;
pub use operations::OperatorLoginResponse;
pub use operations::OperatorLogoutRequest;
pub use operations::PaymentSystemEntry;
pub use operations::PaymentSystemsListRequest;
pub use operations::PaymentSystemsListResponse;
pub use operations::PrintLastReceiptRequest;
pub use operations::PrintMode;
pub use operations::PrintReceiptRequest;
pub use operations::PrintReturnReceiptRequest;
pub use operations::ReceiptItem;
pub use operations::ReceiptResponse;
pub use operations::ReceiptSampleRequest;
pub use operations::ReportFilter;
pub use operations::ReturnItem;
pub use operations::ReturnReceiptResponse;
pub use operations::ReturnableReceiptItem;
pub use operations::ReturnableReceiptResponse;
pub use operations::SetupHeaderFooterRequest;
pub use operations::SetupHeaderLogoRequest;
pub use operations::SingleEmarkRequest;
pub use operations::TaxationKind;
pub use operations::TextAlign;
pub use operations::TextLine;
pub use probe::HdmIdentity;
pub use probe::identify;
pub use seq::FileSeq;
pub use seq::InMemorySeq;
pub use seq::SequenceProvider;

Modules§

client
High-level HDM client. Owns the transport, the encryption phase (password key before login, session key after), and the sequence-number provider; exposes one method per spec operation.
error
Error taxonomy with recovery semantics.
format
Render a fiscal receipt as human-friendly text from the wire request/response pair.
operations
Per-operation request and response shapes, serialised as JSON per spec §4.5.
probe
Credential-less endpoint identification.
seq
Request sequence-number provider (spec §4.4.5).

Structs§

Decimal
Re-exported so consumers can name monetary/quantity values without depending on rust_decimal directly. All amount and quantity fields use this type.

Enums§

OperationCode
HDM protocol operation codes. Codes 1-10 are v0.5; 11-16 were added through v0.7.3.

Constants§

PROTOCOL_VERSION
Wire framing version advertised in the request header (big-endian).
SPEC_VERSION
HDM specification (document) version this crate targets — the operation and field set follow this manual revision.