Matrix protocol in OCaml, Eio specialised
at main 205 lines 5.6 kB view raw
1(** Cmdliner terms for Matrix CLI applications. 2 3 This module provides reusable cmdliner terms and combinators for building 4 Matrix client command-line interfaces. It follows the principle of 5 separation: parsing logic lives here, whilst business logic should remain 6 in plain OCaml functions that receive already-parsed values. 7 8 {2 Design Principles} 9 10 - {b Clarity}: Each option has a single, clearly stated purpose 11 - {b Orthogonality}: Each flag controls one independent aspect 12 - {b Discoverability}: Good --help output with defaults documented 13 - {b Composability}: Terms can be combined for different CLI tools 14 15 {2 Example Usage} 16 17 {[ 18 open Cmdliner 19 20 let run ~homeserver ~profile ~verbose () = 21 (* your implementation *) 22 () 23 24 let term = 25 let open Matrix_client.Cmd in 26 Term.(const run 27 $ homeserver_term 28 $ profile_term 29 $ verbose_term) 30 31 let cmd = 32 let info = Cmd.info "myapp" ~doc:"My Matrix app" in 33 Cmd.v info term 34 ]} *) 35 36open Cmdliner 37 38(** {1 Connection Options} *) 39 40(** Matrix homeserver URL term. 41 42 Accepts [--homeserver URL] or [-s URL], with fallback to 43 [MATRIX_HOMESERVER] environment variable. 44 45 @return The homeserver URL as a string *) 46val homeserver_term : string Term.t 47 48(** Matrix homeserver URL term (optional). 49 50 Like {!homeserver_term} but returns [None] if not specified. 51 Useful when a stored session may provide the homeserver. *) 52val homeserver_opt_term : string option Term.t 53 54(** {1 Authentication Options} *) 55 56(** Username term. 57 58 Accepts [--username USER] or [-u USER], with fallback to 59 [MATRIX_USERNAME] environment variable. Accepts either a 60 localpart or full [@user:server] format. *) 61val username_term : string Term.t 62 63(** Username term (optional). *) 64val username_opt_term : string option Term.t 65 66(** Password term. 67 68 Accepts [--password PASS] or [-p PASS], with fallback to 69 [MATRIX_PASSWORD] environment variable. 70 71 {b Security note}: The environment variable is preferred 72 over the command-line flag to avoid password exposure in 73 process listings. *) 74val password_term : string Term.t 75 76(** Password term (optional). *) 77val password_opt_term : string option Term.t 78 79(** {1 Session Management} *) 80 81(** Profile name term. 82 83 Accepts [--profile NAME] with default ["default"]. 84 Profiles are stored in [$XDG_DATA_HOME/matrix/profiles/NAME/]. 85 86 Multiple profiles allow managing several Matrix accounts 87 on the same machine. *) 88val profile_term : string Term.t 89 90(** {1 Target Options} *) 91 92(** Room ID term. 93 94 Accepts [--room ROOM_ID] or [-r ROOM_ID]. 95 The room ID should be in the format [!roomid:server]. *) 96val room_term : string Term.t 97 98(** Room ID term (optional). *) 99val room_opt_term : string option Term.t 100 101(** Recipient user ID term. 102 103 Accepts [--to USER_ID] or [-t USER_ID]. 104 The user ID should be in the format [@user:server]. 105 Used for direct messages. *) 106val recipient_term : string Term.t 107 108(** Recipient user ID term (optional). *) 109val recipient_opt_term : string option Term.t 110 111(** {1 Message Options} *) 112 113(** Message body term. 114 115 A positional argument for the message text to send. *) 116val message_term : string Term.t 117 118(** Message body term (optional). *) 119val message_opt_term : string option Term.t 120 121(** {1 Encryption Options} *) 122 123(** Encrypted flag term. 124 125 Accepts [--encrypted] or [-e]. 126 Enables end-to-end encryption for newly created rooms. *) 127val encrypted_term : bool Term.t 128 129(** {1 Logging Options} *) 130 131(** Verbosity level term. 132 133 Accepts [-v] (repeatable) for increasing verbosity: 134 - No flags: warnings and errors only 135 - [-v]: info messages 136 - [-v -v]: debug messages 137 138 Also respects [--color] for output styling. 139 140 This term returns [unit] and sets up logging as a side effect 141 when the term is evaluated. *) 142val verbosity_term : unit Term.t 143 144(** {1 Argument Converters} *) 145 146(** Cmdliner converter for Matrix user IDs. 147 148 Validates that the string is a valid user ID in the format 149 [@localpart:server]. *) 150val user_id_conv : Matrix_proto.Id.User_id.t Arg.conv 151 152(** Cmdliner converter for Matrix room IDs. 153 154 Validates that the string is a valid room ID in the format 155 [!opaque_id:server]. *) 156val room_id_conv : Matrix_proto.Id.Room_id.t Arg.conv 157 158(** Cmdliner converter for URIs. *) 159val uri_conv : Uri.t Arg.conv 160 161(** {1 Parsed Types} 162 163 Record types for collecting parsed arguments, useful for 164 structuring command implementations. *) 165 166(** Credentials for password-based login. *) 167type login_credentials = { 168 homeserver : string; 169 username : string; 170 password : string; 171 profile : string; 172} 173 174(** Term that collects login credentials. *) 175val login_credentials_term : login_credentials Term.t 176 177(** Target for sending a message (room or DM). *) 178type message_target = 179 | Room of string (** Room ID *) 180 | Direct of string (** Recipient user ID *) 181 182(** Message parameters for sending. *) 183type message_params = { 184 target : message_target; 185 body : string; 186 encrypted : bool; 187} 188 189(** {1 Command Builders} 190 191 Helper functions for building common command patterns. *) 192 193(** Exit codes following standard conventions. 194 195 - [exit_ok]: Success (0) 196 - [exit_usage]: Usage error (64) 197 - [exit_auth]: Authentication failure (77) 198 - [exit_network]: Network error (69) 199 - [exit_internal]: Internal error (70) *) 200 201val exit_ok : Cmd.Exit.code 202val exit_usage : Cmd.Exit.code 203val exit_auth : Cmd.Exit.code 204val exit_network : Cmd.Exit.code 205val exit_internal : Cmd.Exit.code