···308308309309type parsed = { mqtt : t; xdg : Xdge.t; xdg_config : Xdge.Cmd.t }
310310311311-let term ~app_name ~fs () =
312312- (* Create XDG context to read config file defaults at term construction time.
313313- The xdg_term from Xdge.Cmd will provide runtime XDG paths with CLI override. *)
314314- let xdg = Xdge.create fs app_name in
315315- let file_config =
316316- match Config_file.load xdg with Some c -> c | None -> Config_file.empty
317317- in
311311+let term_with_config ~app_name ~fs ~config:file_config () =
318312 (* Xdge.Cmd.term provides XDG paths with command-line override support *)
319313 let xdg_term = Xdge.Cmd.term app_name fs ~dirs:[ `Config ] () in
320314 let make (xdg, xdg_config) connection config pool_config =
···325319 $ connection_term ~file_config
326320 $ config_term ~file_config
327321 $ pool_config_term ~file_config)
322322+323323+let term ~app_name ~fs () =
324324+ (* Create XDG context to read config file defaults at term construction time. *)
325325+ let xdg = Xdge.create fs app_name in
326326+ let file_config =
327327+ match Config_file.load xdg with Some c -> c | None -> Config_file.empty
328328+ in
329329+ term_with_config ~app_name ~fs ~config:file_config ()
328330329331(** {1 Connection Pool Helpers} *)
330332
+84-2
lib/cmd/mqtte_cmd.mli
···129129(** {1 Configuration File} *)
130130131131module Config_file : sig
132132- type t
133133- (** Parsed TOML configuration. *)
132132+ (** {2 MQTT Configuration} *)
133133+134134+ type mqtt_config = {
135135+ host : string option;
136136+ port : int option;
137137+ tls : bool option;
138138+ insecure : bool option;
139139+ client_id : string option;
140140+ clean_session : bool option;
141141+ keep_alive : int option;
142142+ username : string option;
143143+ password : string option;
144144+ protocol_version : string option;
145145+ }
146146+ (** MQTT connection settings parsed from config file. All fields optional. *)
147147+148148+ val empty_mqtt_config : mqtt_config
149149+ (** Empty MQTT config with all fields set to [None]. *)
150150+151151+ val mqtt_codec : mqtt_config Tomlt.t
152152+ (** Tomlt codec for the [[mqtt]] section. Use this to compose with your
153153+ application's config codec. *)
154154+155155+ (** {2 Pool Configuration} *)
156156+157157+ type pool_config = {
158158+ min_connections : int option;
159159+ max_connections : int option;
160160+ idle_timeout : float option;
161161+ }
162162+ (** Connection pool settings parsed from config file. *)
163163+164164+ val empty_pool_config : pool_config
165165+ (** Empty pool config with all fields set to [None]. *)
166166+167167+ val pool_codec : pool_config Tomlt.t
168168+ (** Tomlt codec for the [[pool]] section. *)
169169+170170+ (** {2 Combined Configuration} *)
171171+172172+ type t = { mqtt : mqtt_config; pool : pool_config }
173173+ (** Combined configuration from both sections. *)
174174+175175+ val empty : t
176176+ (** Empty configuration. *)
177177+178178+ val codec : t Tomlt.t
179179+ (** Tomlt codec for the full config file (both [[mqtt]] and [[pool]] sections).
180180+ Use this when loading a standalone config.toml, or use {!mqtt_codec} and
181181+ {!pool_codec} separately to compose with application-specific sections. *)
134182135183 val load : Xdge.t -> t option
136184 (** [load xdg] attempts to load [config.toml] from the XDG config directory.
···140188 (** [load_from_path path] loads configuration from a specific file path.
141189 Returns [None] if the file doesn't exist or cannot be parsed. *)
142190end
191191+192192+val term_with_config :
193193+ app_name:string ->
194194+ fs:Eio.Fs.dir_ty Eio.Path.t ->
195195+ config:Config_file.t ->
196196+ unit ->
197197+ parsed Cmdliner.Term.t
198198+(** [term_with_config ~app_name ~fs ~config ()] creates a Cmdliner term using
199199+ the provided pre-loaded configuration. Use this when you have a custom
200200+ config file format that includes the [[mqtt]] and [[pool]] sections.
201201+202202+ Example with composed config:
203203+ {[
204204+ (* In your app's config module *)
205205+ type t = {
206206+ app_setting : string;
207207+ mqtt : Mqtte_cmd.Config_file.mqtt_config;
208208+ pool : Mqtte_cmd.Config_file.pool_config;
209209+ }
210210+211211+ let codec = Tomlt.Table.(
212212+ obj (fun app_setting mqtt pool -> { app_setting; mqtt; pool })
213213+ |> mem "app_setting" Tomlt.string ~enc:(fun c -> c.app_setting)
214214+ |> opt_mem "mqtt" Mqtte_cmd.Config_file.mqtt_codec
215215+ ~enc:(fun c -> Some c.mqtt)
216216+ |> opt_mem "pool" Mqtte_cmd.Config_file.pool_codec
217217+ ~enc:(fun c -> Some c.pool)
218218+ |> finish
219219+ )
220220+221221+ (* When creating the term *)
222222+ let mqtt_config = Mqtte_cmd.Config_file.{ mqtt = config.mqtt; pool = config.pool } in
223223+ Mqtte_cmd.term_with_config ~app_name ~fs ~config:mqtt_config ()
224224+ ]} *)
143225144226(** {1 Man Page Documentation}
145227