diff --git a/otherlibs/stdune/src/filename_set.ml b/otherlibs/stdune/src/filename_set.ml new file mode 100644 index 00000000000..0f8bc3a37ac --- /dev/null +++ b/otherlibs/stdune/src/filename_set.ml @@ -0,0 +1,27 @@ +(* CR-someday amokhov: Switch from sets to "flat sets" backed by immutable arrays. *) +type t = + { dir : Path.t + ; filenames : Filename.Set.t + } + +let equal t { dir; filenames } = + Path.equal t.dir dir && Filename.Set.equal filenames t.filenames +;; + +let dir { dir; filenames = _ } = dir +let filenames { dir = _; filenames } = filenames +let empty ~dir = { dir; filenames = String.Set.empty } + +let create ?filter ~dir filenames = + match filter with + | None -> { dir; filenames } + | Some f -> + { dir + ; filenames = + Filename.Set.to_list filenames + |> List.filter ~f:(fun basename -> f ~basename) + |> Filename.Set.of_list + } +;; + +let to_list { dir; filenames } = Filename.Set.to_list_map filenames ~f:(Path.relative dir) diff --git a/otherlibs/stdune/src/filename_set.mli b/otherlibs/stdune/src/filename_set.mli new file mode 100644 index 00000000000..9a69b17134e --- /dev/null +++ b/otherlibs/stdune/src/filename_set.mli @@ -0,0 +1,19 @@ +(** Like [Path.Set.t] but tailored for representing sets of file names in the same parent + directory. Compared to [Path.Set.t], [Filename_set.t] statically enforces an important + invariant, and can also be processed more efficiently. *) + +type t + +val equal : t -> t -> bool + +(** The directory of the filename set. *) +val dir : t -> Path.t + +(** The set of file names, all relative to [dir]. *) +val filenames : t -> Filename.Set.t + +val empty : dir:Path.t -> t + +(* CR-soon amokhov: Decouple [create] from [filter]. *) +val create : ?filter:(basename:string -> bool) -> dir:Path.t -> Filename.Set.t -> t +val to_list : t -> Path.t list