use std::sync::{Arc, Mutex};
use psdk_father::types::psdk_types::PsdkPrinterCommandEnumValue;
use psdk_father::{
args::{ArgContext, PsdkArgBase, PsdkEasyArg},
command::{CommandClause, PsdkTextCommand},
errors::PsdkFatherResult,
};
use crate::marks::{CodeRotation, CorrectLevel};
#[derive(Clone, Debug)]
pub struct CQRCodeOptions {
pub x: i32,
pub y: i32,
pub content: String,
pub code_rotation: Option<CodeRotation>,
pub width: i32,
pub level: Option<CorrectLevel>,
}
#[derive(Clone, Debug)]
pub struct CQRCode {
options: CQRCodeOptions,
ctx: Arc<Mutex<ArgContext>>,
}
impl CQRCode {
pub fn new(options: CQRCodeOptions) -> Self {
Self {
options,
ctx: Default::default(),
}
}
}
impl<T: Into<String>> From<(i32, i32, T, i32)> for CQRCode {
fn from((x, y, content, width): (i32, i32, T, i32)) -> Self {
Self::new(CQRCodeOptions {
x,
y,
content: content.into(),
code_rotation: None,
width,
level: None,
})
}
}
impl PsdkEasyArg<String> for CQRCode {
fn context(&self) -> Arc<Mutex<ArgContext>> {
self.ctx.clone()
}
}
impl PsdkArgBase<String> for CQRCode {
fn header(&self) -> String {
"SETQRVER".to_string()
}
fn clause(&self) -> PsdkFatherResult<CommandClause> {
let mut ptc = PsdkTextCommand::with_header_format_cpcl_and_charset(self.header(), "utf-8");
let code_rotation = self
.options
.code_rotation
.clone()
.unwrap_or(CodeRotation::Rotation0);
let level = self.options.level.clone().unwrap_or(CorrectLevel::L);
let level_string = format!(
"{}\n{}",
level.get_level_num(),
code_rotation.command_value()
);
let content = self.options.content.replace(['\r', '\n'], " ");
let level_num_string = format!(
"{}\n{}A,{}\n{}",
self.options.width,
level.get_level(),
content,
"ENDQR"
);
ptc
.append(level_string)
.append("QR")
.append(self.options.x)
.append(self.options.y)
.append("M")
.append("2")
.append("U")
.append(level_num_string);
Ok(ptc.clause())
}
}
psdk_father::impl_psdk_arg_to_easy_arg!(String, CQRCode, true);