pub struct Client<T: Read + Write, S: SequenceProvider> { /* private fields */ }Expand description
Synchronous HDM client.
Generic over the transport (anything that’s Read + Write) and the sequence-number provider
(anything implementing SequenceProvider). The split allows in-memory testing via
std::io::Cursor-style mocks and pluggable persistence (InMemorySeq, FileSeq, custom).
Threading: the client is not internally synchronised. Wrap in a Mutex if you need to
share it across threads. The HDM itself is single-session anyway, so concurrent calls don’t
make sense at the protocol layer.
Timeouts: Client does not enforce timeouts on its transport. Configure
set_read_timeout/set_write_timeout on a TcpStream before passing it to Self::new.
The spec’s §4.2 step 7 mandates a 50-second cap on response wait time.
Implementations§
Source§impl<T: Read + Write, S: SequenceProvider> Client<T, S>
impl<T: Read + Write, S: SequenceProvider> Client<T, S>
Sourcepub fn new(transport: T, password: impl Into<String>, seq: S) -> Self
pub fn new(transport: T, password: impl Into<String>, seq: S) -> Self
Build a new client over transport, deriving the password key from password.
Sourcepub const fn is_logged_in(&self) -> bool
pub const fn is_logged_in(&self) -> bool
Whether a session has been established via Self::login (and not invalidated).
Sourcepub const fn forget_session(&mut self)
pub const fn forget_session(&mut self)
Drop the in-memory session key. Does not notify the HDM — call Self::logout for that.
Sourcepub fn list_operators_and_departments(
&mut self,
) -> Result<ListOpsAndDepsResponse, Error>
pub fn list_operators_and_departments( &mut self, ) -> Result<ListOpsAndDepsResponse, Error>
Sourcepub fn login(
&mut self,
cashier: u32,
pin: impl Into<String>,
) -> Result<(), Error>
pub fn login( &mut self, cashier: u32, pin: impl Into<String>, ) -> Result<(), Error>
Op 2 (§4.5.2): operator login. On success the session key returned by the HDM is decoded and installed; subsequent operations use it transparently.
§Errors
Error::Serverwithkind = BadOperatorPassword / NoSuchOperator / InactiveOperatoron login failure.Error::Crypto(CryptoError::SessionKeyBase64/InvalidKeyLength) if the HDM returns akeyfield that isn’t valid 24-byte Base64 (would indicate a device bug).
Sourcepub fn logout(&mut self) -> Result<(), Error>
pub fn logout(&mut self) -> Result<(), Error>
Op 3 (§4.5.3): operator logout. Drops the session both server-side and locally.
§Errors
See Error. Returns Error::NotLoggedIn if Self::login hasn’t been called.
Sourcepub fn print_receipt(
&mut self,
request: PrintReceiptRequest,
) -> Result<ReceiptResponse, Error>
pub fn print_receipt( &mut self, request: PrintReceiptRequest, ) -> Result<ReceiptResponse, Error>
Op 4 (§4.5.4): print a fiscal receipt. The sequence number is assigned by the client.
§Errors
See Error. Common business errors:
NoSuchDepartment, BadAtgCode, PaidLessThanTotal, BadEmarkFormat,
PrinterOutOfPaper, HdmSyncRequired. Check ServerErrorKind::is_retryable and
ServerErrorKind::requires_relogin on the returned error.
Sourcepub fn print_last_receipt(&mut self) -> Result<EmptyResponse, Error>
pub fn print_last_receipt(&mut self) -> Result<EmptyResponse, Error>
Sourcepub fn get_returnable_receipt(
&mut self,
receipt_id: impl Into<String>,
crn: impl Into<String>,
) -> Result<ReturnableReceiptResponse, Error>
pub fn get_returnable_receipt( &mut self, receipt_id: impl Into<String>, crn: impl Into<String>, ) -> Result<ReturnableReceiptResponse, Error>
Op 6 (§4.5.6): look up the contents of a receipt you intend to return.
Read-only — returns the receipt’s items, amounts and eMarks so you can build the actual
return (Self::print_return_receipt, op 10). It registers nothing.
§Errors
See Error.
Sourcepub fn setup_header_logo(
&mut self,
logo_base64: impl Into<String>,
) -> Result<EmptyResponse, Error>
pub fn setup_header_logo( &mut self, logo_base64: impl Into<String>, ) -> Result<EmptyResponse, Error>
Sourcepub fn fiscal_report(
&mut self,
request: FiscalReportRequest,
) -> Result<EmptyResponse, Error>
pub fn fiscal_report( &mut self, request: FiscalReportRequest, ) -> Result<EmptyResponse, Error>
Sourcepub fn print_return_receipt(
&mut self,
request: PrintReturnReceiptRequest,
) -> Result<ReturnReceiptResponse, Error>
pub fn print_return_receipt( &mut self, request: PrintReturnReceiptRequest, ) -> Result<ReturnReceiptResponse, Error>
Op 10 (§4.5.7): print a return/refund receipt — the operation that actually registers a
return. Full, by-amount or per-item returns are driven via the request’s optional fields.
The read-only lookup of the receipt being returned is op 6 (Self::get_returnable_receipt).
§Errors
See Error.
Sourcepub fn cash_in_out(
&mut self,
request: CashInOutRequest,
) -> Result<EmptyResponse, Error>
pub fn cash_in_out( &mut self, request: CashInOutRequest, ) -> Result<EmptyResponse, Error>
Sourcepub fn date_time(&mut self) -> Result<DateTimeResponse, Error>
pub fn date_time(&mut self) -> Result<DateTimeResponse, Error>
Sourcepub fn receipt_sample(&mut self) -> Result<EmptyResponse, Error>
pub fn receipt_sample(&mut self) -> Result<EmptyResponse, Error>
Sourcepub fn hdm_time_sync(&mut self) -> Result<EmptyResponse, Error>
pub fn hdm_time_sync(&mut self) -> Result<EmptyResponse, Error>
Sourcepub fn payment_systems_list(
&mut self,
) -> Result<PaymentSystemsListResponse, Error>
pub fn payment_systems_list( &mut self, ) -> Result<PaymentSystemsListResponse, Error>
Op 15 (§4.8): list the payment systems configured on the HDM. Use this once at startup
to discover the code-to-name mapping for PrintReceiptRequest::payment_system rather
than hardcoding codes.
§Errors
See Error.