Rename crate to escpos-vfd and add tokio support

Rename crate to escpos-vfd and add tokio support

Introduce a configurable crate-ready API with presets, typed errors,
optional Tokio async support, and expanded documentation.
This commit is contained in:
Кобелев Андрей Андреевич
2026-08-16 11:24:20 +05:00
parent efc53e6ef5
commit 244d907cc2
25 changed files with 3823 additions and 782 deletions
+38 -11
View File
@@ -1,39 +1,52 @@
//! Общие утилиты командной строки для всех демонстрационных программ.
//! Общие утилиты командной строки для демонстрационных программ.
//!
//! Каждый пример компилируется как отдельный binary. Этот модуль убирает повторение:
//! первый аргумент всегда serial-порт, второй - ширина дисплея, остальные параметры
//! зависят от конкретного примера.
#![allow(
dead_code,
reason = "модуль компилируется отдельно для каждого примера, поэтому часть API используется в соседних примерах"
)]
use m::vfd::VfdConfig;
use escpos_vfd::{Preset, VfdConfig};
use std::error::Error;
use std::str::FromStr;
use std::vec::IntoIter;
const DEFAULT_PORT: &str = "/dev/cu.usbmodem101";
const DEFAULT_WIDTH: usize = 20;
/// Общие аргументы примера: serial-порт, ширина дисплея и оставшиеся параметры.
/// Общие аргументы примера: готовая конфигурация, ширина дисплея и оставшиеся параметры.
pub struct ExampleArgs {
/// Конфигурация VFD на основе пресета текущего дисплея.
pub config: VfdConfig,
pub width: usize,
/// Ширина дисплея в символах.
pub columns: usize,
remaining: IntoIter<String>,
}
impl ExampleArgs {
/// Читает общие аргументы из командной строки и применяет безопасные значения по умолчанию.
pub fn from_env() -> Self {
/// Читает общие аргументы из командной строки и применяет значения по умолчанию.
pub fn from_env() -> Result<Self, Box<dyn Error>> {
let mut values = std::env::args().skip(1);
// Примеры должны запускаться без длинной CLI-команды на авторском стенде, но
// первый аргумент позволяет сразу проверить другой USB/COM-порт.
let port_name = values.next().unwrap_or_else(|| DEFAULT_PORT.to_string());
let width = values
// Геометрия дисплея участвует в проверке координат и обрезке строк. Меняем
// только ширину, потому что демонстрации ниже рассчитаны на две строки.
let columns = values
.next()
.and_then(|value| value.parse().ok())
.unwrap_or(DEFAULT_WIDTH);
let config = VfdConfig::new(port_name).with_width(width);
let config = preset_config(port_name, columns)?;
Self {
width: config.width,
Ok(Self {
columns,
config,
remaining: values.collect::<Vec<_>>().into_iter(),
}
})
}
/// Читает следующий аргумент нужного типа или возвращает переданное значение по умолчанию.
@@ -57,3 +70,17 @@ impl ExampleArgs {
pub fn sleep_ms(delay_ms: u64) {
std::thread::sleep(std::time::Duration::from_millis(delay_ms));
}
/// Создаёт конфигурацию пресета текущего дисплея с переопределяемой шириной.
pub fn preset_config(
port_name: impl Into<String>,
columns: usize,
) -> Result<VfdConfig, Box<dyn Error>> {
let mut config = VfdConfig::preset(port_name, Preset::Epson20x2Cp866)?;
// Пресет сохраняет baud/code table/кодировку, а ширину даём менять из CLI, чтобы
// теми же примерами проверять 16x2, 20x2 и другие ESC/POS-совместимые VFD.
config.display.columns = columns;
config.validate()?;
Ok(config)
}