test/
test.rs

1use std::io::{self, Write};
2use std::time::Duration;
3
4use catprinter::ble::{connect, scan};
5
6/// Example: Interactive CatPrinter session
7/// - Scans for BLE printers
8/// - Lets user select device
9/// - Prints text or image based on user input
10#[tokio::main]
11async fn main() -> Result<(), Box<dyn std::error::Error>> {
12    println!("Scanning for CatPrinter-compatible BLE devices for 3 seconds...");
13    let devices = scan(Duration::from_secs(3)).await?;
14    if devices.is_empty() {
15        println!(
16            "No devices found. Make sure your Bluetooth adapter is up and the printer is powered on and advertising."
17        );
18        return Ok(());
19    }
20
21    println!("Found devices:");
22    for (i, d) in devices.iter().enumerate() {
23        println!("  {}) id={} name={:?}", i + 1, d.id, d.name);
24    }
25
26    // Ask user to pick a device
27    let mut input = String::new();
28    loop {
29        print!("Select device number to connect to (1-{}): ", devices.len());
30        io::stdout().flush()?;
31        input.clear();
32        io::stdin().read_line(&mut input)?;
33        if let Ok(n) = input.trim().parse::<usize>() {
34            if n >= 1 && n <= devices.len() {
35                let chosen = &devices[n - 1];
36                println!(
37                    "Connecting to device id={} name={:?} ...",
38                    chosen.id, chosen.name
39                );
40                match connect(&chosen.id, Duration::from_secs(10)).await {
41                    Ok(printer) => {
42                        println!("Connected successfully.");
43                        run_interactive_session(printer).await?;
44                        return Ok(());
45                    }
46                    Err(e) => {
47                        eprintln!("Failed to connect: {}", e);
48                        // Ask to retry or choose another device
49                        print!("Try another device? (y/N): ");
50                        io::stdout().flush()?;
51                        input.clear();
52                        io::stdin().read_line(&mut input)?;
53                        if input.trim().to_lowercase() != "y" {
54                            return Ok(());
55                        } else {
56                            // re-list and continue loop to let user enter another index
57                            for (i, d) in devices.iter().enumerate() {
58                                println!("  {}) id={} name={:?}", i + 1, d.id, d.name);
59                            }
60                        }
61                    }
62                }
63                break;
64            }
65        }
66        println!("Invalid selection.");
67    }
68
69    Ok(())
70}
71
72/// Runs an interactive print session with the selected CatPrinter.
73/// Prompts user for text or image, then prints.
74async fn run_interactive_session(
75    printer: catprinter::ble::CatPrinterAsync,
76) -> Result<(), Box<dyn std::error::Error>> {
77    // Show status
78    println!("Querying printer status...");
79    match printer.get_status(Duration::from_secs(10)).await {
80        Ok(s) => {
81            println!(
82                "Status -> battery: {:?}, temperature: {:?}, state: {:?}",
83                s.battery_percent, s.temperature, s.state
84            );
85        }
86        Err(e) => {
87            eprintln!("Failed to get status: {}", e);
88        }
89    }
90    let mut mode = String::new();
91    // Prompt user for print mode
92    print!("Choose print mode: 1 for text, 2 for image: ");
93    io::stdout().flush()?;
94    io::stdin().read_line(&mut mode)?;
95
96    if mode.trim() == "1" {
97        // Prompt user for text and author
98        let mut main = String::new();
99        let mut author = String::new();
100        // Prompt for text and author
101        print!("Enter the main text to print: ");
102        io::stdout().flush()?;
103        io::stdin().read_line(&mut main)?;
104        print!("Enter the author name: ");
105        io::stdout().flush()?;
106        io::stdin().read_line(&mut author)?;
107        let main = main.trim();
108        let author = author.trim();
109
110        if main.is_empty() {
111            println!("No text entered, aborting.");
112            return Ok(());
113        }
114
115        // Print text
116        println!("Sending print job (text)...");
117        match printer.print_text(main, author).await {
118            Ok(()) => println!("Print job completed (printer reported AA/complete)."),
119            Err(e) => eprintln!("Print job failed: {}", e),
120        }
121    } else if mode.trim() == "2" {
122        let mut img_path = String::new();
123        // Prompt for image path
124        print!("Enter the path to the image: ");
125        io::stdout().flush()?;
126        io::stdin().read_line(&mut img_path)?;
127        let img_path = img_path.trim();
128
129        if img_path.is_empty() {
130            println!("No image path entered, aborting.");
131            return Ok(());
132        }
133
134        // Prompt for dithering mode
135        let mut dithering_mode = String::new();
136        print!("Choose dithering mode: 1=Threshold, 2=Floyd-Steinberg, 3=Atkinson, 4=Halftone: ");
137        io::stdout().flush()?;
138        io::stdin().read_line(&mut dithering_mode)?;
139        let dithering = match dithering_mode.trim() {
140            "2" => catprinter::dithering::ImageDithering::FloydSteinberg,
141            "3" => catprinter::dithering::ImageDithering::Atkinson,
142            "4" => catprinter::dithering::ImageDithering::Halftone,
143            _ => catprinter::dithering::ImageDithering::Threshold,
144        };
145
146        // Print image
147        println!("Sending print job (image)...");
148        match printer.print_image_from_path(img_path, dithering).await {
149            Ok(()) => println!("Print job completed (printer reported AA/complete)."),
150            Err(e) => eprintln!("Print job failed: {}", e),
151        }
152    } else {
153        println!("Invalid selection.");
154    }
155
156    Ok(())
157}