proc 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a33f3939a8156059653e7edde57a9ac0b0ee46ab04bcb1f08ce098073e884358
4
- data.tar.gz: df8c021333f0f03b6acdaa195b2c39035a4054b026fd1f6c09d08df674aef7f9
3
+ metadata.gz: 0f07ae5d056122c93826012896beb760372534d7c2c83193674580517ff31f86
4
+ data.tar.gz: 5cd335938ec4121d5170c27518678d81c27dd3b65ff6b0235be72213e05613e2
5
5
  SHA512:
6
- metadata.gz: 52107c5f8c68d623aead4dab7131fe7ea42c5abc29bf748cb81f2aea80bc0ae2b68447764c02a1d40aca4a21e24521f2bc291e9ae7794bd69d98cb867c7f0959
7
- data.tar.gz: 8bcab50d65564adb5ce355b75dd407f82ccf93dee798c1219def178293978251b6bfff6c588a823eecd52732a6784a971226026f796601941f1866d3d0c00035
6
+ metadata.gz: '08b92c4b033fe05dea3a0db6321c5cea4ce5f8ce3587e3f1b7902b295e7778f95a433e84652f12d71f3eff0e60d2bc53d584cce308bd307e32b54f76ed3213e3'
7
+ data.tar.gz: ef90d03381df7f8f016460cc83f15c14b3b1f9768dd5078588e85591e61d46df628fd63fd7e804d6d7e1975c7dd9749642f4b51ecaa5bf1e7c19896f64155d72
data/README.md CHANGED
@@ -0,0 +1,80 @@
1
+ The `proc` gem lets you call codeless web functions through the proc.dev service.
2
+
3
+ ## Getting Started
4
+
5
+ Install `proc` using the `gem` command from the command line:
6
+
7
+ ```
8
+ gem install proc
9
+ ```
10
+
11
+ You will also need a proc.dev account. Create a free account in seconds at [proc.dev](https://proc.dev/).
12
+
13
+ ## Connecting
14
+
15
+ Sign in to your proc.dev account and locate your secret key. Use the secret to create a client connection:
16
+
17
+ ```ruby
18
+ client = Proc.connect("secret-key")
19
+ ```
20
+
21
+ ## Calling Procs
22
+
23
+ You can call available procs through a connected client:
24
+
25
+ ```ruby
26
+ client.core.string.reverse.call("hello")
27
+ => "olleh"
28
+ ```
29
+
30
+ Requests are sent to proc.dev anytime the `call` method is invoked.
31
+
32
+ ## Callable Contexts
33
+
34
+ Proc lookups create contexts that can be called later:
35
+
36
+ ```ruby
37
+ string = client.core.string
38
+
39
+ string.reverse.call("hello")
40
+ => "olleh"
41
+
42
+ string.truncate.call("hello", length: 3)
43
+ => "hel"
44
+ ```
45
+
46
+ Contexts can be configured with default input and arguments using the `with` method:
47
+
48
+ ```ruby
49
+ truncate = client.core.string.truncate.with("default", length: 1)
50
+
51
+ truncate.call
52
+ => "d"
53
+ ```
54
+
55
+ Default input and/or arguments can be overidden for a specific call:
56
+
57
+ ```ruby
58
+ truncate.call(length: 3)
59
+ => "def"
60
+ ```
61
+
62
+ Procs can also be looked up using the hash key syntax:
63
+
64
+ ```ruby
65
+ client["core.string.truncate"].call("hello", length: 3)
66
+ => "hel"
67
+ ```
68
+
69
+ ## Compositions
70
+
71
+ Procs can be composed together to build more complex behavior:
72
+
73
+ ```ruby
74
+ composition = client.core.string.reverse >> client.core.string.truncate(length: 3) >> client.core.string.capitalize
75
+
76
+ composition.call("hello")
77
+ => "Oll"
78
+ ```
79
+
80
+ Compositions are sent to proc.dev in a single request.
@@ -2,15 +2,26 @@
2
2
 
3
3
  class Proc
4
4
  class Callable
5
- attr_reader :proc
5
+ attr_reader :proc, :input, :arguments
6
6
 
7
- def initialize(proc, client:)
7
+ def initialize(proc, client:, input: nil, arguments: {})
8
8
  @proc = proc
9
9
  @client = client
10
+ @input = input
11
+ @arguments = arguments
10
12
  end
11
13
 
12
- def call(input = nil, **arguments)
13
- @client.call(@proc, input, **arguments)
14
+ def initialize_copy(_)
15
+ @input = input.dup
16
+ @arguments = arguments.dup
17
+ end
18
+
19
+ def call(input = input_omitted = true, **arguments)
20
+ @client.call(@proc, input_omitted ? @input : input, **@arguments.merge(arguments))
21
+ end
22
+
23
+ def with(input = input_omitted = true, **arguments)
24
+ self.class.new(@proc, client: @client, input: input_omitted ? @input : input, arguments: @arguments.merge(arguments))
14
25
  end
15
26
 
16
27
  def >>(other)
@@ -19,5 +30,51 @@ class Proc
19
30
  composed << other
20
31
  composed
21
32
  end
33
+
34
+ def serialize
35
+ {
36
+ "{}" => {
37
+ "<<" => serialize_value(@input),
38
+ "[]" => [[@proc, serialized_arguments]]
39
+ }
40
+ }
41
+ end
42
+
43
+ def serialized_arguments
44
+ @arguments.each_pair.each_with_object({}) { |(key, value), hash|
45
+ hash[key.to_s] = serialize_value(value)
46
+ }
47
+ end
48
+
49
+ IGNORE_MISSING = %i[to_hash].freeze
50
+
51
+ def method_missing(name, input = input_omitted = true, **arguments)
52
+ if IGNORE_MISSING.include?(name)
53
+ super
54
+ else
55
+ Callable.new(
56
+ [@proc, name].join("."),
57
+ client: @client,
58
+ input: input_omitted ? @input : input,
59
+ arguments: @arguments.merge(arguments)
60
+ )
61
+ end
62
+ end
63
+
64
+ def respond_to_missing?(name, *)
65
+ if IGNORE_MISSING.include?(name)
66
+ super
67
+ else
68
+ true
69
+ end
70
+ end
71
+
72
+ private def serialize_value(value)
73
+ if value.respond_to?(:serialize)
74
+ value.serialize
75
+ else
76
+ value
77
+ end
78
+ end
22
79
  end
23
80
  end
@@ -60,9 +60,6 @@ class Proc
60
60
  @resets_at
61
61
  end
62
62
 
63
- def compose(&block)
64
- Composition.new(client: self, &block)
65
- end
66
63
 
67
64
  DEFAULT_HEADERS = {
68
65
  "accept" => "application/json",
@@ -71,14 +68,10 @@ class Proc
71
68
 
72
69
  def call(proc = nil, input = nil, **arguments)
73
70
  Async(logger: NullLogger) { |task|
74
- body = { "<<" => input }
71
+ body = { "<<" => serialize_value(input) }
75
72
 
76
73
  arguments.each_pair do |key, value|
77
- body[key.to_s] = if value.respond_to?(:serialize)
78
- value.serialize
79
- else
80
- value
81
- end
74
+ body[key.to_s] = serialize_value(value)
82
75
  end
83
76
 
84
77
  headers = {
@@ -119,10 +112,26 @@ class Proc
119
112
  }.wait
120
113
  end
121
114
 
115
+ def method_missing(name, input = nil, **arguments)
116
+ Callable.new(name, client: self, input: input, arguments: arguments)
117
+ end
118
+
119
+ def respond_to_missing?(name, *)
120
+ true
121
+ end
122
+
122
123
  private def build_uri(proc)
123
124
  host_and_path = File.join(@host, proc.to_s.split(".").join("/"))
124
125
 
125
126
  "#{@scheme}://#{host_and_path}"
126
127
  end
128
+
129
+ private def serialize_value(value)
130
+ if value.respond_to?(:serialize)
131
+ value.serialize
132
+ else
133
+ value
134
+ end
135
+ end
127
136
  end
128
137
  end
@@ -2,12 +2,8 @@
2
2
 
3
3
  class Proc
4
4
  class Composition
5
- require_relative "composition/deferable"
6
- require_relative "composition/evaluator"
7
-
8
- def initialize(client:, &block)
5
+ def initialize(client:)
9
6
  @client = client
10
- @block = block
11
7
  @callables = []
12
8
  end
13
9
 
@@ -15,10 +11,8 @@ class Proc
15
11
  @callables = @callables.dup
16
12
  end
17
13
 
18
- def call(input = nil, **arguments)
19
- # TODO: This will probably call `proc.run`.
20
- #
21
- @client.call("compose", input, proc: build_evaluator(**arguments))
14
+ def call(input = input_omitted = true, **arguments)
15
+ @client.call("exec", input_omitted ? @callables.first.input : input, proc: serialize)
22
16
  end
23
17
 
24
18
  def >>(other)
@@ -31,28 +25,10 @@ class Proc
31
25
  @callables << callable
32
26
  end
33
27
 
34
- def with(**arguments)
35
- build_evaluator(**arguments)
36
- end
37
-
38
28
  def serialize
39
- build_evaluator.serialize
40
- rescue ::ArgumentError => error
41
- raise ::ArgumentError, error.message + " (try using `with' to build a composition with arguments)"
42
- end
43
-
44
- private def build_evaluator(**arguments)
45
- evaluator = if @block
46
- @block.call(Evaluator.new, **arguments)
47
- else
48
- Evaluator.new
49
- end
50
-
51
- @callables.each do |callable|
52
- evaluator << Deferable.new(callable.proc)
53
- end
54
-
55
- evaluator
29
+ @callables.map { |callable|
30
+ [callable.proc, callable.serialized_arguments]
31
+ }
56
32
  end
57
33
  end
58
34
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Proc
4
- VERSION = "0.0.4"
4
+ VERSION = "0.1.0"
5
5
 
6
6
  def self.version
7
7
  VERSION
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Powell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-24 00:00:00.000000000 Z
11
+ date: 2020-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-http
@@ -50,8 +50,6 @@ files:
50
50
  - lib/proc/callable.rb
51
51
  - lib/proc/client.rb
52
52
  - lib/proc/composition.rb
53
- - lib/proc/composition/deferable.rb
54
- - lib/proc/composition/evaluator.rb
55
53
  - lib/proc/http/client.rb
56
54
  - lib/proc/http/request.rb
57
55
  - lib/proc/http/response.rb
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Proc
4
- class Composition
5
- class Deferable
6
- attr_reader :proc
7
- attr_writer :arguments
8
-
9
- def initialize(proc)
10
- @proc = proc
11
- @arguments = {}
12
- end
13
-
14
- def serialize
15
- [@proc, serialized_arguments]
16
- end
17
-
18
- private def serialized_arguments
19
- @arguments.each.each_with_object({}) do |(key, value), hash|
20
- hash[key] = if value.respond_to?(:serialize)
21
- value.serialize
22
- else
23
- value
24
- end
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Proc
4
- class Composition
5
- class Evaluator
6
- attr_reader :callables
7
-
8
- def initialize
9
- @callables = []
10
- end
11
-
12
- def initialize_copy(_)
13
- @callables = @callables.map(&:dup)
14
- end
15
-
16
- def [](proc)
17
- evaluator = dup
18
- evaluator << Deferable.new(proc)
19
- evaluator
20
- end
21
-
22
- def <<(proc)
23
- @callables << proc
24
- end
25
-
26
- def >>(other)
27
- evaluator = dup
28
-
29
- case other
30
- when Evaluator
31
- other.callables.each do |each_callable|
32
- evaluator << each_callable
33
- end
34
- when Callable
35
- evaluator << Deferable.new(other.proc)
36
- end
37
-
38
- evaluator
39
- end
40
-
41
- def call(**arguments)
42
- evaluator = dup
43
- evaluator.callables.last.arguments = arguments
44
- evaluator
45
- end
46
-
47
- def serialize
48
- { "[]" => @callables.map(&:serialize) }
49
- end
50
- end
51
- end
52
- end