tauri_plugin_serialplugin/
commands.rs

1//! Command functions for serial port operations
2//! 
3//! This module contains all the Tauri command functions that can be used
4//! to interact with serial ports. These functions can be imported and used
5//! directly in your Rust code.
6//! 
7//! # Example
8//! 
9//! ```rust
10//! use tauri_plugin_serialplugin::commands::{available_ports, open, write, read, close};
11//! use tauri_plugin_serialplugin::state::{DataBits, FlowControl, Parity, StopBits};
12//! use tauri::{AppHandle, State};
13//! 
14//! #[tauri::command]
15//! async fn my_serial_function(
16//!     app: AppHandle<tauri::Wry>,
17//!     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
18//! ) -> Result<(), String> {
19//!     // Get available ports
20//!     let ports = available_ports(app.clone(), serial.clone())
21//!         .map_err(|e| e.to_string())?;
22//!     
23//!     // Open a port
24//!     open(app.clone(), serial.clone(), "COM1".to_string(), 9600, None, None, None, None, None)
25//!         .map_err(|e| e.to_string())?;
26//!     
27//!     // Write data
28//!     write(app.clone(), serial.clone(), "COM1".to_string(), "Hello".to_string())
29//!         .map_err(|e| e.to_string())?;
30//!     
31//!     // Read data
32//!     let data = read(app.clone(), serial.clone(), "COM1".to_string(), Some(1000), Some(1024))
33//!         .map_err(|e| e.to_string())?;
34//!     
35//!     // Close port
36//!     close(app, serial, "COM1".to_string())
37//!         .map_err(|e| e.to_string())?;
38//!     
39//!     Ok(())
40//! }
41//! ```
42
43#[cfg(desktop)]
44use crate::desktop_api::SerialPort;
45use crate::error::Error;
46#[cfg(mobile)]
47use crate::mobile_api::SerialPort;
48use crate::state::{ClearBuffer, DataBits, FlowControl, Parity, StopBits};
49use std::collections::HashMap;
50use std::time::Duration;
51use tauri::{AppHandle, Runtime, State};
52
53/// Lists all available serial ports on the system
54/// 
55/// Returns a map of port names to port information including type, manufacturer, product, etc.
56/// 
57/// # Arguments
58/// 
59/// * `_app` - The Tauri app handle
60/// * `serial` - The serial port state
61/// 
62/// # Returns
63/// 
64/// A `HashMap` where keys are port names (e.g., "COM1", "/dev/ttyUSB0") and values are
65/// maps containing port information like type, manufacturer, product, etc.
66/// 
67/// # Example
68/// 
69/// ```rust
70/// use tauri_plugin_serialplugin::commands::available_ports;
71/// use tauri::{AppHandle, State};
72/// 
73/// #[tauri::command]
74/// async fn list_ports(
75///     app: AppHandle<tauri::Wry>,
76///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
77/// ) -> Result<(), String> {
78///     let ports = available_ports(app, serial)
79///         .map_err(|e| e.to_string())?;
80///     println!("Available ports: {:?}", ports);
81///     Ok(())
82/// }
83/// ```
84/// 
85/// # JavaScript Equivalent
86/// 
87/// ```javascript
88/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
89/// 
90/// const ports = await SerialPort.available_ports();
91/// console.log("Available ports:", ports);
92/// ```
93#[tauri::command]
94pub fn available_ports<R: Runtime>(
95    _app: AppHandle<R>,
96    serial: State<'_, SerialPort<R>>,
97) -> Result<HashMap<String, HashMap<String, String>>, Error> {
98    serial.available_ports()
99}
100
101/// Lists all available serial ports using platform-specific commands
102/// 
103/// This function uses platform-specific system commands to detect serial ports,
104/// which can provide more detailed information than the standard detection method.
105/// 
106/// # Arguments
107/// 
108/// * `_app` - The Tauri app handle
109/// * `serial` - The serial port state
110/// 
111/// # Returns
112/// 
113/// A `HashMap` where keys are port names and values are maps containing
114/// detailed port information obtained through platform-specific commands.
115/// 
116/// # Example
117/// 
118/// ```rust
119/// use tauri_plugin_serialplugin::commands::available_ports_direct;
120/// use tauri::{AppHandle, State};
121/// 
122/// #[tauri::command]
123/// async fn list_ports_detailed(
124///     app: AppHandle<tauri::Wry>,
125///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
126/// ) -> Result<(), String> {
127///     let ports = available_ports_direct(app, serial)
128///         .map_err(|e| e.to_string())?;
129///     println!("Detailed port information: {:?}", ports);
130///     Ok(())
131/// }
132/// ```
133/// 
134/// # JavaScript Equivalent
135/// 
136/// ```javascript
137/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
138/// 
139/// const ports = await SerialPort.available_ports_direct();
140/// console.log("Detailed port information:", ports);
141/// ```
142#[tauri::command]
143pub fn available_ports_direct<R: Runtime>(
144    _app: AppHandle<R>,
145    serial: State<'_, SerialPort<R>>,
146) -> Result<HashMap<String, HashMap<String, String>>, Error> {
147    serial.available_ports_direct()
148}
149
150/// Lists all currently managed serial ports
151/// 
152/// Returns a list of port names that are currently open and managed by the application.
153/// These are ports that have been opened but not yet closed.
154/// 
155/// # Arguments
156/// 
157/// * `_app` - The Tauri app handle
158/// * `serial` - The serial port state
159/// 
160/// # Returns
161/// 
162/// A `Vec<String>` containing the names of all currently managed ports.
163/// 
164/// # Example
165/// 
166/// ```rust
167/// use tauri_plugin_serialplugin::commands::managed_ports;
168/// use tauri::{AppHandle, State};
169/// 
170/// #[tauri::command]
171/// async fn list_open_ports(
172///     app: AppHandle<tauri::Wry>,
173///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
174/// ) -> Result<(), String> {
175///     let open_ports = managed_ports(app, serial)
176///         .map_err(|e| e.to_string())?;
177///     println!("Currently open ports: {:?}", open_ports);
178///     Ok(())
179/// }
180/// ```
181/// 
182/// # JavaScript Equivalent
183/// 
184/// ```javascript
185/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
186/// 
187/// const openPorts = await SerialPort.managed_ports();
188/// console.log("Currently open ports:", openPorts);
189/// ```
190#[tauri::command]
191pub fn managed_ports<R: Runtime>(
192    _app: AppHandle<R>,
193    serial: State<'_, SerialPort<R>>,
194) -> Result<Vec<String>, Error> {
195    serial.managed_ports()
196}
197
198/// Cancels ongoing read operations on a serial port
199/// 
200/// Stops any active read operations on the specified port. This is useful
201/// for interrupting long-running read operations or cleaning up resources.
202/// 
203/// # Arguments
204/// 
205/// * `_app` - The Tauri app handle
206/// * `serial` - The serial port state
207/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
208/// 
209/// # Returns
210/// 
211/// `Ok(())` if the read operation was cancelled successfully, or an `Error` if it failed.
212/// 
213/// # Example
214/// 
215/// ```rust
216/// use tauri_plugin_serialplugin::commands::cancel_read;
217/// use tauri::{AppHandle, State};
218/// 
219/// #[tauri::command]
220/// async fn stop_reading(
221///     app: AppHandle<tauri::Wry>,
222///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
223/// ) -> Result<(), String> {
224///     cancel_read(app, serial, "COM1".to_string()).map_err(|e| e.to_string())
225/// }
226/// ```
227/// 
228/// # JavaScript Equivalent
229/// 
230/// ```javascript
231/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
232/// 
233/// const port = new SerialPort({ path: "COM1" });
234/// await port.cancelListen();
235/// ```
236#[tauri::command]
237pub fn cancel_read<R: Runtime>(
238    _app: AppHandle<R>,
239    serial: State<'_, SerialPort<R>>,
240    path: String,
241) -> Result<(), Error> {
242    serial.cancel_read(path)
243}
244
245/// Closes a serial port
246/// 
247/// Closes the specified serial port and releases all associated resources.
248/// The port must be open before it can be closed.
249/// 
250/// # Arguments
251/// 
252/// * `_app` - The Tauri app handle
253/// * `serial` - The serial port state
254/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
255/// 
256/// # Returns
257/// 
258/// `Ok(())` if the port was closed successfully, or an `Error` if it failed.
259/// 
260/// # Example
261/// 
262/// ```rust
263/// use tauri_plugin_serialplugin::commands::close;
264/// use tauri::{AppHandle, State};
265/// 
266/// #[tauri::command]
267/// async fn close_serial_port(
268///     app: AppHandle<tauri::Wry>,
269///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
270/// ) -> Result<(), String> {
271///     close(app, serial, "COM1".to_string()).map_err(|e| e.to_string())
272/// }
273/// ```
274/// 
275/// # JavaScript Equivalent
276/// 
277/// ```javascript
278/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
279/// 
280/// const port = new SerialPort({ path: "COM1" });
281/// await port.close();
282/// ```
283#[tauri::command]
284pub fn close<R: Runtime>(
285    _app: AppHandle<R>,
286    serial: State<'_, SerialPort<R>>,
287    path: String,
288) -> Result<(), Error> {
289    serial.close(path)
290}
291
292/// Closes all open serial ports
293/// 
294/// Closes all currently open serial ports and releases all associated resources.
295/// This is useful for cleanup when shutting down the application.
296/// 
297/// # Arguments
298/// 
299/// * `_app` - The Tauri app handle
300/// * `serial` - The serial port state
301/// 
302/// # Returns
303/// 
304/// `Ok(())` if all ports were closed successfully, or an `Error` if any failed.
305/// 
306/// # Example
307/// 
308/// ```rust
309/// use tauri_plugin_serialplugin::commands::close_all;
310/// use tauri::{AppHandle, State};
311/// 
312/// #[tauri::command]
313/// async fn cleanup_ports(
314///     app: AppHandle<tauri::Wry>,
315///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
316/// ) -> Result<(), String> {
317///     close_all(app, serial).map_err(|e| e.to_string())
318/// }
319/// ```
320/// 
321/// # JavaScript Equivalent
322/// 
323/// ```javascript
324/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
325/// 
326/// await SerialPort.closeAll();
327/// ```
328#[tauri::command]
329pub fn close_all<R: Runtime>(
330    _app: AppHandle<R>,
331    serial: State<'_, SerialPort<R>>,
332) -> Result<(), Error> {
333    serial.close_all()
334}
335
336/// Forcefully closes a serial port
337/// 
338/// Forcefully closes the specified serial port, even if it's in use or has
339/// active operations. This should be used as a last resort when normal
340/// closing fails.
341/// 
342/// # Arguments
343/// 
344/// * `_app` - The Tauri app handle
345/// * `serial` - The serial port state
346/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
347/// 
348/// # Returns
349/// 
350/// `Ok(())` if the port was force closed successfully, or an `Error` if it failed.
351/// 
352/// # Example
353/// 
354/// ```rust
355/// use tauri_plugin_serialplugin::commands::force_close;
356/// use tauri::{AppHandle, State};
357/// 
358/// #[tauri::command]
359/// async fn emergency_close(
360///     app: AppHandle<tauri::Wry>,
361///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
362/// ) -> Result<(), String> {
363///     force_close(app, serial, "COM1".to_string()).map_err(|e| e.to_string())
364/// }
365/// ```
366/// 
367/// # JavaScript Equivalent
368/// 
369/// ```javascript
370/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
371/// 
372/// const port = new SerialPort({ path: "COM1" });
373/// await port.forceClose();
374/// ```
375#[tauri::command]
376pub fn force_close<R: Runtime>(
377    _app: AppHandle<R>,
378    serial: State<'_, SerialPort<R>>,
379    path: String,
380) -> Result<(), Error> {
381    serial.force_close(path)
382}
383
384/// Opens a serial port with the specified configuration
385/// 
386/// Opens a serial port and configures it with the given parameters. The port must be closed
387/// before it can be opened again.
388/// 
389/// # Arguments
390/// 
391/// * `_app` - The Tauri app handle
392/// * `serial` - The serial port state
393/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
394/// * `baud_rate` - The baud rate for communication (e.g., 9600, 115200)
395/// * `data_bits` - Number of data bits per character (5, 6, 7, or 8)
396/// * `flow_control` - Flow control mode (None, Software, or Hardware)
397/// * `parity` - Parity checking mode (None, Odd, or Even)
398/// * `stop_bits` - Number of stop bits (One or Two)
399/// * `timeout` - Read timeout in milliseconds
400/// 
401/// # Returns
402/// 
403/// `Ok(())` if the port was opened successfully, or an `Error` if it failed.
404/// 
405/// # Example
406/// 
407/// ```rust
408/// use tauri_plugin_serialplugin::commands::open;
409/// use tauri_plugin_serialplugin::state::{DataBits, FlowControl, Parity, StopBits};
410/// use tauri::{AppHandle, State};
411/// 
412/// #[tauri::command]
413/// async fn open_serial_port(
414///     app: AppHandle<tauri::Wry>,
415///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
416/// ) -> Result<(), String> {
417///     open(
418///         app,
419///         serial,
420///         "COM1".to_string(),
421///         9600,
422///         Some(DataBits::Eight),
423///         Some(FlowControl::None),
424///         Some(Parity::None),
425///         Some(StopBits::One),
426///         Some(1000)
427///     ).map_err(|e| e.to_string())
428/// }
429/// ```
430/// 
431/// # JavaScript Equivalent
432/// 
433/// ```javascript
434/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
435/// 
436/// const port = new SerialPort({
437///   path: "COM1",
438///   baudRate: 9600,
439///   dataBits: 8,
440///   flowControl: 0, // None
441///   parity: 0,      // None
442///   stopBits: 1
443/// });
444/// await port.open();
445/// ```
446#[tauri::command]
447pub fn open<R: Runtime>(
448    _app: AppHandle<R>,
449    serial: State<'_, SerialPort<R>>,
450    path: String,
451    baud_rate: u32,
452    data_bits: Option<DataBits>,
453    flow_control: Option<FlowControl>,
454    parity: Option<Parity>,
455    stop_bits: Option<StopBits>,
456    timeout: Option<u64>,
457) -> Result<(), Error> {
458    serial.open(
459        path,
460        baud_rate,
461        data_bits,
462        flow_control,
463        parity,
464        stop_bits,
465        timeout,
466    )
467}
468
469/// Writes string data to a serial port
470/// 
471/// Sends the specified string data to the serial port. The port must be open before
472/// writing data.
473/// 
474/// # Arguments
475/// 
476/// * `_app` - The Tauri app handle
477/// * `serial` - The serial port state
478/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
479/// * `value` - The string data to write to the port
480/// 
481/// # Returns
482/// 
483/// The number of bytes written, or an `Error` if the operation failed.
484/// 
485/// # Example
486/// 
487/// ```rust
488/// use tauri_plugin_serialplugin::commands::write;
489/// use tauri::{AppHandle, State};
490/// 
491/// #[tauri::command]
492/// async fn send_data(
493///     app: AppHandle<tauri::Wry>,
494///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
495/// ) -> Result<(), String> {
496///     let bytes_written = write(app, serial, "COM1".to_string(), "Hello World".to_string())
497///         .map_err(|e| e.to_string())?;
498///     println!("Wrote {} bytes", bytes_written);
499///     Ok(())
500/// }
501/// ```
502/// 
503/// # JavaScript Equivalent
504/// 
505/// ```javascript
506/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
507/// 
508/// const port = new SerialPort({ path: "COM1" });
509/// await port.open();
510/// const bytesWritten = await port.write("Hello World");
511/// console.log(`Wrote ${bytesWritten} bytes`);
512/// ```
513#[tauri::command]
514pub fn write<R: Runtime>(
515    _app: AppHandle<R>,
516    serial: State<'_, SerialPort<R>>,
517    path: String,
518    value: String,
519) -> Result<usize, Error> {
520    serial.write(path, value)
521}
522
523/// Writes binary data to a serial port
524/// 
525/// Sends the specified binary data (as a vector of bytes) to the serial port.
526/// The port must be open before writing data.
527/// 
528/// # Arguments
529/// 
530/// * `_app` - The Tauri app handle
531/// * `serial` - The serial port state
532/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
533/// * `value` - The binary data to write as a vector of bytes
534/// 
535/// # Returns
536/// 
537/// The number of bytes written, or an `Error` if the operation failed.
538/// 
539/// # Example
540/// 
541/// ```rust
542/// use tauri_plugin_serialplugin::commands::write_binary;
543/// use tauri::{AppHandle, State};
544/// 
545/// #[tauri::command]
546/// async fn send_binary_data(
547///     app: AppHandle<tauri::Wry>,
548///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
549/// ) -> Result<(), String> {
550///     let binary_data = vec![0x48, 0x65, 0x6C, 0x6C, 0x6F]; // "Hello" in ASCII
551///     let bytes_written = write_binary(app, serial, "COM1".to_string(), binary_data)
552///         .map_err(|e| e.to_string())?;
553///     println!("Wrote {} bytes of binary data", bytes_written);
554///     Ok(())
555/// }
556/// ```
557/// 
558/// # JavaScript Equivalent
559/// 
560/// ```javascript
561/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
562/// 
563/// const port = new SerialPort({ path: "COM1" });
564/// await port.open();
565/// const binaryData = new Uint8Array([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello" in ASCII
566/// const bytesWritten = await port.writeBinary(binaryData);
567/// console.log(`Wrote ${bytesWritten} bytes of binary data`);
568/// ```
569#[tauri::command]
570pub fn write_binary<R: Runtime>(
571    _app: AppHandle<R>,
572    serial: State<'_, SerialPort<R>>,
573    path: String,
574    value: Vec<u8>,
575) -> Result<usize, Error> {
576    serial.write_binary(path, value)
577}
578
579/// Reads string data from a serial port
580/// 
581/// Reads data from the serial port and returns it as a string. The port must be open
582/// before reading data.
583/// 
584/// # Arguments
585/// 
586/// * `_app` - The Tauri app handle
587/// * `serial` - The serial port state
588/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
589/// * `timeout` - Read timeout in milliseconds (None for no timeout)
590/// * `size` - Maximum number of bytes to read (None for unlimited)
591/// 
592/// # Returns
593/// 
594/// The string data read from the port, or an `Error` if the operation failed.
595/// 
596/// # Example
597/// 
598/// ```rust
599/// use tauri_plugin_serialplugin::commands::read;
600/// use tauri::{AppHandle, State};
601/// 
602/// #[tauri::command]
603/// async fn receive_data(
604///     app: AppHandle<tauri::Wry>,
605///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
606/// ) -> Result<(), String> {
607///     let data = read(app, serial, "COM1".to_string(), Some(1000), Some(1024))
608///         .map_err(|e| e.to_string())?;
609///     println!("Received: {}", data);
610///     Ok(())
611/// }
612/// ```
613/// 
614/// # JavaScript Equivalent
615/// 
616/// ```javascript
617/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
618/// 
619/// const port = new SerialPort({ path: "COM1" });
620/// await port.open();
621/// const data = await port.read({ timeout: 1000, size: 1024 });
622/// console.log("Received:", data);
623/// ```
624#[tauri::command]
625pub fn read<R: Runtime>(
626    _app: AppHandle<R>,
627    serial: State<'_, SerialPort<R>>,
628    path: String,
629    timeout: Option<u64>,
630    size: Option<usize>,
631) -> Result<String, Error> {
632    serial.read(path, timeout, size)
633}
634
635/// Reads binary data from a serial port
636/// 
637/// Reads binary data from the serial port and returns it as a vector of bytes.
638/// The port must be open before reading data.
639/// 
640/// # Arguments
641/// 
642/// * `_app` - The Tauri app handle
643/// * `serial` - The serial port state
644/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
645/// * `timeout` - Read timeout in milliseconds (None for no timeout)
646/// * `size` - Maximum number of bytes to read (None for unlimited)
647/// 
648/// # Returns
649/// 
650/// The binary data read from the port as a vector of bytes, or an `Error` if the operation failed.
651/// 
652/// # Example
653/// 
654/// ```rust
655/// use tauri_plugin_serialplugin::commands::read_binary;
656/// use tauri::{AppHandle, State};
657/// 
658/// #[tauri::command]
659/// async fn receive_binary_data(
660///     app: AppHandle<tauri::Wry>,
661///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
662/// ) -> Result<(), String> {
663///     let data = read_binary(app, serial, "COM1".to_string(), Some(1000), Some(256))
664///         .map_err(|e| e.to_string())?;
665///     println!("Received {} bytes: {:?}", data.len(), data);
666///     Ok(())
667/// }
668/// ```
669/// 
670/// # JavaScript Equivalent
671/// 
672/// ```javascript
673/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
674/// 
675/// const port = new SerialPort({ path: "COM1" });
676/// await port.open();
677/// const data = await port.readBinary({ timeout: 1000, size: 256 });
678/// console.log(`Received ${data.length} bytes:`, data);
679/// ```
680#[tauri::command]
681pub fn read_binary<R: Runtime>(
682    _app: AppHandle<R>,
683    serial: State<'_, SerialPort<R>>,
684    path: String,
685    timeout: Option<u64>,
686    size: Option<usize>,
687) -> Result<Vec<u8>, Error> {
688    serial.read_binary(path, timeout, size)
689}
690
691/// Starts listening for data on a serial port
692/// 
693/// Begins continuous monitoring of the serial port for incoming data.
694/// This creates a background thread that continuously reads data from the port.
695/// 
696/// # Arguments
697/// 
698/// * `_app` - The Tauri app handle
699/// * `serial` - The serial port state
700/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
701/// * `timeout` - Read timeout in milliseconds (None for no timeout)
702/// * `size` - Maximum number of bytes to read per operation (None for unlimited)
703/// 
704/// # Returns
705/// 
706/// `Ok(())` if listening started successfully, or an `Error` if it failed.
707/// 
708/// # Example
709/// 
710/// ```rust
711/// use tauri_plugin_serialplugin::commands::start_listening;
712/// use tauri::{AppHandle, State};
713/// 
714/// #[tauri::command]
715/// async fn begin_monitoring(
716///     app: AppHandle<tauri::Wry>,
717///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
718/// ) -> Result<(), String> {
719///     start_listening(app, serial, "COM1".to_string(), Some(1000), Some(1024))
720///         .map_err(|e| e.to_string())
721/// }
722/// ```
723/// 
724/// # JavaScript Equivalent
725/// 
726/// ```javascript
727/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
728/// 
729/// const port = new SerialPort({ path: "COM1" });
730/// await port.open();
731/// await port.startListening();
732/// const unsubscribe = await port.listen((data) => {
733///   console.log("Received:", data);
734/// });
735/// ```
736#[tauri::command]
737pub fn start_listening<R: Runtime>(
738    _app: AppHandle<R>,
739    serial: State<'_, SerialPort<R>>,
740    path: String,
741    timeout: Option<u64>,
742    size: Option<usize>,
743) -> Result<(), Error> {
744    serial.start_listening(path, timeout, size)
745}
746
747/// Stops listening for data on a serial port
748/// 
749/// Stops the continuous monitoring of the serial port and terminates
750/// the background thread that was reading data.
751/// 
752/// # Arguments
753/// 
754/// * `_app` - The Tauri app handle
755/// * `serial` - The serial port state
756/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
757/// 
758/// # Returns
759/// 
760/// `Ok(())` if listening stopped successfully, or an `Error` if it failed.
761/// 
762/// # Example
763/// 
764/// ```rust
765/// use tauri_plugin_serialplugin::commands::stop_listening;
766/// use tauri::{AppHandle, State};
767/// 
768/// #[tauri::command]
769/// async fn end_monitoring(
770///     app: AppHandle<tauri::Wry>,
771///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
772/// ) -> Result<(), String> {
773///     stop_listening(app, serial, "COM1".to_string()).map_err(|e| e.to_string())
774/// }
775/// ```
776/// 
777/// # JavaScript Equivalent
778/// 
779/// ```javascript
780/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
781/// 
782/// const port = new SerialPort({ path: "COM1" });
783/// await port.stopListening();
784/// ```
785#[tauri::command]
786pub fn stop_listening<R: Runtime>(
787    _app: AppHandle<R>,
788    serial: State<'_, SerialPort<R>>,
789    path: String,
790) -> Result<(), Error> {
791    serial.stop_listening(path)
792}
793
794/// Sets the baud rate for a serial port
795/// 
796/// Changes the communication speed of the serial port. Common baud rates
797/// include 9600, 19200, 38400, 57600, and 115200.
798/// 
799/// # Arguments
800/// 
801/// * `_app` - The Tauri app handle
802/// * `serial` - The serial port state
803/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
804/// * `baud_rate` - The new baud rate (e.g., 9600, 115200)
805/// 
806/// # Returns
807/// 
808/// `Ok(())` if the baud rate was set successfully, or an `Error` if it failed.
809/// 
810/// # Example
811/// 
812/// ```rust
813/// use tauri_plugin_serialplugin::commands::set_baud_rate;
814/// use tauri::{AppHandle, State};
815/// 
816/// #[tauri::command]
817/// async fn change_speed(
818///     app: AppHandle<tauri::Wry>,
819///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
820/// ) -> Result<(), String> {
821///     set_baud_rate(app, serial, "COM1".to_string(), 115200)
822///         .map_err(|e| e.to_string())
823/// }
824/// ```
825/// 
826/// # JavaScript Equivalent
827/// 
828/// ```javascript
829/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
830/// 
831/// const port = new SerialPort({ path: "COM1" });
832/// await port.open();
833/// await port.setBaudRate(115200);
834/// ```
835#[tauri::command]
836pub fn set_baud_rate<R: Runtime>(
837    _app: AppHandle<R>,
838    serial: State<'_, SerialPort<R>>,
839    path: String,
840    baud_rate: u32,
841) -> Result<(), Error> {
842    serial.set_baud_rate(path, baud_rate)
843}
844
845/// Sets the number of data bits for a serial port
846/// 
847/// Changes the number of data bits per character. Most modern applications
848/// use 8 data bits, but some legacy systems may use 7 bits.
849/// 
850/// # Arguments
851/// 
852/// * `_app` - The Tauri app handle
853/// * `serial` - The serial port state
854/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
855/// * `data_bits` - The number of data bits (Five, Six, Seven, or Eight)
856/// 
857/// # Returns
858/// 
859/// `Ok(())` if the data bits were set successfully, or an `Error` if it failed.
860/// 
861/// # Example
862/// 
863/// ```rust
864/// use tauri_plugin_serialplugin::commands::set_data_bits;
865/// use tauri_plugin_serialplugin::state::DataBits;
866/// use tauri::{AppHandle, State};
867/// 
868/// #[tauri::command]
869/// async fn configure_data_bits(
870///     app: AppHandle<tauri::Wry>,
871///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
872/// ) -> Result<(), String> {
873///     set_data_bits(app, serial, "COM1".to_string(), DataBits::Eight)
874///         .map_err(|e| e.to_string())
875/// }
876/// ```
877/// 
878/// # JavaScript Equivalent
879/// 
880/// ```javascript
881/// import { SerialPort, DataBits } from "tauri-plugin-serialplugin-api";;
882/// 
883/// const port = new SerialPort({ path: "COM1" });
884/// await port.open();
885/// await port.setDataBits(DataBits.Eight);
886/// ```
887#[tauri::command]
888pub fn set_data_bits<R: Runtime>(
889    _app: AppHandle<R>,
890    serial: State<'_, SerialPort<R>>,
891    path: String,
892    data_bits: DataBits,
893) -> Result<(), Error> {
894    serial.set_data_bits(path, data_bits)
895}
896
897/// Sets the flow control mode for a serial port
898/// 
899/// Changes the flow control method used by the serial port. Flow control
900/// prevents data loss by allowing the receiver to signal when it's ready
901/// to receive more data.
902/// 
903/// # Arguments
904/// 
905/// * `_app` - The Tauri app handle
906/// * `serial` - The serial port state
907/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
908/// * `flow_control` - The flow control mode (None, Software, or Hardware)
909/// 
910/// # Returns
911/// 
912/// `Ok(())` if the flow control was set successfully, or an `Error` if it failed.
913/// 
914/// # Example
915/// 
916/// ```rust
917/// use tauri_plugin_serialplugin::commands::set_flow_control;
918/// use tauri_plugin_serialplugin::state::FlowControl;
919/// use tauri::{AppHandle, State};
920/// 
921/// #[tauri::command]
922/// async fn configure_flow_control(
923///     app: AppHandle<tauri::Wry>,
924///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
925/// ) -> Result<(), String> {
926///     set_flow_control(app, serial, "COM1".to_string(), FlowControl::None)
927///         .map_err(|e| e.to_string())
928/// }
929/// ```
930/// 
931/// # JavaScript Equivalent
932/// 
933/// ```javascript
934/// import { SerialPort, FlowControl } from "tauri-plugin-serialplugin-api";;
935/// 
936/// const port = new SerialPort({ path: "COM1" });
937/// await port.open();
938/// await port.setFlowControl(FlowControl.None);
939/// ```
940#[tauri::command]
941pub fn set_flow_control<R: Runtime>(
942    _app: AppHandle<R>,
943    serial: State<'_, SerialPort<R>>,
944    path: String,
945    flow_control: FlowControl,
946) -> Result<(), Error> {
947    serial.set_flow_control(path, flow_control)
948}
949
950/// Sets the parity checking mode for a serial port
951/// 
952/// Changes the parity checking method used by the serial port. Parity is
953/// an error detection method that adds an extra bit to each character.
954/// 
955/// # Arguments
956/// 
957/// * `_app` - The Tauri app handle
958/// * `serial` - The serial port state
959/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
960/// * `parity` - The parity mode (None, Odd, or Even)
961/// 
962/// # Returns
963/// 
964/// `Ok(())` if the parity was set successfully, or an `Error` if it failed.
965/// 
966/// # Example
967/// 
968/// ```rust
969/// use tauri_plugin_serialplugin::commands::set_parity;
970/// use tauri_plugin_serialplugin::state::Parity;
971/// use tauri::{AppHandle, State};
972/// 
973/// #[tauri::command]
974/// async fn configure_parity(
975///     app: AppHandle<tauri::Wry>,
976///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
977/// ) -> Result<(), String> {
978///     set_parity(app, serial, "COM1".to_string(), Parity::None)
979///         .map_err(|e| e.to_string())
980/// }
981/// ```
982/// 
983/// # JavaScript Equivalent
984/// 
985/// ```javascript
986/// import { SerialPort, Parity } from "tauri-plugin-serialplugin-api";;
987/// 
988/// const port = new SerialPort({ path: "COM1" });
989/// await port.open();
990/// await port.setParity(Parity.None);
991/// ```
992#[tauri::command]
993pub fn set_parity<R: Runtime>(
994    _app: AppHandle<R>,
995    serial: State<'_, SerialPort<R>>,
996    path: String,
997    parity: Parity,
998) -> Result<(), Error> {
999    serial.set_parity(path, parity)
1000}
1001
1002/// Sets the number of stop bits for a serial port
1003/// 
1004/// Changes the number of stop bits used by the serial port. Stop bits
1005/// signal the end of a character transmission.
1006/// 
1007/// # Arguments
1008/// 
1009/// * `_app` - The Tauri app handle
1010/// * `serial` - The serial port state
1011/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1012/// * `stop_bits` - The number of stop bits (One or Two)
1013/// 
1014/// # Returns
1015/// 
1016/// `Ok(())` if the stop bits were set successfully, or an `Error` if it failed.
1017/// 
1018/// # Example
1019/// 
1020/// ```rust
1021/// use tauri_plugin_serialplugin::commands::set_stop_bits;
1022/// use tauri_plugin_serialplugin::state::StopBits;
1023/// use tauri::{AppHandle, State};
1024/// 
1025/// #[tauri::command]
1026/// async fn configure_stop_bits(
1027///     app: AppHandle<tauri::Wry>,
1028///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1029/// ) -> Result<(), String> {
1030///     set_stop_bits(app, serial, "COM1".to_string(), StopBits::One)
1031///         .map_err(|e| e.to_string())
1032/// }
1033/// ```
1034/// 
1035/// # JavaScript Equivalent
1036/// 
1037/// ```javascript
1038/// import { SerialPort, StopBits } from "tauri-plugin-serialplugin-api";;
1039/// 
1040/// const port = new SerialPort({ path: "COM1" });
1041/// await port.open();
1042/// await port.setStopBits(StopBits.One);
1043/// ```
1044#[tauri::command]
1045pub fn set_stop_bits<R: Runtime>(
1046    _app: AppHandle<R>,
1047    serial: State<'_, SerialPort<R>>,
1048    path: String,
1049    stop_bits: StopBits,
1050) -> Result<(), Error> {
1051    serial.set_stop_bits(path, stop_bits)
1052}
1053
1054/// Sets the read timeout for a serial port
1055/// 
1056/// Changes the timeout duration for read operations. If no data is received
1057/// within this timeout, the read operation will fail.
1058/// 
1059/// # Arguments
1060/// 
1061/// * `_app` - The Tauri app handle
1062/// * `serial` - The serial port state
1063/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1064/// * `timeout` - The timeout duration in milliseconds
1065/// 
1066/// # Returns
1067/// 
1068/// `Ok(())` if the timeout was set successfully, or an `Error` if it failed.
1069/// 
1070/// # Example
1071/// 
1072/// ```rust
1073/// use tauri_plugin_serialplugin::commands::set_timeout;
1074/// use tauri::{AppHandle, State};
1075/// 
1076/// #[tauri::command]
1077/// async fn configure_timeout(
1078///     app: AppHandle<tauri::Wry>,
1079///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1080/// ) -> Result<(), String> {
1081///     set_timeout(app, serial, "COM1".to_string(), 5000) // 5 seconds
1082///         .map_err(|e| e.to_string())
1083/// }
1084/// ```
1085/// 
1086/// # JavaScript Equivalent
1087/// 
1088/// ```javascript
1089/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1090/// 
1091/// const port = new SerialPort({ path: "COM1" });
1092/// await port.open();
1093/// await port.setTimeout(5000); // 5 seconds
1094/// ```
1095#[tauri::command]
1096pub fn set_timeout<R: Runtime>(
1097    _app: AppHandle<R>,
1098    serial: State<'_, SerialPort<R>>,
1099    path: String,
1100    timeout: u64,
1101) -> Result<(), Error> {
1102    let timeout_duration = Duration::from_millis(timeout);
1103    serial.set_timeout(path, timeout_duration)
1104}
1105
1106/// Sets the RTS (Request To Send) control signal
1107/// 
1108/// Controls the RTS signal line on the serial port. This signal is used
1109/// for hardware flow control to indicate readiness to send data.
1110/// 
1111/// # Arguments
1112/// 
1113/// * `_app` - The Tauri app handle
1114/// * `serial` - The serial port state
1115/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1116/// * `level` - The signal level (true for high, false for low)
1117/// 
1118/// # Returns
1119/// 
1120/// `Ok(())` if the RTS signal was set successfully, or an `Error` if it failed.
1121/// 
1122/// # Example
1123/// 
1124/// ```rust
1125/// use tauri_plugin_serialplugin::commands::write_request_to_send;
1126/// use tauri::{AppHandle, State};
1127/// 
1128/// #[tauri::command]
1129/// async fn control_rts(
1130///     app: AppHandle<tauri::Wry>,
1131///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1132/// ) -> Result<(), String> {
1133///     write_request_to_send(app, serial, "COM1".to_string(), true)
1134///         .map_err(|e| e.to_string())
1135/// }
1136/// ```
1137/// 
1138/// # JavaScript Equivalent
1139/// 
1140/// ```javascript
1141/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1142/// 
1143/// const port = new SerialPort({ path: "COM1" });
1144/// await port.open();
1145/// await port.writeRequestToSend(true);
1146/// ```
1147#[tauri::command]
1148pub fn write_request_to_send<R: Runtime>(
1149    _app: AppHandle<R>,
1150    serial: State<'_, SerialPort<R>>,
1151    path: String,
1152    level: bool,
1153) -> Result<(), Error> {
1154    serial.write_request_to_send(path, level)
1155}
1156
1157/// Sets the DTR (Data Terminal Ready) control signal
1158/// 
1159/// Controls the DTR signal line on the serial port. This signal indicates
1160/// that the terminal (computer) is ready for communication.
1161/// 
1162/// # Arguments
1163/// 
1164/// * `_app` - The Tauri app handle
1165/// * `serial` - The serial port state
1166/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1167/// * `level` - The signal level (true for high, false for low)
1168/// 
1169/// # Returns
1170/// 
1171/// `Ok(())` if the DTR signal was set successfully, or an `Error` if it failed.
1172/// 
1173/// # Example
1174/// 
1175/// ```rust
1176/// use tauri_plugin_serialplugin::commands::write_data_terminal_ready;
1177/// use tauri::{AppHandle, State};
1178/// 
1179/// #[tauri::command]
1180/// async fn control_dtr(
1181///     app: AppHandle<tauri::Wry>,
1182///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1183/// ) -> Result<(), String> {
1184///     write_data_terminal_ready(app, serial, "COM1".to_string(), true)
1185///         .map_err(|e| e.to_string())
1186/// }
1187/// ```
1188/// 
1189/// # JavaScript Equivalent
1190/// 
1191/// ```javascript
1192/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1193/// 
1194/// const port = new SerialPort({ path: "COM1" });
1195/// await port.open();
1196/// await port.writeDataTerminalReady(true);
1197/// ```
1198#[tauri::command]
1199pub fn write_data_terminal_ready<R: Runtime>(
1200    _app: AppHandle<R>,
1201    serial: State<'_, SerialPort<R>>,
1202    path: String,
1203    level: bool,
1204) -> Result<(), Error> {
1205    serial.write_data_terminal_ready(path, level)
1206}
1207
1208/// Reads the CTS (Clear To Send) control signal state
1209/// 
1210/// Reads the current state of the CTS signal line. This signal indicates
1211/// whether the remote device is ready to receive data.
1212/// 
1213/// # Arguments
1214/// 
1215/// * `_app` - The Tauri app handle
1216/// * `serial` - The serial port state
1217/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1218/// 
1219/// # Returns
1220/// 
1221/// The CTS signal state (true for high, false for low), or an `Error` if it failed.
1222/// 
1223/// # Example
1224/// 
1225/// ```rust
1226/// use tauri_plugin_serialplugin::commands::read_clear_to_send;
1227/// use tauri::{AppHandle, State};
1228/// 
1229/// #[tauri::command]
1230/// async fn check_cts(
1231///     app: AppHandle<tauri::Wry>,
1232///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1233/// ) -> Result<(), String> {
1234///     let cts_state = read_clear_to_send(app, serial, "COM1".to_string())
1235///         .map_err(|e| e.to_string())?;
1236///     println!("CTS signal is: {}", if cts_state { "high" } else { "low" });
1237///     Ok(())
1238/// }
1239/// ```
1240/// 
1241/// # JavaScript Equivalent
1242/// 
1243/// ```javascript
1244/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1245/// 
1246/// const port = new SerialPort({ path: "COM1" });
1247/// await port.open();
1248/// const ctsState = await port.readClearToSend();
1249/// console.log("CTS signal is:", ctsState ? "high" : "low");
1250/// ```
1251#[tauri::command]
1252pub fn read_clear_to_send<R: Runtime>(
1253    _app: AppHandle<R>,
1254    serial: State<'_, SerialPort<R>>,
1255    path: String,
1256) -> Result<bool, Error> {
1257    serial.read_clear_to_send(path)
1258}
1259
1260/// Reads the DSR (Data Set Ready) control signal state
1261/// 
1262/// Reads the current state of the DSR signal line. This signal indicates
1263/// whether the remote device (modem) is ready for communication.
1264/// 
1265/// # Arguments
1266/// 
1267/// * `_app` - The Tauri app handle
1268/// * `serial` - The serial port state
1269/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1270/// 
1271/// # Returns
1272/// 
1273/// The DSR signal state (true for high, false for low), or an `Error` if it failed.
1274/// 
1275/// # Example
1276/// 
1277/// ```rust
1278/// use tauri_plugin_serialplugin::commands::read_data_set_ready;
1279/// use tauri::{AppHandle, State};
1280/// 
1281/// #[tauri::command]
1282/// async fn check_dsr(
1283///     app: AppHandle<tauri::Wry>,
1284///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1285/// ) -> Result<(), String> {
1286///     let dsr_state = read_data_set_ready(app, serial, "COM1".to_string())
1287///         .map_err(|e| e.to_string())?;
1288///     println!("DSR signal is: {}", if dsr_state { "high" } else { "low" });
1289///     Ok(())
1290/// }
1291/// ```
1292/// 
1293/// # JavaScript Equivalent
1294/// 
1295/// ```javascript
1296/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1297/// 
1298/// const port = new SerialPort({ path: "COM1" });
1299/// await port.open();
1300/// const dsrState = await port.readDataSetReady();
1301/// console.log("DSR signal is:", dsrState ? "high" : "low");
1302/// ```
1303#[tauri::command]
1304pub fn read_data_set_ready<R: Runtime>(
1305    _app: AppHandle<R>,
1306    serial: State<'_, SerialPort<R>>,
1307    path: String,
1308) -> Result<bool, Error> {
1309    serial.read_data_set_ready(path)
1310}
1311
1312/// Reads the RI (Ring Indicator) control signal state
1313/// 
1314/// Reads the current state of the RI signal line. This signal indicates
1315/// that an incoming call is being received (commonly used with modems).
1316/// 
1317/// # Arguments
1318/// 
1319/// * `_app` - The Tauri app handle
1320/// * `serial` - The serial port state
1321/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1322/// 
1323/// # Returns
1324/// 
1325/// The RI signal state (true for high, false for low), or an `Error` if it failed.
1326/// 
1327/// # Example
1328/// 
1329/// ```rust
1330/// use tauri_plugin_serialplugin::commands::read_ring_indicator;
1331/// use tauri::{AppHandle, State};
1332/// 
1333/// #[tauri::command]
1334/// async fn check_ring(
1335///     app: AppHandle<tauri::Wry>,
1336///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1337/// ) -> Result<(), String> {
1338///     let ri_state = read_ring_indicator(app, serial, "COM1".to_string())
1339///         .map_err(|e| e.to_string())?;
1340///     println!("Ring indicator is: {}", if ri_state { "active" } else { "inactive" });
1341///     Ok(())
1342/// }
1343/// ```
1344/// 
1345/// # JavaScript Equivalent
1346/// 
1347/// ```javascript
1348/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1349/// 
1350/// const port = new SerialPort({ path: "COM1" });
1351/// await port.open();
1352/// const riState = await port.readRingIndicator();
1353/// console.log("Ring indicator is:", riState ? "active" : "inactive");
1354/// ```
1355#[tauri::command]
1356pub fn read_ring_indicator<R: Runtime>(
1357    _app: AppHandle<R>,
1358    serial: State<'_, SerialPort<R>>,
1359    path: String,
1360) -> Result<bool, Error> {
1361    serial.read_ring_indicator(path)
1362}
1363
1364/// Reads the CD (Carrier Detect) control signal state
1365/// 
1366/// Reads the current state of the CD signal line. This signal indicates
1367/// whether a carrier signal is being received (commonly used with modems).
1368/// 
1369/// # Arguments
1370/// 
1371/// * `_app` - The Tauri app handle
1372/// * `serial` - The serial port state
1373/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1374/// 
1375/// # Returns
1376/// 
1377/// The CD signal state (true for high, false for low), or an `Error` if it failed.
1378/// 
1379/// # Example
1380/// 
1381/// ```rust
1382/// use tauri_plugin_serialplugin::commands::read_carrier_detect;
1383/// use tauri::{AppHandle, State};
1384/// 
1385/// #[tauri::command]
1386/// async fn check_carrier(
1387///     app: AppHandle<tauri::Wry>,
1388///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1389/// ) -> Result<(), String> {
1390///     let cd_state = read_carrier_detect(app, serial, "COM1".to_string())
1391///         .map_err(|e| e.to_string())?;
1392///     println!("Carrier detect is: {}", if cd_state { "active" } else { "inactive" });
1393///     Ok(())
1394/// }
1395/// ```
1396/// 
1397/// # JavaScript Equivalent
1398/// 
1399/// ```javascript
1400/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1401/// 
1402/// const port = new SerialPort({ path: "COM1" });
1403/// await port.open();
1404/// const cdState = await port.readCarrierDetect();
1405/// console.log("Carrier detect is:", cdState ? "active" : "inactive");
1406/// ```
1407#[tauri::command]
1408pub fn read_carrier_detect<R: Runtime>(
1409    _app: AppHandle<R>,
1410    serial: State<'_, SerialPort<R>>,
1411    path: String,
1412) -> Result<bool, Error> {
1413    serial.read_carrier_detect(path)
1414}
1415
1416/// Gets the number of bytes available to read from the serial port
1417/// 
1418/// Returns the number of bytes that are currently available in the
1419/// input buffer and ready to be read.
1420/// 
1421/// # Arguments
1422/// 
1423/// * `_app` - The Tauri app handle
1424/// * `serial` - The serial port state
1425/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1426/// 
1427/// # Returns
1428/// 
1429/// The number of bytes available to read, or an `Error` if it failed.
1430/// 
1431/// # Example
1432/// 
1433/// ```rust
1434/// use tauri_plugin_serialplugin::commands::bytes_to_read;
1435/// use tauri::{AppHandle, State};
1436/// 
1437/// #[tauri::command]
1438/// async fn check_available_data(
1439///     app: AppHandle<tauri::Wry>,
1440///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1441/// ) -> Result<(), String> {
1442///     let available = bytes_to_read(app, serial, "COM1".to_string())
1443///         .map_err(|e| e.to_string())?;
1444///     println!("{} bytes available to read", available);
1445///     Ok(())
1446/// }
1447/// ```
1448/// 
1449/// # JavaScript Equivalent
1450/// 
1451/// ```javascript
1452/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1453/// 
1454/// const port = new SerialPort({ path: "COM1" });
1455/// await port.open();
1456/// const available = await port.bytesToRead();
1457/// console.log(`${available} bytes available to read`);
1458/// ```
1459#[tauri::command]
1460pub fn bytes_to_read<R: Runtime>(
1461    _app: AppHandle<R>,
1462    serial: State<'_, SerialPort<R>>,
1463    path: String,
1464) -> Result<u32, Error> {
1465    serial.bytes_to_read(path)
1466}
1467
1468/// Gets the number of bytes available to write to the serial port
1469/// 
1470/// Returns the number of bytes that can be written to the output
1471/// buffer without blocking.
1472/// 
1473/// # Arguments
1474/// 
1475/// * `_app` - The Tauri app handle
1476/// * `serial` - The serial port state
1477/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1478/// 
1479/// # Returns
1480/// 
1481/// The number of bytes available to write, or an `Error` if it failed.
1482/// 
1483/// # Example
1484/// 
1485/// ```rust
1486/// use tauri_plugin_serialplugin::commands::bytes_to_write;
1487/// use tauri::{AppHandle, State};
1488/// 
1489/// #[tauri::command]
1490/// async fn check_write_buffer(
1491///     app: AppHandle<tauri::Wry>,
1492///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1493/// ) -> Result<(), String> {
1494///     let available = bytes_to_write(app, serial, "COM1".to_string())
1495///         .map_err(|e| e.to_string())?;
1496///     println!("{} bytes available to write", available);
1497///     Ok(())
1498/// }
1499/// ```
1500/// 
1501/// # JavaScript Equivalent
1502/// 
1503/// ```javascript
1504/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1505/// 
1506/// const port = new SerialPort({ path: "COM1" });
1507/// await port.open();
1508/// const available = await port.bytesToWrite();
1509/// console.log(`${available} bytes available to write`);
1510/// ```
1511#[tauri::command]
1512pub fn bytes_to_write<R: Runtime>(
1513    _app: AppHandle<R>,
1514    serial: State<'_, SerialPort<R>>,
1515    path: String,
1516) -> Result<u32, Error> {
1517    serial.bytes_to_write(path)
1518}
1519
1520/// Clears the specified buffer of the serial port
1521/// 
1522/// Clears either the input buffer, output buffer, or both buffers
1523/// of the serial port. This is useful for removing stale data.
1524/// 
1525/// # Arguments
1526/// 
1527/// * `_app` - The Tauri app handle
1528/// * `serial` - The serial port state
1529/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1530/// * `buffer_type` - The type of buffer to clear (Input, Output, or Both)
1531/// 
1532/// # Returns
1533/// 
1534/// `Ok(())` if the buffer was cleared successfully, or an `Error` if it failed.
1535/// 
1536/// # Example
1537/// 
1538/// ```rust
1539/// use tauri_plugin_serialplugin::commands::clear_buffer;
1540/// use tauri_plugin_serialplugin::state::ClearBuffer;
1541/// use tauri::{AppHandle, State};
1542/// 
1543/// #[tauri::command]
1544/// async fn clear_input_buffer(
1545///     app: AppHandle<tauri::Wry>,
1546///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1547/// ) -> Result<(), String> {
1548///     clear_buffer(app, serial, "COM1".to_string(), ClearBuffer::Input)
1549///         .map_err(|e| e.to_string())
1550/// }
1551/// ```
1552/// 
1553/// # JavaScript Equivalent
1554/// 
1555/// ```javascript
1556/// import { SerialPort, ClearBuffer } from "tauri-plugin-serialplugin-api";;
1557/// 
1558/// const port = new SerialPort({ path: "COM1" });
1559/// await port.open();
1560/// await port.clearBuffer(ClearBuffer.Input);
1561/// ```
1562#[tauri::command]
1563pub fn clear_buffer<R: Runtime>(
1564    _app: AppHandle<R>,
1565    serial: State<'_, SerialPort<R>>,
1566    path: String,
1567    buffer_type: ClearBuffer,
1568) -> Result<(), Error> {
1569    serial.clear_buffer(path, buffer_type)
1570}
1571
1572/// Sets the break condition on the serial port
1573/// 
1574/// Activates the break condition, which holds the transmit line low
1575/// for a period longer than a character time. This is often used
1576/// to signal special conditions or reset devices.
1577/// 
1578/// # Arguments
1579/// 
1580/// * `_app` - The Tauri app handle
1581/// * `serial` - The serial port state
1582/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1583/// 
1584/// # Returns
1585/// 
1586/// `Ok(())` if the break condition was set successfully, or an `Error` if it failed.
1587/// 
1588/// # Example
1589/// 
1590/// ```rust
1591/// use tauri_plugin_serialplugin::commands::set_break;
1592/// use tauri::{AppHandle, State};
1593/// 
1594/// #[tauri::command]
1595/// async fn activate_break(
1596///     app: AppHandle<tauri::Wry>,
1597///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1598/// ) -> Result<(), String> {
1599///     set_break(app, serial, "COM1".to_string())
1600///         .map_err(|e| e.to_string())
1601/// }
1602/// ```
1603/// 
1604/// # JavaScript Equivalent
1605/// 
1606/// ```javascript
1607/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1608/// 
1609/// const port = new SerialPort({ path: "COM1" });
1610/// await port.open();
1611/// await port.setBreak();
1612/// ```
1613#[tauri::command]
1614pub fn set_break<R: Runtime>(
1615    _app: AppHandle<R>,
1616    serial: State<'_, SerialPort<R>>,
1617    path: String,
1618) -> Result<(), Error> {
1619    serial.set_break(path)
1620}
1621
1622/// Clears the break condition on the serial port
1623/// 
1624/// Deactivates the break condition, returning the transmit line
1625/// to normal operation.
1626/// 
1627/// # Arguments
1628/// 
1629/// * `_app` - The Tauri app handle
1630/// * `serial` - The serial port state
1631/// * `path` - The path to the serial port (e.g., "COM1", "/dev/ttyUSB0")
1632/// 
1633/// # Returns
1634/// 
1635/// `Ok(())` if the break condition was cleared successfully, or an `Error` if it failed.
1636/// 
1637/// # Example
1638/// 
1639/// ```rust
1640/// use tauri_plugin_serialplugin::commands::clear_break;
1641/// use tauri::{AppHandle, State};
1642/// 
1643/// #[tauri::command]
1644/// async fn deactivate_break(
1645///     app: AppHandle<tauri::Wry>,
1646///     serial: State<'_, tauri_plugin_serialplugin::desktop_api::SerialPort<tauri::Wry>>
1647/// ) -> Result<(), String> {
1648///     clear_break(app, serial, "COM1".to_string())
1649///         .map_err(|e| e.to_string())
1650/// }
1651/// ```
1652/// 
1653/// # JavaScript Equivalent
1654/// 
1655/// ```javascript
1656/// import { SerialPort } from "tauri-plugin-serialplugin-api";;
1657/// 
1658/// const port = new SerialPort({ path: "COM1" });
1659/// await port.open();
1660/// await port.clearBreak();
1661/// ```
1662#[tauri::command]
1663pub fn clear_break<R: Runtime>(
1664    _app: AppHandle<R>,
1665    serial: State<'_, SerialPort<R>>,
1666    path: String,
1667) -> Result<(), Error> {
1668    serial.clear_break(path)
1669}