rxing/datamatrix/encoder/
x12_encoder.rs1use crate::common::Result;
18use crate::Exceptions;
19
20use super::{high_level_encoder, C40Encoder, Encoder, EncoderContext};
21
22pub struct X12Encoder(C40Encoder);
23impl Encoder for X12Encoder {
24 fn getEncodingMode(&self) -> usize {
25 high_level_encoder::X12_ENCODATION
26 }
27
28 fn encode(&self, context: &mut super::EncoderContext) -> Result<()> {
29 let mut buffer = String::new();
31 while context.hasMoreCharacters() {
32 let c = context.getCurrentChar();
33 context.pos += 1;
34
35 Self::encodeChar(c, &mut buffer)?;
36
37 let count = buffer.chars().count();
38 if (count % 3) == 0 {
39 C40Encoder::writeNextTriplet(context, &mut buffer)?;
40
41 let newMode = high_level_encoder::lookAheadTest(
42 context.getMessage(),
43 context.pos,
44 self.getEncodingMode() as u32,
45 );
46 if newMode != self.getEncodingMode() {
47 context.signalEncoderChange(high_level_encoder::ASCII_ENCODATION);
49 break;
50 }
51 }
52 }
53 Self::handleEOD(context, &mut buffer)?;
54 Ok(())
55 }
56}
57impl X12Encoder {
58 pub fn new() -> Self {
59 Self(C40Encoder::new())
60 }
61
62 fn encodeChar(c: char, sb: &mut String) -> Result<u32> {
63 match c {
64 '\r' => sb.push('\0'),
65 '*' => sb.push('\u{1}'),
66 '>' => sb.push('\u{2}'),
67 ' ' => sb.push('\u{3}'),
68 _ => {
69 if c.is_ascii_digit() {
70 sb.push((c as u8 - 48 + 4) as char);
71 } else if c.is_ascii_uppercase() {
72 sb.push((c as u8 - 65 + 14) as char);
73 } else {
74 high_level_encoder::illegalCharacter(c)?;
75 }
76 }
77 }
78 Ok(1)
79 }
80
81 fn handleEOD(context: &mut EncoderContext, buffer: &mut str) -> Result<()> {
82 context.updateSymbolInfo();
83 let available = context
84 .getSymbolInfo()
85 .ok_or(Exceptions::ILLEGAL_STATE)?
86 .getDataCapacity()
87 - context.getCodewordCount() as u32;
88 let count = buffer.chars().count();
89 context.pos -= count as u32;
90 if context.getRemainingCharacters() > 1
91 || available > 1
92 || context.getRemainingCharacters() != available
93 {
94 context.writeCodeword(high_level_encoder::X12_UNLATCH);
95 }
96 if context.getNewEncoding().is_none() {
97 context.signalEncoderChange(high_level_encoder::ASCII_ENCODATION);
98 }
99 Ok(())
100 }
101}
102
103impl Default for X12Encoder {
104 fn default() -> Self {
105 Self::new()
106 }
107}