| Name | Message | Date |
|---|---|---|
| 📄 escpos_printer.rs | 1 month ago | |
| 📄 main.rs | 1 month ago | |
| 📄 proto.rs | - | |
| 📄 receipt_printer_service.rs | 1 month ago |
📄
src/receipt_printer_service.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use tonic::{Request, Response, Status}; use typst::foundations::{Dict, IntoValue}; use typst::layout::PagedDocument; use typst_as_lib::TypstEngine; use typst_as_lib::typst_kit_options::TypstKitFontOptions; use crate::escpos_printer::EscposPrinter; use crate::proto::print_request::Content; use crate::proto::receipt_printer_server::ReceiptPrinter; use crate::proto::{PrintRequest, PrintResponse, TypstContent}; #[derive(Debug)] pub struct ReceiptPrinterService { template_path: String, printer_host: String, printer_port: u16, } impl ReceiptPrinterService { pub fn new(template_path: String, printer_host: String, printer_port: u16) -> Self { Self { template_path, printer_host, printer_port, } } } #[tonic::async_trait] impl ReceiptPrinter for ReceiptPrinterService { async fn print( &self, request: Request<PrintRequest>, ) -> Result<Response<PrintResponse>, Status> { let Some(Content::Typst(TypstContent { content: Some(content), })) = &request.get_ref().content else { println!("No Typst content received"); return Ok(Response::new(PrintResponse::default())); }; let engine = TypstEngine::builder() .with_file_system_resolver(".") .search_fonts_with(TypstKitFontOptions::new().include_system_fonts(true)) .build(); println!("Compiling document..."); let mut inputs = Dict::new(); inputs.insert("content".into(), content.clone().into_value()); let document: PagedDocument = match engine .compile_with_input(self.template_path.as_ref(), inputs) .output { Ok(document) => document, Err(error) => { println!("Failed to compile with message: {error}"); return Ok(Response::new(PrintResponse::default())); } }; println!("Rendering document..."); let pixmap = typst_render::render(&document.pages[0], EscposPrinter::IMAGE_PIXELS_PER_PT); println!("Pixel size: {}x{}", pixmap.width(), pixmap.height()); let png = match pixmap.encode_png() { Ok(png) => png, Err(error) => { println!("Could not encode image to PNG: {error}"); return Ok(Response::new(PrintResponse::default())); } }; println!("Connecting to printer..."); let mut printer = match EscposPrinter::open(self.printer_host.as_ref(), self.printer_port) { Ok(printer) => printer, Err(error) => { println!("Error connecting to printer: {error}"); return Ok(Response::new(PrintResponse::default())); } }; println!("Printing..."); if let Err(error) = printer.print_image(&png) { println!("Error when printing: {error}"); return Ok(Response::new(PrintResponse::default())); } println!("Done!"); Ok(Response::new(PrintResponse::default())) } }