code-ruby 0.7.7 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d84bcfcb9ae6cbd546334c89b2aefd5a0b70bf4da537d0fe646c5f2a8030c4a3
4
- data.tar.gz: d9894a0ee1a9c80fa1744b4b29c3b8065c6dedd310558d0f4210f252f5f330a2
3
+ metadata.gz: efd32092c4583410121731e5e6a0300001ef215812e690b0a3fe3c280f0cf84e
4
+ data.tar.gz: b7a88bce4d570b5c9156e79fe5a684f8e945a18faca8a3ecfb242b8ca720d96f
5
5
  SHA512:
6
- metadata.gz: f18605e6c94eccb892d45d09dddb06cf4f5fba5f2f1f30df077687812424ea97c0fde6c3c53f80bc075dfc362864307d17ef354ed5f45997c9ccc42faeb44658
7
- data.tar.gz: 1333842f223896c4bff55a2359034420631680bfe6d2563458b1dc6546e95e7c1d50b42b577396866f3770592bc574b616aaf48d32acda843d80997a4179bb09
6
+ metadata.gz: 2d047f84b6ddb2ac77b8154692089eea38f02a6e4d8b7a46b2e2334594d9a00178dcdfa4b649c82267178c7a681ccd3874685b19c5a8c531c7fb72b7ce5e3189
7
+ data.tar.gz: df9dd8a546339658b3efa419685559981b20aba4b3e7a48e52a580cae0dabc7e19e5691efabdd4591f89ed0525358b557947cf0a744eee52d59297722ef059a2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- code-ruby (0.7.6)
4
+ code-ruby (0.7.8)
5
5
  activesupport (~> 7)
6
6
  bigdecimal (~> 3)
7
7
  language-ruby (~> 0)
@@ -9,6 +9,18 @@ class Code
9
9
  @raw = raw
10
10
  end
11
11
 
12
+ def call(...)
13
+ raw.call(...)
14
+ end
15
+
16
+ def to_s
17
+ raw.name
18
+ end
19
+
20
+ def inspect
21
+ to_s
22
+ end
23
+
12
24
  def self.name
13
25
  "Class"
14
26
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Code
4
+ class Object
5
+ class Date < Object
6
+ attr_reader :raw
7
+
8
+ def initialize(date)
9
+ @raw = date
10
+ end
11
+
12
+ def self.name
13
+ "Date"
14
+ end
15
+
16
+ def self.call(**args)
17
+ operator = args.fetch(:operator, nil)
18
+
19
+ case operator.to_s
20
+ when "tomorrow"
21
+ sig(args)
22
+ code_tomorrow
23
+ else
24
+ super
25
+ end
26
+ end
27
+
28
+ def self.code_tomorrow
29
+ ::Time.zone ||= Time::DEFAULT_ZONE
30
+ new(::Time.zone.tomorrow)
31
+ end
32
+
33
+ def inspect
34
+ to_s
35
+ end
36
+
37
+ def to_s
38
+ raw.to_s
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/numeric/time"
4
-
5
3
  class Code
6
4
  class Object
7
5
  class Duration < Object
@@ -22,6 +22,9 @@ class Code
22
22
  when "Class"
23
23
  sig(args) { Object.maybe }
24
24
  value ? value.code_to_class : Class.new(Class)
25
+ when "Date"
26
+ sig(args) { Object.maybe }
27
+ value ? value.code_to_date : Class.new(Date)
25
28
  when "Decimal"
26
29
  sig(args) { Object.maybe }
27
30
  value ? value.code_to_decimal : Class.new(Decimal)
@@ -55,6 +58,9 @@ class Code
55
58
  when "String"
56
59
  sig(args) { Object.maybe }
57
60
  value ? value.code_to_string : Class.new(String)
61
+ when "Time"
62
+ sig(args) { Object.maybe }
63
+ value ? value.code_to_time : Class.new(Time)
58
64
  when "context"
59
65
  sig(args) { String.maybe }
60
66
  value ? context.code_get(value) || Nothing.new : context
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/numeric/time"
4
-
5
3
  class Code
6
4
  class Object
7
5
  class Integer < Number
@@ -3,6 +3,8 @@
3
3
  class Code
4
4
  class Object
5
5
  class Time < Object
6
+ DEFAULT_ZONE = "Etc/UTC"
7
+
6
8
  attr_reader :raw
7
9
 
8
10
  def initialize(time)
@@ -13,6 +15,23 @@ class Code
13
15
  "Time"
14
16
  end
15
17
 
18
+ def self.call(**args)
19
+ operator = args.fetch(:operator, nil)
20
+
21
+ case operator.to_s
22
+ when "tomorrow"
23
+ sig(args)
24
+ code_tomorrow
25
+ else
26
+ super
27
+ end
28
+ end
29
+
30
+ def self.code_tomorrow
31
+ ::Time.zone ||= DEFAULT_ZONE
32
+ new(::Time.zone.tomorrow.beginning_of_day)
33
+ end
34
+
16
35
  def inspect
17
36
  to_s
18
37
  end
data/lib/code/object.rb CHANGED
@@ -18,6 +18,151 @@ class Code
18
18
  Type::Or.new(self, other)
19
19
  end
20
20
 
21
+ def self.sig(args, &block)
22
+ Type::Sig.sig(args, object: self, &block)
23
+ end
24
+
25
+ def self.call(**args)
26
+ operator = args.fetch(:operator, nil)
27
+ arguments = args.fetch(:arguments, [])
28
+ value = arguments.first&.value
29
+
30
+ case operator.to_s
31
+ when "!", "not"
32
+ sig(args)
33
+ code_exclamation_point
34
+ when "!=", "different"
35
+ sig(args) { Object }
36
+ code_different(value)
37
+ when "&&", "and"
38
+ sig(args) { Object }
39
+ code_and_operator(value)
40
+ when "+", "self"
41
+ sig(args)
42
+ code_self
43
+ when "..", "inclusive_range"
44
+ sig(args) { Object }
45
+ code_inclusive_range(value)
46
+ when "...", "exclusive_range"
47
+ sig(args) { Object }
48
+ code_exclusive_range(value)
49
+ when "==", "equal"
50
+ sig(args) { Object }
51
+ code_equal_equal(value)
52
+ when "===", "strict_equal"
53
+ sig(args) { Object }
54
+ code_equal_equal_equal(value)
55
+ when "falsy?"
56
+ sig(args)
57
+ Boolean.new(falsy?)
58
+ when "to_string"
59
+ sig(args)
60
+ code_to_string
61
+ when "truthy?"
62
+ sig(args)
63
+ Boolean.new(truthy?)
64
+ when "||", "or"
65
+ sig(args) { Object }
66
+ code_or_operator(value)
67
+ when /=$/
68
+ sig(args) { Object }
69
+
70
+ if operator == "="
71
+ context = args[:context]
72
+ context.code_set(self, value)
73
+ else
74
+ context = args[:context].lookup!(self)
75
+ context.code_set(
76
+ self,
77
+ context.code_fetch(self).call(
78
+ **args,
79
+ operator: operator[..-2],
80
+ arguments: [Argument.new(value)]
81
+ )
82
+ )
83
+ end
84
+
85
+ context.code_fetch(self)
86
+ else
87
+ raise(
88
+ Code::Error::Undefined,
89
+ "#{operator} not defined on #{inspect}:#{name}"
90
+ )
91
+ end
92
+ end
93
+
94
+ def self.code_and_operator(other)
95
+ truthy? ? other : self
96
+ end
97
+
98
+ def self.code_different(other)
99
+ Boolean.new(self != other)
100
+ end
101
+
102
+ def self.code_equal_equal(other)
103
+ Boolean.new(self == other)
104
+ end
105
+
106
+ def self.code_exclamation_point
107
+ Boolean.new(falsy?)
108
+ end
109
+
110
+ def self.code_exclusive_range(value)
111
+ Range.new(self, value, exclude_end: true)
112
+ end
113
+
114
+ def self.code_inclusive_range(value)
115
+ Range.new(self, value, exclude_end: false)
116
+ end
117
+
118
+ def self.code_or_operator(other)
119
+ truthy? ? self : other
120
+ end
121
+
122
+ def self.code_self
123
+ self
124
+ end
125
+
126
+ def self.code_equal_equal_equal(other)
127
+ Boolean.new(self === other)
128
+ end
129
+
130
+ def self.code_to_string
131
+ String.new(to_s)
132
+ end
133
+
134
+ def self.falsy?
135
+ !truthy?
136
+ end
137
+
138
+ def self.hash
139
+ unless respond_to?(:raw)
140
+ raise NotImplementedError, "#{self.class.name}#hash"
141
+ end
142
+
143
+ [self.class, raw].hash
144
+ end
145
+
146
+ def self.multi_fetch(hash, *keys)
147
+ keys.map { |key| [key, hash.fetch(key)] }.to_h
148
+ end
149
+
150
+ def self.sig(args, &block)
151
+ Type::Sig.sig(args, object: self, &block)
152
+ end
153
+
154
+ def self.name
155
+ raise NotImplementedError, "name"
156
+ end
157
+
158
+ def self.to_s
159
+ name
160
+ end
161
+
162
+ def self.truthy?
163
+ true
164
+ end
165
+
21
166
  def <=>(other)
22
167
  if respond_to?(:raw)
23
168
  raw <=> (other.respond_to?(:raw) ? other.raw : other)
@@ -117,7 +262,7 @@ class Code
117
262
  end
118
263
 
119
264
  def code_exclamation_point
120
- truthy? ? Object::Boolean.new(false) : Object::Boolean.new(true)
265
+ Boolean.new(falsy?)
121
266
  end
122
267
 
123
268
  def code_exclusive_range(value)
data/lib/code/version.rb CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require_relative "../code"
4
4
 
5
- Code::Version = Gem::Version.new("0.7.7")
5
+ Code::Version = Gem::Version.new("0.8.0")
data/lib/code-ruby.rb CHANGED
@@ -6,6 +6,8 @@ require "timeout"
6
6
  require "zeitwerk"
7
7
  require "language-ruby"
8
8
  require "active_support"
9
+ require "active_support/core_ext/numeric/time"
10
+ require "active_support/core_ext/date/conversions"
9
11
 
10
12
  loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
11
13
  loader.ignore("#{__dir__}/code-ruby.rb")
data/spec/code_spec.rb CHANGED
@@ -190,7 +190,11 @@ RSpec.describe Code do
190
190
  ).to eq(Code.evaluate("[:Hello]"))
191
191
  end
192
192
 
193
- it "works with time" do
194
- Code.evaluate("1.hour.from_now")
193
+ [
194
+ "1.hour.from_now",
195
+ "Time.tomorrow",
196
+ "Date.tomorrow"
197
+ ].each do |input|
198
+ it(input) { Code.evaluate(input) }
195
199
  end
196
200
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.7
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dorian Marié
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-12 00:00:00.000000000 Z
11
+ date: 2024-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -118,6 +118,7 @@ files:
118
118
  - lib/code/object/boolean.rb
119
119
  - lib/code/object/class.rb
120
120
  - lib/code/object/context.rb
121
+ - lib/code/object/date.rb
121
122
  - lib/code/object/decimal.rb
122
123
  - lib/code/object/dictionary.rb
123
124
  - lib/code/object/duration.rb