typechar 1.1.0

Type any Unicode string on macOS, regardless of keyboard layout
Documentation
#[cfg(not(target_os = "macos"))]
compile_error!("typechar only works on macOS — it types characters via CoreGraphics events");

use std::thread::sleep;
use std::time::Duration;

use typechar::{Action, TypeError, parse_args, request_permission, type_string};

const USAGE: &str = "\
typechar — type any Unicode string, regardless of keyboard layout

Usage:
  typechar [OPTIONS] <string>
  typechar [OPTIONS] --unicode <hex> [--unicode <hex>...]

Options:
  -u, --unicode <hex>  Codepoint to type, e.g. 20ac or U+20AC (repeatable)
  -d, --delay <ms>     Wait before typing (for apps that drop fast events)
  -h, --help           Show this help
  -V, --version        Show version

Examples:
  typechar €
  typechar --unicode 20ac
  typechar --delay 100 '¯\\_(ツ)_/¯'";

fn main() {
    let args: Vec<String> = std::env::args().skip(1).collect();
    match parse_args(&args) {
        Ok(Action::Help) => println!("{USAGE}"),
        Ok(Action::Version) => println!("typechar {}", env!("CARGO_PKG_VERSION")),
        Ok(Action::Type { text, delay_ms }) => {
            if delay_ms > 0 {
                sleep(Duration::from_millis(delay_ms));
            }
            if let Err(err) = type_string(&text) {
                if err == TypeError::PermissionDenied {
                    request_permission();
                    eprintln!(
                        "typechar: {err}.\n\
                         Grant Accessibility access to the app that runs typechar (your \
                         terminal, Karabiner, skhd, ...) in System Settings → Privacy & \
                         Security → Accessibility, then try again."
                    );
                } else {
                    eprintln!("typechar: {err}");
                }
                std::process::exit(1);
            }
        }
        Err(msg) => {
            eprintln!("typechar: {msg}\n\n{USAGE}");
            std::process::exit(2);
        }
    }
}