(** Example demonstrating keyeio library usage *) open Cmdliner (** Example 1: Basic usage with single service *) let basic_example (_xdg, _xdg_cmd) profile = Fmt.pr "=== Basic Example ===@."; Fmt.pr "Service: %s@." (Keyeio.Profile.service profile); Fmt.pr "Profile: %s@." (Keyeio.Profile.name profile); (* Get required API key *) let api_key = Keyeio.Profile.get_required profile ~key:"api_key" in Fmt.pr "API Key loaded: %s@." (String.sub api_key 0 (min 10 (String.length api_key)) ^ "..."); (* Get optional base URL *) (match Keyeio.Profile.get profile ~key:"base_url" with | Some url -> Fmt.pr "Base URL: %s@." url | None -> Fmt.pr "No base URL configured@."); (* List all available keys *) let keys = Keyeio.Profile.keys profile in Fmt.pr "Available keys: %a@." Fmt.(list ~sep:comma string) keys; (* Pretty print the profile *) Fmt.pr "@.Profile details:@.%a@." Keyeio.Profile.pp profile; 0 (** Example 2: List all services *) let list_services_example (xdg, _xdg_cmd) = Fmt.pr "=== List Services Example ===@."; let keyeio = Keyeio.create xdg in match Keyeio.list_services keyeio with | Ok services -> if services = [] then Fmt.pr "No services configured yet@." else begin Fmt.pr "Available services:@."; List.iter (fun svc -> Fmt.pr " - %s@." svc) services end; 0 | Error (`Msg msg) -> Fmt.epr "Error listing services: %s@." msg; 1 (** Example 3: Load service and list profiles *) let list_profiles_example (xdg, _xdg_cmd) service_name = Fmt.pr "=== List Profiles Example ===@."; let keyeio = Keyeio.create xdg in match Keyeio.load_service keyeio ~service:service_name with | Ok service -> Fmt.pr "Service: %s@." (Keyeio.Service.name service); let profiles = Keyeio.Service.profile_names service in Fmt.pr "Available profiles:@."; List.iter (fun name -> Fmt.pr " - %s" name; match Keyeio.Service.get_profile service name with | Some prof -> let keys = Keyeio.Profile.keys prof in Fmt.pr " (keys: %a)" Fmt.(list ~sep:comma string) keys | None -> () ) profiles; Fmt.pr "@."; (* Pretty print the service *) Fmt.pr "@.Service details:@.%a@." Keyeio.Service.pp service; 0 | Error (`Msg msg) -> Fmt.epr "Error loading service '%s': %s@." service_name msg; 1 (** Example 4: Simulated API client using loaded credentials *) let api_client_example (_xdg, _xdg_cmd) profile = Fmt.pr "=== API Client Example ===@."; (* Simulate creating an API client with loaded credentials *) let api_key = Keyeio.Profile.get_required profile ~key:"api_key" in let base_url = Keyeio.Profile.get profile ~key:"base_url" |> Option.value ~default:"https://api.example.com" in Fmt.pr "Creating API client for %s@." (Keyeio.Profile.service profile); Fmt.pr " Base URL: %s@." base_url; Fmt.pr " Profile: %s@." (Keyeio.Profile.name profile); Fmt.pr " Authenticated: yes@."; (* Simulate making an API call *) Fmt.pr "@.Simulating API request...@."; Fmt.pr "GET %s/api/status@." base_url; Fmt.pr "Authorization: Bearer %s@." (String.sub api_key 0 (min 8 (String.length api_key)) ^ "..."); Fmt.pr "@.Response: 200 OK@."; 0 (** Main command dispatcher *) let () = Eio_main.run @@ fun env -> (* Common terms *) let xdg_term = Xdge.Cmd.term "keyeio-example" env#fs () in (* Command: basic - Basic usage example *) let basic_cmd = let profile_term = Keyeio.Cmd.term ~app_name:"keyeio-example" ~fs:env#fs ~service:"immiche" () in let info = Cmd.info "basic" ~doc:"Basic keyeio usage example" in Cmd.v info Term.(const basic_example $ xdg_term $ profile_term) in (* Command: list - List all services *) let list_cmd = let info = Cmd.info "list" ~doc:"List all configured services" in Cmd.v info Term.(const list_services_example $ xdg_term) in (* Command: profiles - List profiles for a service *) let profiles_cmd = let service_arg = let doc = "Service name to inspect" in Arg.(required & pos 0 (some string) None & info [] ~docv:"SERVICE" ~doc) in let info = Cmd.info "profiles" ~doc:"List profiles for a service" in Cmd.v info Term.(const list_profiles_example $ xdg_term $ service_arg) in (* Command: client - API client simulation *) let client_cmd = let profile_term = Keyeio.Cmd.term ~app_name:"keyeio-example" ~fs:env#fs ~service:"immiche" ~profile:"default" () in let info = Cmd.info "client" ~doc:"Simulate API client with credentials" in Cmd.v info Term.(const api_client_example $ xdg_term $ profile_term) in (* Command: init - Create a keyfile *) let init_cmd = let default_data = [ ("api_key", None); (* Will prompt if not provided *) ("base_url", Some "https://immich.example.com") (* Has default *) ] in let init_term = Keyeio.Cmd.create_term ~app_name:"keyeio-example" ~fs:env#fs ~service:"immiche" ~default_data () in let info = Cmd.info "init" ~doc:"Create keyeio credentials" in Cmd.v info init_term in (* Main command group *) let main_cmd = let info = Cmd.info "keyeio-example" ~version:"0.1.0" ~doc:"Examples demonstrating keyeio library usage" ~man:[ `S Manpage.s_description; `P "This program demonstrates various usage patterns for the keyeio library."; `P "Keyeio provides secure API key storage using XDG directories with support for multiple profiles per service."; `S "EXAMPLES"; `P "List all configured services:"; `Pre " $(b,keyeio-example list)"; `P "Show profiles for a service:"; `Pre " $(b,keyeio-example profiles immiche)"; `P "Basic usage with default profile:"; `Pre " $(b,keyeio-example basic)"; `P "Use a specific profile:"; `Pre " $(b,keyeio-example basic --profile production)"; `P "Simulate an API client:"; `Pre " $(b,keyeio-example client --profile staging)"; ] in Cmd.group info [init_cmd; basic_cmd; list_cmd; profiles_cmd; client_cmd] in exit (Cmd.eval' main_cmd)