Last active
December 25, 2015 07:19
Revisions
-
mbj revised this gist
Oct 11, 2013 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -76,9 +76,9 @@ class Item evaluator = item.call(input) evaluator.success? # => true evaluator.output.class # => Item evaluator.output # => <Item @foo='a value for foo', @bar == 'a value for bar' # Inversible properties: item.inverse.call(Item.new(:foo => 'foo', :bar => 'bar')) # => { 'complex_name' => 'foo', 'bar' => 'bar' } -
mbj created this gist
Oct 11, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,450 @@ require 'ducktrap' # Very simple ducktrap without any real world use # # Not transforming. # string = Ducktrap.build do primitive(String) end evaluator = string.call("") evaluator.success? # => true evaluator.output # => "" evaluator = string.call(:foo) evaluator.success? # => false evaluator.output # => Ducktrap::Evaluator::Invalid # A composed example # # Not transforming. # ducktrap = Ducktrap.build do primitive(Array) # stupid dsl node name, must be replaced map do # using another ducktrap node here # # Equivalent to: # # primitive(String) # add(string) end end ducktrap.call([]).success? # => true ducktrap.call([""]).success? # => true ducktrap.call(nil).success? # => false ducktrap.call([nil]).success? # => false # A transforming example # Some PORO to map to class Item include Anima.new(:foo, :bar) end # Item item = Ducktrap.build do primitive(Hash) # Suboptimal dsl I know. hash_transform do # fetch_key => dump_key will be tranform_key(origin => target, origin2 => target2) in future fetch_key('complex_name') do primitive(String) dump_key(:foo) end fetch_key('bar') do primitive(String) dump_key(:bar) end end anima_load(Item) end input = { 'complex_name' => 'a value for foo', 'bar' => 'a value for bar' } evaluator = item.call(input) evaluator.success? # => true evaluator.class # => Item evaluator.output # => <Item @foo='a value for foo', @bar == 'a value for bar' # Inversible properties: item.inverse.call(Item.new(:foo => 'foo', :bar => 'bar')) # => { 'complex_name' => 'foo', 'bar' => 'bar' } # Round trippable on node level item.inverse.inverse == item # => true # Round trippable semantics item.inverse.inverse.call(input) == item.call(input) # => true # A composed transforming example: class SomeOtherItem include Anima.new(:items, :title) end some_other_item = Ducktrap.build do primitive(Hash) hash_transform do fetch_key('items') do map do add(item) end dump_key(:item) end fetch_key('title') do primitive(String) dump_key(:title) end end end input = { 'items' => [ { 'complex_name' => 'A complex name', 'bar' => 'A value for bar' }, { 'complex_name' => 'Another complex name', 'bar' => 'Another value for bar' } ], 'title' => 'A title' } evaluator = some_other_item.call(input) evaluator.success? # => true evaluator.output # => <SomeOtherItem @items=[<Item @foo='A complex name'> ....] @title='A title'> # Error behavior input = { 'items' => [ nil, # Note incompatible input here { 'complex_name' => 'A complex name', 'bar' => 'A value for bar' }, { 'complex_name' => 'Another complex name', 'bar' => 'Another value for bar' } ], 'title' => 'A title' } evaluator = some_other_item.call(input) evaluator.success? # => false # Precise error location here: evaluator.output # => #<Ducktrap::Error context=#<Ducktrap::Node::Hash::Transform::Evaluator context=#<Ducktr... # And pretty dumpable/inspectable of course :D # # Yeah this is TOO verbose. But guys this is a 0.0.1 version and many times more than a: # # NoMethodError: undefined method `each' for nil:NilClass # With a stacktrace NOT showing input data ;) # evaluator.output.pretty_dump # prints: # Ducktrap::Error # input: {"items"=>[nil, {"complex_name"=>"A complex name", "bar"=>"A value for bar"}, {"complex_name"=>"Another complex name", "bar"=>"Another value for bar"}], "title"=>"A title"} # context: # Ducktrap::Node::Hash::Transform::Evaluator # input: {"items"=>[nil, {"complex_name"=>"A complex name", "bar"=>"A value for bar"}, {"complex_name"=>"Another complex name", "bar"=>"Another value for bar"}], "title"=>"A title"} # error: # Ducktrap::Error # input: {"items"=>[nil, {"complex_name"=>"A complex name", "bar"=>"A value for bar"}, {"complex_name"=>"Another complex name", "bar"=>"Another value for bar"}], "title"=>"A title"} # context: # Ducktrap::Node::Key::Fetch::Evaluator # input: {"items"=>[nil, {"complex_name"=>"A complex name", "bar"=>"A value for bar"}, {"complex_name"=>"Another complex name", "bar"=>"Another value for bar"}], "title"=>"A title"} # error: # Ducktrap::Error # input: {"items"=>[nil, {"complex_name"=>"A complex name", "bar"=>"A value for bar"}, {"complex_name"=>"Another complex name", "bar"=>"Another value for bar"}], "title"=>"A title"} # context: # Ducktrap::Node::Block::Evaluator # input: [nil, {"complex_name"=>"A complex name", "bar"=>"A value for bar"}, {"complex_name"=>"Another complex name", "bar"=>"Another value for bar"}] # error: # Ducktrap::Error # input: [nil, {"complex_name"=>"A complex name", "bar"=>"A value for bar"}, {"complex_name"=>"Another complex name", "bar"=>"Another value for bar"}] # context: # Ducktrap::Node::Map::Evaluator # input: [nil, {"complex_name"=>"A complex name", "bar"=>"A value for bar"}, {"complex_name"=>"Another complex name", "bar"=>"Another value for bar"}] # error: # Ducktrap::Error # input: [nil, {"complex_name"=>"A complex name", "bar"=>"A value for bar"}, {"complex_name"=>"Another complex name", "bar"=>"Another value for bar"}] # context: # Ducktrap::Node::Block::Evaluator # input: nil # error: # Ducktrap::Error # input: nil # context: # Ducktrap::Node::Block::Evaluator # input: nil # error: # Ducktrap::Error # input: nil # context: # Ducktrap::Evaluator::Invalid # input: nil # error: # Ducktrap::Error # input: nil # context: # Ducktrap::Node::Primitive # primitive: Hash # context: # Ducktrap::Node::Primitive # primitive: Hash # context: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: Hash # Ducktrap::Node::Hash::Transform # body: # Ducktrap::Node::Key::Fetch # key: "complex_name" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :foo # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Key::Fetch # key: "bar" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :bar # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Anima::Load # model: Item # context: # Ducktrap::Node::Block # body: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: Hash # Ducktrap::Node::Hash::Transform # body: # Ducktrap::Node::Key::Fetch # key: "complex_name" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :foo # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Key::Fetch # key: "bar" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :bar # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Anima::Load # model: Item # context: # Ducktrap::Node::Map # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: Hash # Ducktrap::Node::Hash::Transform # body: # Ducktrap::Node::Key::Fetch # key: "complex_name" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :foo # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Key::Fetch # key: "bar" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :bar # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Anima::Load # model: Item # context: # Ducktrap::Node::Block # body: # Ducktrap::Node::Map # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: Hash # Ducktrap::Node::Hash::Transform # body: # Ducktrap::Node::Key::Fetch # key: "complex_name" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :foo # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Key::Fetch # key: "bar" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :bar # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Anima::Load # model: Item # Ducktrap::Node::Key::Dump # key: :item # operand: # Ducktrap::Node::Noop # context: # Ducktrap::Node::Key::Fetch # key: "items" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Map # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: Hash # Ducktrap::Node::Hash::Transform # body: # Ducktrap::Node::Key::Fetch # key: "complex_name" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :foo # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Key::Fetch # key: "bar" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :bar # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Anima::Load # model: Item # Ducktrap::Node::Key::Dump # key: :item # operand: # Ducktrap::Node::Noop # context: # Ducktrap::Node::Hash::Transform # body: # Ducktrap::Node::Key::Fetch # key: "items" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Map # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: Hash # Ducktrap::Node::Hash::Transform # body: # Ducktrap::Node::Key::Fetch # key: "complex_name" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :foo # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Key::Fetch # key: "bar" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :bar # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Anima::Load # model: Item # Ducktrap::Node::Key::Dump # key: :item # operand: # Ducktrap::Node::Noop # Ducktrap::Node::Key::Fetch # key: "title" # operand: # Ducktrap::Node::Block # body: # Ducktrap::Node::Primitive # primitive: String # Ducktrap::Node::Key::Dump # key: :title # operand: # Ducktrap::Node::Noop