diff --git a/src/action.ml b/src/action.ml index 4cc10353..d112621c 100644 --- a/src/action.ml +++ b/src/action.ml @@ -374,8 +374,8 @@ module Unexpanded = struct | Left x -> map x | Right template -> match To_VE.expand dir template ~f with - | Left e -> special dir e - | Right s -> generic dir s + | Expansion e -> special dir e + | String s -> generic dir s [@@inlined always] let string ~dir ~f x = @@ -465,9 +465,9 @@ module Unexpanded = struct module E = struct let expand ~generic ~special ~dir ~f template = match To_VE.partial_expand dir template ~f with - | Left (Left e) -> Left (special dir e) - | Left (Right s) -> Left (generic dir s) - | Right _ as x -> x + | Expansion e -> Left (special dir e) + | String s -> Left (generic dir s) + | Unexpanded x -> Right x let string ~dir ~f x = expand ~dir ~f x diff --git a/src/string_with_vars.ml b/src/string_with_vars.ml index c1593165..605bb458 100644 --- a/src/string_with_vars.ml +++ b/src/string_with_vars.ml @@ -116,6 +116,20 @@ let concat_rev = function | [s] -> s | l -> String.concat (List.rev l) ~sep:"" +module Expand = struct + module Full = struct + type nonrec 'a t = + | Expansion of 'a + | String of string + end + module Partial = struct + type nonrec 'a t = + | Expansion of 'a + | String of string + | Unexpanded of t + end +end + module Expand_to(V: EXPANSION) = struct let expand ctx t ~f = @@ -123,10 +137,10 @@ module Expand_to(V: EXPANSION) = struct | [Var (syntax, v)] when not t.quoted -> (* Unquoted single var *) (match f t.loc v with - | Some e -> Left e - | None -> Right (string_of_var syntax v)) + | Some e -> Expand.Full.Expansion e + | None -> Expand.Full.String (string_of_var syntax v)) | _ -> - Right (List.map t.items ~f:(function + Expand.Full.String (List.map t.items ~f:(function | Text s -> s | Var (syntax, v) -> match f t.loc v with @@ -137,7 +151,7 @@ module Expand_to(V: EXPANSION) = struct (string_of_var syntax v) else V.to_string ctx x | None -> string_of_var syntax v) - |> String.concat ~sep:"") + |> String.concat ~sep:"") let partial_expand ctx t ~f = let commit_text acc_text acc = @@ -148,8 +162,8 @@ module Expand_to(V: EXPANSION) = struct match items with | [] -> begin match acc with - | [] -> Left (Right (concat_rev acc_text)) - | _ -> Right { t with items = List.rev (commit_text acc_text acc) } + | [] -> Expand.Partial.String (concat_rev acc_text) + | _ -> Unexpanded { t with items = List.rev (commit_text acc_text acc) } end | Text s :: items -> loop (s :: acc_text) acc items | Var (syntax, v) as it :: items -> @@ -165,8 +179,8 @@ module Expand_to(V: EXPANSION) = struct | [Var (_, v)] when not t.quoted -> (* Unquoted single var *) (match f t.loc v with - | Some e -> Left (Left e) - | None -> Right t) + | Some e -> Expand.Partial.Expansion e + | None -> Expand.Partial.Unexpanded t) | _ -> loop [] [] t.items end @@ -180,12 +194,15 @@ end module S = Expand_to(String_expansion) let expand t ~f = - match S.expand () t ~f with Left s | Right s -> s + match S.expand () t ~f with + | Expand.Full.String s + | Expansion s -> s let partial_expand t ~f = match S.partial_expand () t ~f with - | Left (Left s | Right s) -> Left s - | Right _ as x -> x + | Expand.Partial.Expansion s -> Left s + | String s -> Left s + | Unexpanded s -> Right s let to_string t = match t.items with diff --git a/src/string_with_vars.mli b/src/string_with_vars.mli index 4bde6edb..9dc3ab38 100644 --- a/src/string_with_vars.mli +++ b/src/string_with_vars.mli @@ -63,17 +63,36 @@ module type EXPANSION = sig using [to_string]. *) end +module Expand : sig + module Full : sig + type nonrec 'a t = + | Expansion of 'a + | String of string + end + module Partial : sig + type nonrec 'a t = + | Expansion of 'a + | String of string + | Unexpanded of t + end +end + module Expand_to(V : EXPANSION) : sig - val expand : V.context -> t -> f:(Loc.t -> string -> V.t option) -> - (V.t, string) Either.t + val expand + : V.context + -> t + -> f:(Loc.t -> string -> V.t option) + -> V.t Expand.Full.t (** [expand t ~f] return [t] where all variables have been expanded using [f]. If [f loc var] return [Some x], the variable [var] is replaced by [x]; otherwise, the variable is inserted using the syntax it was originally defined with: ${..} or $(..) *) - val partial_expand : - V.context -> t -> f:(Loc.t -> string -> V.t option) -> - ((V.t, string) either, t) Either.t + val partial_expand + : V.context + -> t + -> f:(Loc.t -> string -> V.t option) + -> V.t Expand.Partial.t (** [partial_expand t ~f] is like [expand_generic] where all variables that could be expanded (i.e., those for which [f] returns [Some _]) are. If all the variables of [t] were