(** Cache entry flags management *) type flag = [ | `Pinned | `Stale | `Temporary | `Chunk ] module FlagSet = Set.Make(struct type t = flag let compare = Stdlib.compare end) type t = FlagSet.t let empty = FlagSet.empty let of_list flags = List.fold_left (fun acc f -> FlagSet.add f acc) FlagSet.empty flags let to_list t = FlagSet.elements t let singleton flag = FlagSet.singleton flag let add flag t = FlagSet.add flag t let remove flag t = FlagSet.remove flag t let mem flag t = FlagSet.mem flag t let union = FlagSet.union let inter = FlagSet.inter let diff = FlagSet.diff let is_empty = FlagSet.is_empty let is_pinned t = mem `Pinned t let is_stale t = mem `Stale t let is_temporary t = mem `Temporary t let is_chunk t = mem `Chunk t let is_complete t = not (is_chunk t) let flag_to_char = function | `Pinned -> 'P' | `Stale -> 'S' | `Temporary -> 'T' | `Chunk -> 'C' let char_to_flag = function | 'P' -> Some `Pinned | 'S' -> Some `Stale | 'T' -> Some `Temporary | 'C' -> Some `Chunk | _ -> None let to_string t = to_list t |> List.map flag_to_char |> List.to_seq |> String.of_seq let of_string s = String.to_seq s |> Seq.filter_map char_to_flag |> List.of_seq |> of_list let equal = FlagSet.equal let compare = FlagSet.compare let pp_flag fmt = function | `Pinned -> Format.fprintf fmt "Pinned" | `Stale -> Format.fprintf fmt "Stale" | `Temporary -> Format.fprintf fmt "Temporary" | `Chunk -> Format.fprintf fmt "Chunk" let pp fmt t = let flags = to_list t in match flags with | [] -> Format.fprintf fmt "[]" | _ -> Format.fprintf fmt "[%s]" (String.concat "," (List.map (function | `Pinned -> "P" | `Stale -> "S" | `Temporary -> "T" | `Chunk -> "C") flags)) (* Jsont support *) (* JSON codec for individual flags - using string representation *) let flag_jsont = let kind = "Flag" in let doc = "A cache entry flag" in let dec s = match s with | "pinned" -> `Pinned | "stale" -> `Stale | "temporary" -> `Temporary | "chunk" -> `Chunk | _ -> Jsont.Error.msg Jsont.Meta.none "Invalid flag value" in let enc = function | `Pinned -> "pinned" | `Stale -> "stale" | `Temporary -> "temporary" | `Chunk -> "chunk" in Jsont.map ~kind ~doc ~dec ~enc Jsont.string (* JSON codec for flag set *) let jsont = let kind = "Flags" in let doc = "A set of cache entry flags" in let dec lst = of_list lst in let enc t = to_list t in Jsont.map ~kind ~doc ~dec ~enc (Jsont.list flag_jsont)