1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
(**************************************************************************)
(* Copyright © 2025-2025 Stéphane Glondu <steph@glondu.net> *)
(* *)
(* This program is free software: you can redistribute it and/or modify *)
(* it under the terms of the GNU Affero General Public License as *)
(* published by the Free Software Foundation, either version 3 of the *)
(* License, or (at your option) any later version, with the additional *)
(* exemption that compiling, linking, and/or using OpenSSL is allowed. *)
(* *)
(* This program is distributed in the hope that it will be useful, but *)
(* WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *)
(* Affero General Public License for more details. *)
(* *)
(* You should have received a copy of the GNU Affero General Public *)
(* License along with this program. If not, see *)
(* <http://www.gnu.org/licenses/>. *)
(**************************************************************************)
open Core
type t = { fields : string list; map : string StringMap.t }
let empty = { fields = []; map = StringMap.empty }
let mem k m = StringMap.mem (String.lowercase_ascii k) m.map
let find k m = StringMap.find (String.lowercase_ascii k) m.map
let add k v m =
let k' = String.lowercase_ascii k in
let fields = if StringMap.mem k' m.map then m.fields else k :: m.fields in
let map = StringMap.add k' v m.map in
{ fields; map }
let remove k m =
let k' = String.lowercase_ascii k in
if StringMap.mem k' m.map then
let fields =
List.filter (fun x -> String.lowercase_ascii x <> k') m.fields
in
let map = StringMap.remove k' m.map in
{ fields; map }
else m
let filter f m =
let fields, map =
List.fold_left
(fun (fields, map) k ->
if f k then (k :: fields, map)
else (fields, StringMap.remove (String.lowercase_ascii k) map))
([], m.map) (List.rev m.fields)
in
if map == m.map then m else { fields; map }
let pp outc m =
List.iter
(fun k ->
let v = StringMap.find (String.lowercase_ascii k) m.map in
Format.fprintf outc "%s: %s\n" k v)
(List.rev m.fields);
Format.fprintf outc "\n"
|