Class: Ruby::Rego::Builtins::Regex::GoTemplate

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby/rego/builtins/regex/go_template.rb

Overview

Parses a Go regexp.Expand replacement template once, then expands it against each match. $name/${name} reference a submatch (numeric name = numbered group, $0 = whole match; an unknown or out-of-range reference expands to the empty string), $$ is a literal $, a $ not followed by a valid name is a literal $, and every other character (including backslash) is a literal.

Constant Summary collapse

NAME_CHAR =

Go’s Expand reads a name as Unicode letters, digits, and underscore.

/[\p{L}\p{Nd}_]/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template, names) ⇒ GoTemplate

Callers MUST cap the template length (Regex.assert_source_length) before constructing — parse materializes template.chars, an uninterruptible O(n) call. replace is the only caller and does so.

Parameters:

  • template (String)
  • names (Hash{String => Integer})

    named group -> capture index



29
30
31
32
33
# File 'lib/ruby/rego/builtins/regex/go_template.rb', line 29

def initialize(template, names)
  @names = names
  @segments = parse(template.chars)
  @segment_count = @segments.length
end

Instance Attribute Details

#segment_countObject (readonly)

Number of parsed segments; the caller charges this per match against the work budget, since each expansion loops exactly this many segments. The template length is capped (MAX_REGEX_SOURCE) before construction, so parse and per-match expand are both O(capped template) — no separate time bound needed.



21
22
23
# File 'lib/ruby/rego/builtins/regex/go_template.rb', line 21

def segment_count
  @segment_count
end

Instance Method Details

#expand(match, budget) ⇒ String

Expands the template against match, raising once accumulated output would exceed budget so a single expansion cannot exhaust memory.

Parameters:

  • match (MatchData)
  • budget (Integer)

Returns:

  • (String)


41
42
43
44
45
46
47
48
# File 'lib/ruby/rego/builtins/regex/go_template.rb', line 41

def expand(match, budget)
  out = +""
  @segments.each do |kind, value|
    out << resolve(kind, value, match)
    raise_output_too_large(budget) if out.length > budget
  end
  out
end