Class: Text::Gen::Runner
- Inherits:
-
Object
- Object
- Text::Gen::Runner
- Defined in:
- lib/text/gen/runner.rb
Overview
Runner generates results from the builder that is found with the given key.
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
Returns the value of attribute key.
-
#locale ⇒ Object
Returns the value of attribute locale.
-
#lookup ⇒ Object
readonly
Returns the value of attribute lookup.
-
#max_attempts ⇒ Object
readonly
Returns the value of attribute max_attempts.
-
#max_recursion ⇒ Object
readonly
Returns the value of attribute max_recursion.
-
#store ⇒ Object
Returns the value of attribute store.
-
#unique ⇒ Object
Returns the value of attribute unique.
Class Method Summary collapse
Instance Method Summary collapse
- #apply_item_filters(items, filters) ⇒ Object
- #apply_result_filters(result, filters) ⇒ Object
- #apply_result_function(result, filters) ⇒ Object
- #fetch_builder(key) ⇒ Object
-
#initialize(key:, lookup:, max_recursion: 10, max_attempts: 10, request_filters: []) ⇒ Runner
constructor
A new instance of Runner.
- #merge_filters(builder, filters) ⇒ Object
-
#populate_replace ⇒ Object
A filter of type “replace:key:value” creates a temporary builder that always returns the given value.
- #random_from_dice(text) ⇒ Object
- #random_item(strategy, items) ⇒ Object
- #run(count: 1) ⇒ Object
-
#run_builder(_key, builder, filters, depth) ⇒ Object
A builder is hash with a key field, items, filters, and meta.
- #run_dice_segment(seg) ⇒ Object
- #run_item(item, depth) ⇒ Object
- #run_item_sequence(items, filters, meta, depth) ⇒ Object
- #run_items(strategy, items, filters, meta, depth) ⇒ Object
- #run_number_segment(seg) ⇒ Object
- #run_random_item(strategy, items, meta, depth) ⇒ Object
- #run_reference_segment(seg, depth) ⇒ Object
- #run_segment(seg, depth) ⇒ Object
- #run_weighted_items(items, meta, depth) ⇒ Object
- #to_h ⇒ Object
- #unique? ⇒ Boolean
Constructor Details
#initialize(key:, lookup:, max_recursion: 10, max_attempts: 10, request_filters: []) ⇒ Runner
Returns a new instance of Runner.
13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/text/gen/runner.rb', line 13 def initialize(key:, lookup:, max_recursion: 10, max_attempts: 10, request_filters: []) @key = key.to_s.downcase @lookup = lookup @locale = nil @store = Store.new @unique = false @request_filters = request_filters @max_attempts = max_attempts @max_recursion = max_recursion populate_replace end |
Instance Attribute Details
#key ⇒ Object (readonly)
Returns the value of attribute key.
10 11 12 |
# File 'lib/text/gen/runner.rb', line 10 def key @key end |
#locale ⇒ Object
Returns the value of attribute locale.
11 12 13 |
# File 'lib/text/gen/runner.rb', line 11 def locale @locale end |
#lookup ⇒ Object (readonly)
Returns the value of attribute lookup.
10 11 12 |
# File 'lib/text/gen/runner.rb', line 10 def lookup @lookup end |
#max_attempts ⇒ Object (readonly)
Returns the value of attribute max_attempts.
10 11 12 |
# File 'lib/text/gen/runner.rb', line 10 def max_attempts @max_attempts end |
#max_recursion ⇒ Object (readonly)
Returns the value of attribute max_recursion.
10 11 12 |
# File 'lib/text/gen/runner.rb', line 10 def max_recursion @max_recursion end |
#store ⇒ Object
Returns the value of attribute store.
11 12 13 |
# File 'lib/text/gen/runner.rb', line 11 def store @store end |
#unique ⇒ Object
Returns the value of attribute unique.
11 12 13 |
# File 'lib/text/gen/runner.rb', line 11 def unique @unique end |
Class Method Details
.from_hash(hash) ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/text/gen/runner.rb', line 198 def from_hash(hash) runner = Runner.new( key: hash["key"], request_filters: hash.fetch("request_filters", []) ) hash.fetch("store", {}).each do |k, b| runner.store.add(k, b) end runner end |
Instance Method Details
#apply_item_filters(items, filters) ⇒ Object
180 181 182 183 184 185 186 |
# File 'lib/text/gen/runner.rb', line 180 def apply_item_filters(items, filters) items = Filter.filter_select(items, filters) items = Filter.filter_reject(items, filters) raise FilterError if items.empty? items end |
#apply_result_filters(result, filters) ⇒ Object
166 167 168 169 170 |
# File 'lib/text/gen/runner.rb', line 166 def apply_result_filters(result, filters) result = Filter.result_select(result, filters) result = Filter.result_reject(result, filters) if result result end |
#apply_result_function(result, filters) ⇒ Object
172 173 174 |
# File 'lib/text/gen/runner.rb', line 172 def apply_result_function(result, filters) Filter.functions(result, filters) end |
#fetch_builder(key) ⇒ Object
45 46 47 48 49 |
# File 'lib/text/gen/runner.rb', line 45 def fetch_builder(key) builder = @store.find(key) || lookup.call(key) @store.add(key, builder) builder end |
#merge_filters(builder, filters) ⇒ Object
176 177 178 |
# File 'lib/text/gen/runner.rb', line 176 def merge_filters(builder, filters) builder.key?("filters") ? builder["filters"] + filters : filters end |
#populate_replace ⇒ Object
A filter of type “replace:key:value” creates a temporary builder that always returns the given value.
31 32 33 34 35 |
# File 'lib/text/gen/runner.rb', line 31 def populate_replace @request_filters.each do |f| store.add(f["key"], Filter.constant_builder(f["key"], f["value"])) if f["type"] == "replace" end end |
#random_from_dice(text) ⇒ Object
143 144 145 146 147 148 149 |
# File 'lib/text/gen/runner.rb', line 143 def random_from_dice(text) rolled = DiceNomShim.roll(text) parsed = JSON.parse(rolled).first["lhs"] count = parsed["values"].size total = parsed["total"] [total, count] end |
#random_item(strategy, items) ⇒ Object
77 78 79 80 81 82 83 84 85 |
# File 'lib/text/gen/runner.rb', line 77 def random_item(strategy, items) if strategy.nil? || strategy.empty? || strategy == "random" items.sample else total, count = random_from_dice(strategy) total -= count # make the roll 0-indexed items[total] end end |
#run(count: 1) ⇒ Object
37 38 39 40 41 42 43 |
# File 'lib/text/gen/runner.rb', line 37 def run(count: 1) builder = fetch_builder(key) ResultAccumulator.accumulate(unique: unique?, count: count, max_attempts: max_attempts) do run_builder(key, builder, @request_filters, 0) end end |
#run_builder(_key, builder, filters, depth) ⇒ Object
A builder is hash with a key field, items, filters, and meta
52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/text/gen/runner.rb', line 52 def run_builder(_key, builder, filters, depth) depth += 1 raise MaxRecursionError if depth > max_recursion current_filters = merge_filters(builder, filters) current_items = apply_item_filters(builder["items"], current_filters) result = run_items(builder["strategy"], current_items, current_filters, builder["meta"], depth) return unless result result.(builder["meta"]) result = apply_result_function(result, current_filters) apply_result_filters(result, current_filters) end |
#run_dice_segment(seg) ⇒ Object
151 152 153 154 |
# File 'lib/text/gen/runner.rb', line 151 def run_dice_segment(seg) total, = random_from_dice(seg["text"]) Result.new(text: total.to_s, multiplier: total, type: :dice) end |
#run_item(item, depth) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/text/gen/runner.rb', line 116 def run_item(item, depth) locale_item = Filter.replace_locale(item, locale) item = locale_item || item results = item["segments"].map { |seg| run_segment(seg, depth) } result = Result.merge(results, value: item["value"], multiplier: item["multiplier"], filters: item["filters"], meta: item["meta"]) result = apply_result_function(result, item["filters"]) apply_result_filters(result, item["filters"]) end |
#run_item_sequence(items, filters, meta, depth) ⇒ Object
96 97 98 99 |
# File 'lib/text/gen/runner.rb', line 96 def run_item_sequence(items, filters, , depth) results = items.map { |item| run_item(item, depth) } Result.merge(results, filters:, meta:, type: :sequence) end |
#run_items(strategy, items, filters, meta, depth) ⇒ Object
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/text/gen/runner.rb', line 66 def run_items(strategy, items, filters, , depth) case strategy when "sequence" run_item_sequence(items, filters, , depth) when "weighted" run_weighted_items(items, , depth) else run_random_item(strategy, items, , depth) end end |
#run_number_segment(seg) ⇒ Object
156 157 158 159 |
# File 'lib/text/gen/runner.rb', line 156 def run_number_segment(seg) num = seg["text"].to_i Result.new(text: num.to_s, multiplier: num, type: :number) end |
#run_random_item(strategy, items, meta, depth) ⇒ Object
87 88 89 90 91 92 93 94 |
# File 'lib/text/gen/runner.rb', line 87 def run_random_item(strategy, items, , depth) item = random_item(strategy, items) return unless item result = run_item(item, depth) result.() result end |
#run_reference_segment(seg, depth) ⇒ Object
161 162 163 164 |
# File 'lib/text/gen/runner.rb', line 161 def run_reference_segment(seg, depth) key = seg["text"] run_builder(key, fetch_builder(key), seg.fetch("filters", []), depth) end |
#run_segment(seg, depth) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/text/gen/runner.rb', line 130 def run_segment(seg, depth) case seg["type"] when "dice" run_dice_segment(seg) when "number" run_number_segment(seg) when "reference" run_reference_segment(seg, depth) else Result.new(text: seg["text"], value: seg["value"], type: :constant) end end |
#run_weighted_items(items, meta, depth) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/text/gen/runner.rb', line 101 def run_weighted_items(items, , depth) total_weight = items.sum { |item| [item.fetch("weight", 1).to_i, 1].max } rand_weight = rand(total_weight) current_weight = 0 item = items.find do |item| current_weight += [item.fetch("weight", 1).to_i, 1].max current_weight > rand_weight end return unless item result = run_item(item, depth) result.() result end |
#to_h ⇒ Object
188 189 190 191 192 193 194 195 |
# File 'lib/text/gen/runner.rb', line 188 def to_h { "key" => key, "request_filters" => request_filters, "request_meta" => , "store" => store.to_h } end |
#unique? ⇒ Boolean
25 26 27 |
# File 'lib/text/gen/runner.rb', line 25 def unique? @unique end |