Skip to main content

hdm_am/operations/
config.rs

1use crate::wire::OperationCode;
2use serde::{Deserialize, Serialize, Serializer};
3
4use super::{EmptyResponse, Operation};
5
6/// Text alignment for header/footer lines.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8#[repr(u8)]
9pub enum TextAlign {
10    /// `1` — Left-aligned.
11    Left = 1,
12    /// `2` — Centered.
13    Centered = 2,
14    /// `3` — Right-aligned.
15    Right = 3,
16}
17
18impl Serialize for TextAlign {
19    fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
20        ser.serialize_u8(*self as u8)
21    }
22}
23
24impl<'de> Deserialize<'de> for TextAlign {
25    fn deserialize<D: serde::Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
26        let code = u8::deserialize(de)?;
27        Ok(match code {
28            1 => Self::Left,
29            2 => Self::Centered,
30            3 => Self::Right,
31            other => {
32                return Err(serde::de::Error::custom(format!(
33                    "unknown text alignment {other} (expected 1, 2, or 3)"
34                )));
35            }
36        })
37    }
38}
39
40/// A single line of header or footer text.
41#[derive(Debug, Clone, Serialize, Deserialize)]
42#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
43pub struct TextLine {
44    /// Alignment.
45    #[cfg_attr(feature = "schema", schemars(with = "u8"))]
46    pub align: TextAlign,
47    /// Bold flag, serialised as a JSON boolean (`true`/`false`) per the spec's field-type column
48    /// ("Boolean"). The spec's §4.6.3 JSON example loosely writes it as the integer `1`, but a
49    /// Newland N950 was verified to accept the boolean form (op 7 returned success).
50    pub bold: bool,
51    /// Font size (1 through 5).
52    pub fsize: u8,
53    /// Text content.
54    pub text: String,
55}
56
57/// Op 7 request: configure receipt header and footer lines.
58#[derive(Debug, Clone, Serialize, Deserialize)]
59#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
60pub struct SetupHeaderFooterRequest {
61    /// Header lines, in print order (top to bottom).
62    #[serde(default)]
63    pub headers: Vec<TextLine>,
64    /// Footer lines, in print order (top to bottom).
65    #[serde(default)]
66    pub footers: Vec<TextLine>,
67}
68
69impl Operation for SetupHeaderFooterRequest {
70    const CODE: OperationCode = OperationCode::SetupHeaderFooter;
71    type Response = EmptyResponse;
72}
73
74/// Op 8 request: upload a header logo image (Base64-encoded BMP, colour depth ≤4 bits).
75#[derive(Debug, Clone, Serialize, Deserialize)]
76#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
77pub struct SetupHeaderLogoRequest {
78    /// Logo image bytes encoded as a Base64 string. Per spec §4.6.4 the image must be in **BMP**
79    /// format with a colour depth of **no more than 4 bits** (≤16 colours; 1-bit monochrome is
80    /// fine). Note: the English translation's "must not exceed 4 pixels in height" is a
81    /// mistranslation of the original "must not contain more than 4 bits of colour".
82    #[serde(rename = "headerLogo")]
83    pub header_logo: String,
84}
85
86impl Operation for SetupHeaderLogoRequest {
87    const CODE: OperationCode = OperationCode::SetupHeaderLogo;
88    type Response = EmptyResponse;
89}