metaphor 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2009 Sean O'Halpin
4
+ Copyright (c) 2010 Craig R Webster <http://barkingiguana.com/>
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ 'Software'), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,92 @@
1
+ Metaphor
2
+ ========
3
+
4
+ From the Greek: μεταφορά - metaphora, meaning "transfer"
5
+
6
+
7
+ Rationale
8
+ ---------
9
+
10
+ As programmers an awful lot of what we do revolves around taking an
11
+ input, doing something to it, and sending the result somewhere. Quite a
12
+ bit of time is wasted writing the "glue" that transfers the results from
13
+ one place to the next. Metaphor aims to provide a standardised and easy
14
+ to use way of passing results, leaving you to concentrate on the bit
15
+ that's important - the business logic.
16
+
17
+
18
+ Programming with Metaphor
19
+ -------------------------
20
+
21
+ metaphor = Metaphor.new
22
+ metaphor.processors << Foo.new
23
+ metaphor.processors << Bar.new
24
+ metaphor.processors << Baz.new
25
+ metaphor.processors << Metaphor::Processor::PrintMessage.new
26
+
27
+ # Process one message
28
+ metaphor.call(headers, body) # => [ new_headers, new_body ]
29
+ # => false (if halted by processor)
30
+
31
+ # Process messages from this class until the Ruby VM is killed or the
32
+ # input returns nil
33
+ metaphor.call(StdinInput.new)
34
+
35
+
36
+ Classes used for input must respond to #get and return an array of headers
37
+ and the message body:
38
+
39
+ class StdinInput
40
+ def get
41
+ # return an array like this:
42
+ [
43
+ { "header" => "value", ... }, # Message headers
44
+ "body" # Message body
45
+ ]
46
+ end
47
+ end
48
+
49
+ Classes used as processors must respond to #call(headers, body):
50
+
51
+ class PrintMessage
52
+ def call(headers, body)
53
+ puts "Headers: #{headers.inspect}"
54
+ puts "Body : #{body.inspect}"
55
+ end
56
+ end
57
+
58
+ The return value of #call controls what happens to the message. If the
59
+ processor returns:
60
+
61
+ * An array of headers and the message body
62
+ - they are passed to the next processor
63
+ * Boolean false (or something that is === to it)
64
+ - Metaphor stops processing this message and discards it
65
+ * Any other value that is not false
66
+ - Metaphor passes the same headers and message that were passed into
67
+ this processor to the next processor in the chain
68
+
69
+ Contributing
70
+ ------------
71
+
72
+ * Fork the project.
73
+ * Make your feature addition or bug fix.
74
+ * Add tests for it. This is important so I don't break it in a
75
+ future version unintentionally.
76
+ * Commit, do not mess with the Rakefile or Metaphor::VERSION. If you
77
+ want to have your own version, that is fine but bump version in a
78
+ commit by itself I can ignore when I pull.
79
+ * Send me a pull request. Bonus points for topic branches.
80
+
81
+
82
+ Authors
83
+ -------
84
+
85
+ * Sean O'Halpin
86
+ * Craig R Webster <http://barkingiguana.com/>
87
+
88
+
89
+ License
90
+ -------
91
+
92
+ Released under the MIT licence. See the LICENSE file for details.
@@ -0,0 +1,33 @@
1
+ class Metaphor
2
+ VERSION = '0.2.1'
3
+ attr_accessor :processors
4
+
5
+ def initialize
6
+ self.processors = []
7
+ end
8
+
9
+ def call(*args)
10
+ case args.size
11
+ when 1
12
+ while message = args.first.get
13
+ process_message(*message)
14
+ end
15
+ when 2
16
+ process_message(*args)
17
+ end
18
+ end
19
+
20
+ private
21
+ def process_message(headers, body)
22
+ processors.each do |processor|
23
+ processor_output = processor.call(headers, body)
24
+ case
25
+ when processor_output === false
26
+ return false
27
+ when processor_output.respond_to?(:size) && processor_output.size == 2
28
+ headers, body = processor_output
29
+ end
30
+ end
31
+ [ headers, body ]
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ class Metaphor
2
+ module Input
3
+ class StdinInput
4
+ def initialize(source = STDIN, prompt = STDOUT)
5
+ @source = source
6
+ @prompt = prompt
7
+ end
8
+
9
+ def get
10
+ @prompt.puts "Enter headers in the format header:value."
11
+ @prompt.puts "Each header:value pair should be followed by a newline."
12
+ @prompt.puts "When you're done enter a blank line."
13
+ headers = {}
14
+ loop do
15
+ line = @source.readline.to_s.strip
16
+ break if line == ""
17
+ header, value = line.split(/:/, 2).map{|s|s.strip}
18
+ headers[header] = value
19
+ end
20
+
21
+ @prompt.puts "Enter the message body."
22
+ @prompt.puts "When you're done enter a blank line."
23
+ body = []
24
+ loop do
25
+ line = @source.readline.to_s.strip
26
+ break if line == ""
27
+ body << line
28
+ end
29
+
30
+ [ headers, body.join("\n") ]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ class Metaphor
2
+ module Processor
3
+ class Detour
4
+ def initialize(default, detour)
5
+ @default = default
6
+ @detour = Metaphor.new
7
+ @detour.processors << detour
8
+ @detour.processors << default
9
+ @active = false
10
+ end
11
+
12
+ def activate
13
+ @active = true
14
+ end
15
+
16
+ def deactivate
17
+ @active = false
18
+ end
19
+
20
+ def active?
21
+ @active
22
+ end
23
+
24
+ def call(headers, body)
25
+ active_processor.call headers, body
26
+ end
27
+
28
+ private
29
+ def active_processor
30
+ (@active ? @detour : @default)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ class Metaphor
2
+ module Processor
3
+ class JsonProcessor
4
+ def initialize
5
+ require 'json'
6
+ end
7
+
8
+ def call(headers, body)
9
+ result = JSON[body]
10
+ headers['content-type'] = case result
11
+ when Hash: 'application/x-ruby'
12
+ when String: 'application/json'
13
+ end
14
+ [ headers, result ]
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ class Metaphor
2
+ module Processor
3
+ class PrintMessage
4
+ def initialize(target = STDOUT)
5
+ @target = target
6
+ end
7
+
8
+ def call(headers, body)
9
+ headers.each_pair do |header, value|
10
+ @target.puts "#{header}:#{value}"
11
+ end
12
+ @target.puts
13
+ @target.puts body
14
+ @target.puts
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ class Metaphor
2
+ module Processor
3
+ class Wiretap
4
+ def initialize(default, wiretap)
5
+ @default = default
6
+ @wiretap = wiretap
7
+ @active = false
8
+ end
9
+
10
+ def active?
11
+ @active
12
+ end
13
+
14
+ def activate
15
+ @active = true
16
+ end
17
+
18
+ def deactivate
19
+ @active = false
20
+ end
21
+
22
+ def call(headers, body)
23
+ @wiretap.call(headers, body) if active?
24
+ @default.call(headers, body)
25
+ end
26
+ end
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: metaphor
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 1
10
+ version: 0.2.1
11
+ platform: ruby
12
+ authors:
13
+ - Sean O'Halpin
14
+ - Craig R Webster
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-08-20 00:00:00 +01:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description: Metaphor provides a standard interface for defining message processors and transformations and a simple framework for executing them.
24
+ email:
25
+ - craig@barkingiguana.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - lib/metaphor/input/stdin_input.rb
34
+ - lib/metaphor/processor/detour.rb
35
+ - lib/metaphor/processor/json_processor.rb
36
+ - lib/metaphor/processor/print_message.rb
37
+ - lib/metaphor/processor/wiretap.rb
38
+ - lib/metaphor.rb
39
+ - LICENSE
40
+ - README.markdown
41
+ has_rdoc: true
42
+ homepage: http://github.com/seanohalpin/metaphor
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 23
65
+ segments:
66
+ - 1
67
+ - 3
68
+ - 6
69
+ version: 1.3.6
70
+ requirements: []
71
+
72
+ rubyforge_project: metaphor
73
+ rubygems_version: 1.3.7
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Generic pipeline processing
77
+ test_files: []
78
+