<commit_before>$: << 'lib'
require 'bound'
require 'benchmark'

TestBoundary = Bound.required(:foo, :baz => Bound.required(:gonzo))

StructBoundary = Struct.new(:foo, :baz)
NestedStructBoundary = Struct.new(:gonzo)

StaticBound = Class.new do
  def initialize(target)
    @target = target
  end
end

StaticObjBoundary = Class.new(StaticBound) do
  def foo
    @target.foo
  end

  def baz
    @baz ||= BazObjBoundary.new(@target.baz)
  end

  BazObjBoundary = Class.new(StaticBound) do
    def gonzo
      @target.gonzo
    end
  end
end

StaticHashBoundary = Class.new(StaticBound) do
  def foo
    @target[:foo]
  end

  def baz
    @baz ||= BazHashBoundary.new(@target[:baz])
  end

  BazHashBoundary = Class.new(StaticBound) do
    def gonzo
      @target[:gonzo]
    end
  end
end


def assert_correctness(bound)
  raise('foo is wrong') unless bound.foo == 'YES'
  raise('baz.gonzo is wrong') unless bound.baz.gonzo == 22
end

def bench(key, &block)
  result = nil

  time = Benchmark.realtime { result = block.call }
  puts "Benchmarking '#{key}' --> #{time}ms"

  result
end

Provider = Class.new do
  attr_accessor :foo, :baz
  BazProvider = Class.new do
    attr_accessor :gonzo
  end
end
provider_objects = 10_000.times.map do |i|
  Provider.new.tap do |p|
    p.foo = 'YES'
    p.baz = Provider::BazProvider.new.tap do |bp|
      bp.gonzo = 22
    end
  end
end

provider_hashes = 10_000.times.map do |i|
  {
   :foo => 'YES',
   :baz => {:gonzo => 22}
  }
end

bench '      bound w/ objt' do
  provider_objects.each do |provider|
    result = TestBoundary.new(provider)
    assert_correctness result
  end
end

bench '      bound w/ hash' do
  provider_hashes.each do |provider|
    result = TestBoundary.new(provider)
    assert_correctness result
  end
end

bench 'staticbound w/ objt' do
  provider_objects.each do |provider|
    result = StaticObjBoundary.new(provider)
    assert_correctness result
  end
end

bench 'staticbound w/ hash' do
  provider_hashes.each do |provider|
    result = StaticHashBoundary.new(provider)
    assert_correctness result
  end
end

bench 'structbound w/ objt' do
  provider_objects.each do |provider|
    result = StructBoundary.new(
                                provider.foo,
                                NestedStructBoundary.new(provider.baz.gonzo)
                               )
    assert_correctness result
  end
end

bench 'structbound w/ hash' do
  provider_hashes.map do |provider|
    result = StructBoundary.new(
                                provider[:foo],
                                NestedStructBoundary.new(provider[:baz][:gonzo])
                               )<commit_msg>Add bar collection and refactor static bound<commit_after>$: << 'lib'
require 'bound'
require 'benchmark'

TestBoundary = Bound.required(
                              :foo,
                              :bar => [Bound.required(:abc)],
                              :baz => Bound.required(:gonzo)
                             )

StructBoundary = Struct.new(:foo, :bar, :baz)
BarStructBoundary = Struct.new(:abc)
BazStructBoundary = Struct.new(:gonzo)

StaticBound = Class.new do
  def initialize(target)
    @target = target
  end
end

BarStaticBoundary = Class.new(StaticBound) do
  def abc
    @target.kind_of?(Hash)?@target[:abc] : @target.abc
  end
end

BazStaticBoundary = Class.new(StaticBound) do
  def gonzo
    @target.kind_of?(Hash)?@target[:gonzo] : @target.gonzo
  end
end

StaticBoundary = Class.new(StaticBound) do
  def foo
    @target.kind_of?(Hash)?@target[:foo] : @target.foo
  end

  def bar
    @bar ||=
      (@target.kind_of?(Hash)?@target[:bar] : @target.bar).
      map { |t| BarStaticBoundary.new(t) }
  end

  def baz
    @baz ||=
      BazStaticBoundary.new(
                            (@target.kind_of?(Hash)?@target[:baz] : @target.baz)
                           )
  end
end

def assert_correctness(bound)
  raise('foo is wrong') unless bound.foo == 'YES'
  raise('bar size is wrong') unless bound.bar.size == 2
  raise('bar[0] is wrong') unless bound.bar[0].abc == 'TRUE'
  raise('bar[1] is wrong') unless bound.bar[1].abc == 'FALSE'
  raise('baz.gonzo is wrong') unless bound.baz.gonzo == 22
end

def bench(key, &block)
  result = nil

  time = Benchmark.realtime { result = block.call }
  puts "Benchmarking '#{key}' --> #{time}ms"

  result
end

Provider = Class.new do
  attr_accessor :foo, :bar, :baz
  BarProvider = Class.new do
    attr_accessor :abc
  end
  BazProvider = Class.new do
    attr_accessor :gonzo
  end
end
provider_objects = 10_000.times.map do |i|
  Provider.new.tap do |p|
    p.foo = 'YES'
    p.bar = [
             BarProvider.new.tap do |brp|
               brp.abc = 'TRUE'
             end,
             BarProvider.new.tap do |brp|
               brp.abc = 'FALSE'
             end
            ]
    p.baz = Provider::BazProvider.new.tap do |bzp|
      bzp.gonzo = 22
    end
  end
end

provider_hashes = 10_000.times.map do |i|
  {
   :foo => 'YES',
   :bar => [{:abc => 'TRUE'}, {:abc => 'FALSE'}],
   :baz => {:gonzo => 22}
  }
end

bench '      bound w/ objt' do
  provider_objects.each do |provider|
    result = TestBoundary.new(provider)
    assert_correctness result
  end
end

bench '      bound w/ hash' do
  provider_hashes.each do |provider|
    result = TestBoundary.new(provider)
    assert_correctness result
  end
end

bench 'staticbound w/ objt' do
  provider_objects.each do |provider|
    result = StaticBoundary.new(provider)
    assert_correctness result
  end
end

bench 'staticbound w/ hash' do
  provider_hashes.each do |provider|
    result = StaticBoundary.new(provider)
    assert_correctness result
  end
end

bench 'structbound w/ objt' do
  provider_objects.each do |provider|
    result = StructBoundary.new(
                                provider.foo,
                                [
                                 BarStructBoundary.new(provider.bar[0].abc),
                                 BarStructBoundary.new(provider.bar[1].abc),
                                ],
                                BazStructBoundary.new(provider.baz.gonzo)
                               )
    assert_correctness result
  end
end

bench 'structbound w/ hash' do
  provider_hashes.map do |provider|
    result = StructBoundary.new(
                                provider[:foo],
                                [
                                 BarStructBoundary.new(provider[:bar][0][:abc]),
                                 BarStructBoundary.new(provider[:bar][1][:abc]),
                                ],
                                BazStructBoundary.new(provider[:baz][:gonzo])
                               )
{'fraction_non_alphanumeric': 0.11016058832357797, 'fraction_numerical': 0.006153384361398769, 'mean_word_length': 2.1227741330834116, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6905310', 'n_tokens_mistral': 2221, 'n_tokens_neox': 2114, 'n_words': 503}