Skip to content

Commit

Permalink
improve performence
Browse files Browse the repository at this point in the history
  • Loading branch information
oleander committed Dec 16, 2021
1 parent a65d9b2 commit 0cb820b
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 70 deletions.
10 changes: 0 additions & 10 deletions lib/remap/selector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ module Remap
# Defines how a path element, or selector
# Specifies how a value is extracted from a state
class Selector < Dry::Interface
defines :requirement, type: Types::Any.constrained(type: Dry::Types::Type)
requirement Types::Any

# Selects value from state, package it as a state and passes it to block
#
# @param state [State]
Expand All @@ -20,12 +17,5 @@ class Selector < Dry::Interface
def call(state)
raise NotImplementedError, "#{self.class}#call not implemented"
end

private

# @return [Dry::Types::Type]
def requirement
self.class.requirement
end
end
end
18 changes: 9 additions & 9 deletions lib/remap/selector/all.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,28 @@ class Selector
# end
# result.fetch(:value) # => [Hash, Hash]
class All < Concrete
requirement Types::Enumerable

# Iterates over state and passes each value to block
#
# @param outer_state [State<Enumerable<T>>]
# @param state [State<Enumerable<T>>]
#
# @yieldparam [State<T>]
# @yieldreturn [State<U>]
#
# @return [State<U>]
def call(outer_state, &block)
def call(state, &block)
unless block
raise ArgumentError, "All selector requires an iteration block"
end

outer_state.bind(quantifier: "*") do |enum, state|
requirement[enum] do
state.fatal!("Expected enumerable")
end
value = state.fetch(:value) do
return state
end

state.map(&block)
unless value.is_a?(Enumerable)
state.fatal!("Not an enumerator")
end

state.map(&block)
end
end
end
Expand Down
18 changes: 8 additions & 10 deletions lib/remap/selector/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ class Index < Unit
# @return [Integer]
attribute :index, Integer

requirement Types::Array

# Selects the {#index}th element from state and passes it to block
#
# @param state [State<Array<T>>]
Expand All @@ -35,17 +33,17 @@ def call(state, &block)
raise ArgumentError, "The index selector requires an iteration block"
end

state.bind(index: index) do |array, s|
requirement[array] do
s.fatal!("Expected an array")
end
array = state.fetch(:value) { return state }

element = array.fetch(index) do
s.ignore!("Index not found")
end
unless array.is_a?(Array)
state.fatal!("Expected an array got %s", array.class)
end

state.set(element, index: index).then(&block)
value = array.fetch(index) do
state.ignore!("Index [%s] (%s) not found", index, index.class)
end

state.set(value, index: index).then(&block)
end
end
end
Expand Down
18 changes: 8 additions & 10 deletions lib/remap/selector/key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ class Key < Unit
# @return [#hash
attribute :key, Types::Key

requirement Types::Hash

# Selects {#key} from state and passes it to block
#
# @param state [State<Hash<K, V>>]
Expand All @@ -32,17 +30,17 @@ def call(state, &block)
raise ArgumentError, "The key selector requires an iteration block"
end

state.bind(key: key) do |hash, s|
requirement[hash] do
s.fatal!("Expected hash")
end
hash = state.fetch(:value) { return state }

value = hash.fetch(key) do
s.ignore!("Key not found")
end
unless hash.is_a?(Hash)
state.fatal!("Expected hash got %s", hash.class)
end

state.set(value, key: key).then(&block)
value = hash.fetch(key) do
state.ignore!("Key [%s] (%s) not found", key, key.class)
end

state.set(value, key: key).then(&block)
end
end
end
Expand Down
11 changes: 9 additions & 2 deletions spec/feature/remap/failures/each_failure_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
failures: contain_exactly(
have_attributes(
value: { does_not_match: "with John" },
path: [:people, 0, :name]
reason: include("name"),
path: [:people, 0]
)
)
)
Expand All @@ -43,7 +44,13 @@
expect { |b| mapper.call(input, &b) }.to yield_with_args(
an_instance_of(Remap::Failure).and(
have_attributes(
failures: contain_exactly(have_attributes(value: input, path: [:people]))
failures: contain_exactly(
have_attributes(
reason: include("people"),
value: input,
path: []
)
)
)
)
)
Expand Down
16 changes: 14 additions & 2 deletions spec/feature/remap/failures/embed_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@
expect { |b| mapper.call(input, &b) }.to yield_with_args(
an_instance_of(Remap::Failure).and(
have_attributes(
failures: contain_exactly(have_attributes(value: input, path: [:name]))
failures: contain_exactly(
have_attributes(
reason: include("name"),
path: be_empty,
value: input
)
)
)
)
)
Expand All @@ -41,7 +47,13 @@
expect { |b| mapper.call(input, &b) }.to yield_with_args(
an_instance_of(Remap::Failure).and(
have_attributes(
failures: contain_exactly(have_attributes(value: input, path: [:car]))
failures: contain_exactly(
have_attributes(
reason: include("car"),
path: be_empty,
value: input
)
)
)
)
)
Expand Down
24 changes: 14 additions & 10 deletions spec/feature/remap/failures/index_map_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
failures: contain_exactly(
have_attributes(
value: { not_a_match: "Lisa" },
path: [:people, 1, :name]
reason: include("name"),
path: [:people, 1]
)
)
)
Expand All @@ -41,7 +42,7 @@
expect { |b| mapper.call(input, &b) }.to yield_with_args(
be_an_instance_of(Remap::Failure).and(
have_attributes(
failures: contain_exactly(have_attributes(path: [:people, 1]))
failures: contain_exactly(have_attributes(path: [:people]))
)
)
)
Expand All @@ -57,28 +58,31 @@
expect { |b| mapper.call(input, &b) }.to yield_with_args(
an_instance_of(Remap::Failure).and(
have_attributes(
failures: contain_exactly(have_attributes(value: input, path: [:people]))
failures: contain_exactly(
have_attributes(
reason: include("people"),
path: be_empty,
value: input
)
)
)
)
)
end
end

context "when key points to the wrong data type" do
let(:string) { "not a hash" }

let(:input) do
{ people: [{ name: "John" }, "this is not a hash"] }
{ people: [{ name: "John" }, string] }
end

it "raises an exception" do
expect { mapper.call(input, &error) }.to raise_error(
an_instance_of(Remap::Failure::Error).and(
having_attributes(
failures: contain_exactly(
having_attributes(
value: "this is not a hash",
path: [:people, 1, :name]
)
)
failures: contain_exactly(having_attributes(path: [:people, 1], value: string))
)
)
)
Expand Down
5 changes: 3 additions & 2 deletions spec/feature/remap/failures/map_all_selector_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
failures: contain_exactly(
have_attributes(
value: { does_not_match: "with John" },
path: [:people, 0, :name]
reason: include("name"),
path: [:people, 0]
)
)
)
Expand All @@ -39,7 +40,7 @@
expect { |b| mapper.call(input, &b) }.to yield_with_args(
an_instance_of(Remap::Failure).and(
have_attributes(
failures: contain_exactly(have_attributes(value: input, path: [:people]))
failures: contain_exactly(have_attributes(value: input, path: []))
)
)
)
Expand Down
13 changes: 5 additions & 8 deletions spec/feature/remap/failures/nested_map_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,24 @@
it "invokes block with failure" do
expect { |b| mapper.call(input, &b) }.to yield_with_args(
have_attributes(
failures: contain_exactly(have_attributes(value: { age: 50 }, path: [:person, :name]))
failures: contain_exactly(have_attributes(value: { age: 50 }, path: [:person], reason: include("name")))
)
)
end
end

context "when key points to the wrong data type" do
let(:string) { "not a hash" }

let(:input) do
{ person: "hes 50 years old" }
{ person: string }
end

it "raises an exception" do
expect { mapper.call(input, &error) }.to raise_error(
an_instance_of(Remap::Failure::Error).and(
having_attributes(
failures: contain_exactly(
having_attributes(
value: "hes 50 years old",
path: [:person, :name]
)
)
failures: contain_exactly(having_attributes(path: [:person], value: string))
)
)
)
Expand Down
4 changes: 2 additions & 2 deletions spec/integration/remap/compiler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
end

let(:attributes) do
{ value: { mismatch: "John" }, path: [:person, :name] }
{ value: { mismatch: "John" }, path: [:person], reason: include("name") }
end
end
end
Expand Down Expand Up @@ -137,7 +137,7 @@
end

let(:attributes) do
{ value: { mismatch: "John" }, path: [:name] }
{ value: { mismatch: "John" }, path: [], reason: include("name") }
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/unit/remap/path/input_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
end

let(:attributes) do
{ value: input, path: selectors }
{ value: input, path: be_empty, reason: include("key") }
end
end
end
Expand Down Expand Up @@ -164,7 +164,7 @@
end

let(:attributes) do
{ path: [1], value: input }
{ path: [], value: input, reason: include("1") }
end
end
end
Expand Down
6 changes: 3 additions & 3 deletions spec/unit/remap/selector/index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
it_behaves_like "a fatal exception" do
let(:attributes) do
{
path: [index],
path: be_empty,
value: input
}
end
Expand Down Expand Up @@ -61,7 +61,7 @@

it_behaves_like "an ignored exception" do
let(:attributes) do
{ path: [index], value: input }
{ path: [], value: input, reason: include("4") }
end
end
end
Expand All @@ -79,7 +79,7 @@

it_behaves_like "an ignored exception" do
let(:attributes) do
{ path: [index], value: input }
{ path: [], value: input, reason: include("0") }
end
end
end
Expand Down

0 comments on commit 0cb820b

Please sign in to comment.