brlapi 0.4.1

Safe Rust bindings for the BrlAPI library
// SPDX-License-Identifier: LGPL-2.1

//! Error handling example for BrlAPI
//!
//! This example demonstrates how to handle various BrlAPI errors gracefully
//! and provide helpful feedback to users.

use brlapi::{BrlApiError, Connection, TtyMode};

fn main() {
    println!("BrlAPI Error Handling Example");
    println!("============================");

    // Demonstrate connection error handling
    match Connection::open() {
        Ok(connection) => {
            println!("Connected to BrlAPI successfully!");

            // Try to get display info
            match connection.display_size() {
                Ok((width, height)) => {
                    println!("Display size: {width}x{height} cells");

                    // Demonstrate TTY mode error handling
                    demonstrate_tty_errors(&connection);
                }
                Err(e) => {
                    handle_error("getting display information", &e);
                }
            }
        }
        Err(e) => {
            handle_error("connecting to BrlAPI", &e);
        }
    }
}

fn demonstrate_tty_errors(connection: &Connection) {
    println!("\nTesting TTY mode operations...");

    // First, try the automatic TTY detection (recommended approach)
    match TtyMode::enter_auto(&connection, None) {
        Ok((tty_mode, tty_num)) => {
            println!("TTY mode entered automatically (TTY {tty_num})");

            // Try to write text using TtyMode convenience method
            match tty_mode.write_text("Hello from error handling example!") {
                Ok(()) => println!("Text written successfully"),
                Err(e) => handle_error("writing text", &e),
            }

            // TTY mode automatically cleaned up when tty_mode drops
            println!("TTY mode exited successfully");
        }
        Err(e) => {
            handle_error("entering TTY mode", &e);

            // If auto-detection fails, show specific TTY error handling
            demonstrate_specific_tty_errors(connection);
        }
    }
}

fn demonstrate_specific_tty_errors(connection: &Connection) {
    println!("\nTrying specific TTY numbers...");

    for tty_num in 1..=6 {
        match TtyMode::with_tty(connection, Some(tty_num), None) {
            Ok(_tty_mode) => {
                println!("Successfully entered TTY mode on TTY {tty_num})");
                // TTY mode automatically cleaned up when _tty_mode drops
                break;
            }
            Err(e) => {
                println!("TTY {tty_num} failed: {e}");
                if tty_num == 6 {
                    handle_error("entering any TTY mode", &e);
                }
            }
        }
    }
}

fn handle_error(operation: &str, error: &BrlApiError) {
    println!("\nError {operation}: {error}");

    // The error message is already user-friendly via thiserror

    // Show suggestions if available
    let suggestions = error.suggestions();
    if !suggestions.is_empty() {
        println!("Suggestions:");
        for (i, suggestion) in suggestions.iter().enumerate() {
            println!("   {}. {suggestion}", i + 1);
        }
    }

    // Show error category
    if error.is_connection_error() {
        println!("This is a connection-related error");
    } else if error.is_resource_busy() {
        println!("This is a resource availability error");
    } else if error.is_operation_error() {
        println!("This is an operation or parameter error");
    }

    println!(); // Add spacing
}