rider-server 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.build.yml +3 -3
- data/CHANGELOG.md +23 -1
- data/COPYING +20 -0
- data/README.rdoc +39 -0
- data/Rakefile +5 -0
- data/exe/rider-server +3 -3
- data/lib/rider_server/config.rb +76 -0
- data/lib/rider_server/core_ext/array.rb +3 -1
- data/lib/rider_server/core_ext/class.rb +5 -0
- data/lib/rider_server/core_ext/env.rb +14 -0
- data/lib/rider_server/core_ext/hash.rb +3 -1
- data/lib/rider_server/core_ext/kernel.rb +5 -0
- data/lib/rider_server/core_ext/module.rb +18 -0
- data/lib/rider_server/core_ext/object.rb +7 -1
- data/lib/rider_server/core_ext/string.rb +3 -1
- data/lib/rider_server/core_ext/symbol.rb +3 -1
- data/lib/rider_server/exception_extension.rb +2 -0
- data/lib/rider_server/inspect.rb +115 -43
- data/lib/rider_server/logger.rb +11 -4
- data/lib/rider_server/operation.rb +39 -20
- data/lib/rider_server/{ops → operations}/clone.rb +3 -2
- data/lib/rider_server/{ops → operations}/close.rb +3 -2
- data/lib/rider_server/operations/completions.rb +146 -0
- data/lib/rider_server/operations/lookup.rb +102 -0
- data/lib/rider_server/operations/ls_sessions.rb +51 -0
- data/lib/rider_server/operations/toggle_catch_all_exceptions.rb +24 -0
- data/lib/rider_server/operations.rb +43 -69
- data/lib/rider_server/request.rb +61 -0
- data/lib/rider_server/response.rb +10 -2
- data/lib/rider_server/server.rb +29 -17
- data/lib/rider_server/services/capture_exceptions.rb +18 -2
- data/lib/rider_server/services/rails.rb +1 -1
- data/lib/rider_server/session.rb +77 -34
- data/lib/rider_server/session_operation.rb +17 -0
- data/lib/rider_server/session_operations/eval.rb +61 -0
- data/lib/rider_server/session_operations/inspect.rb +123 -0
- data/lib/rider_server/session_operations/inspect_exception.rb +46 -0
- data/lib/rider_server/session_operations/interrupt.rb +29 -0
- data/lib/rider_server/session_operations/load_path.rb +19 -0
- data/lib/rider_server/session_operations/ls_exceptions.rb +28 -0
- data/lib/rider_server/session_operations/ls_services.rb +18 -0
- data/lib/rider_server/session_operations/service.rb +42 -0
- data/lib/rider_server/session_operations/set_namespace.rb +82 -0
- data/lib/rider_server/session_operations/set_namespace_variable.rb +81 -0
- data/lib/rider_server/session_operations/stdin.rb +19 -0
- data/lib/rider_server/utils.rb +7 -7
- data/lib/rider_server/validate/array.rb +32 -0
- data/lib/rider_server/validate/base.rb +28 -0
- data/lib/rider_server/validate/boolean.rb +47 -0
- data/lib/rider_server/validate/hash.rb +32 -0
- data/lib/rider_server/validate/integer.rb +56 -0
- data/lib/rider_server/validate/predicates.rb +30 -0
- data/lib/rider_server/validate/string.rb +60 -0
- data/lib/rider_server/validate/symbol.rb +90 -0
- data/lib/rider_server/validate.rb +15 -0
- data/lib/rider_server/version.rb +1 -1
- data/lib/rider_server/workspace.rb +1 -1
- data/lib/rider_server.rb +3 -1
- metadata +55 -24
- data/README.md +0 -44
- data/lib/rider_server/ops/completions.rb +0 -100
- data/lib/rider_server/ops/eval.rb +0 -62
- data/lib/rider_server/ops/inspect.rb +0 -121
- data/lib/rider_server/ops/inspect_exception.rb +0 -47
- data/lib/rider_server/ops/interrupt.rb +0 -30
- data/lib/rider_server/ops/load_path.rb +0 -20
- data/lib/rider_server/ops/lookup.rb +0 -83
- data/lib/rider_server/ops/ls_exceptions.rb +0 -29
- data/lib/rider_server/ops/ls_services.rb +0 -19
- data/lib/rider_server/ops/ls_sessions.rb +0 -52
- data/lib/rider_server/ops/service.rb +0 -43
- data/lib/rider_server/ops/set_namespace.rb +0 -79
- data/lib/rider_server/ops/set_namespace_variable.rb +0 -80
- data/lib/rider_server/ops/stdin.rb +0 -20
- data/lib/rider_server/ops/toggle_catch_all_exceptions.rb +0 -27
@@ -0,0 +1,42 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
SessionOperation.define do
|
6
|
+
name "service"
|
7
|
+
documentation "Control a Ruby service integration"
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
argument :service, :string, "The name of the Ruby service to control", required: true
|
11
|
+
argument :state, :string, "The desired state of the service", required: true
|
12
|
+
|
13
|
+
def handle(session, operation)
|
14
|
+
response = Response.new(operation)
|
15
|
+
|
16
|
+
service = operation["service"]
|
17
|
+
state = operation["state"]
|
18
|
+
|
19
|
+
current_state = session.service_state(service)
|
20
|
+
|
21
|
+
case state
|
22
|
+
when "start"
|
23
|
+
raise "Service already running" if current_state == "running"
|
24
|
+
session.start_service(service, response.id)
|
25
|
+
response.set("rider/stream", "true")
|
26
|
+
when "stop"
|
27
|
+
raise "Can't stop service #{service}. It's not running." if current_state == "stopped"
|
28
|
+
session.stop_service(service)
|
29
|
+
response.status("done")
|
30
|
+
else
|
31
|
+
# TODO: throwing this exception will caues a "done" response
|
32
|
+
# to be sent, which will implicitly close the stream. It
|
33
|
+
# might make sense to handle this more gracefully here.
|
34
|
+
raise "Unknown state #{state}"
|
35
|
+
end
|
36
|
+
|
37
|
+
response.set("service", service)
|
38
|
+
response.set("state", session.service_state(service).to_s)
|
39
|
+
response
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
SessionOperation.define do
|
6
|
+
name "set-namespace"
|
7
|
+
documentation "Set the namespace to the given location."
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
argument :location, :array, "The location to set the namespace to", required: true
|
11
|
+
|
12
|
+
def handle(session, operation)
|
13
|
+
response = Response.new(operation)
|
14
|
+
location = operation["location"]
|
15
|
+
|
16
|
+
value = traverse_location(location, nil, session)
|
17
|
+
session.workspace.set_namespace(value)
|
18
|
+
response.set("ns", session.workspace.namespace_name)
|
19
|
+
response.set("location", location)
|
20
|
+
response.status("done")
|
21
|
+
response
|
22
|
+
end
|
23
|
+
|
24
|
+
def traverse_location(location, ctx, session)
|
25
|
+
loc = location.first
|
26
|
+
locs = location.drop(1)
|
27
|
+
|
28
|
+
if locs.empty?
|
29
|
+
lookup_object(loc, ctx, session)
|
30
|
+
else
|
31
|
+
traverse_location(locs, lookup_object(loc, ctx, session), session)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def lookup_object(loc, ctx, session)
|
36
|
+
lookup, identifier = loc.split(":", 2)
|
37
|
+
|
38
|
+
case lookup
|
39
|
+
when "rider_main"
|
40
|
+
"main"
|
41
|
+
when "rider_history"
|
42
|
+
rider_history(identifier, nil, session)
|
43
|
+
when "rider_exception"
|
44
|
+
rider_exception(identifier, nil, session)
|
45
|
+
when "rider_stackframe"
|
46
|
+
ctx.__rider_bindings_stack[identifier.to_i]
|
47
|
+
when "rider_stackframe_variable"
|
48
|
+
frame_id, local_var = identifier.split(":", 2)
|
49
|
+
ctx.__rider_bindings_stack[frame_id.to_i].local_variable_get(local_var)
|
50
|
+
when "rider_array_item"
|
51
|
+
ctx[identifier.to_i]
|
52
|
+
when "rider_hash_key"
|
53
|
+
hash = identifier.to_i
|
54
|
+
ctx.keys.find { |key| key.hash == hash }
|
55
|
+
when "rider_hash_value"
|
56
|
+
hash = identifier.to_i
|
57
|
+
key = ctx.keys.find { |key| key.hash == hash }
|
58
|
+
ctx.fetch(key)
|
59
|
+
when "toplevel_const_get"
|
60
|
+
Object.const_get(identifier)
|
61
|
+
when "instance_variable_get"
|
62
|
+
ctx.instance_variable_get(identifier)
|
63
|
+
when "singleton_class"
|
64
|
+
ctx.singleton_class
|
65
|
+
when "const_get"
|
66
|
+
ctx.const_get(identifier)
|
67
|
+
when "ancestor_find"
|
68
|
+
ctx.class.ancestors.find { |item| item.to_s == identifier }
|
69
|
+
else
|
70
|
+
raise "Unknown inspect function: #{lookup}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def rider_history(value, ctx, session)
|
75
|
+
session.get_result(value)
|
76
|
+
end
|
77
|
+
|
78
|
+
def rider_exception(id, ctx, session)
|
79
|
+
session.get_exception(id)["exception"]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
SessionOperation.define do
|
6
|
+
name "set-namespace-variable"
|
7
|
+
documentation "Set a variable in the current REPL binding."
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
argument :name, :string, "The name of the local variable to set", required: true
|
11
|
+
argument :location, :array, "The location to set the namespace to", required: true
|
12
|
+
|
13
|
+
def handle(session, operation)
|
14
|
+
response = Response.new(operation)
|
15
|
+
name operation["name"]
|
16
|
+
raise "Name must be a valid Ruby identifier" unless /\A[a-zA-Z_]\w*\z/.match?(name)
|
17
|
+
location = operation["location"]
|
18
|
+
|
19
|
+
value = traverse_location(location, nil, session)
|
20
|
+
session.workspace.binding_local_variable_set(name, value)
|
21
|
+
response.status("done")
|
22
|
+
response
|
23
|
+
end
|
24
|
+
|
25
|
+
def traverse_location(location, ctx, session)
|
26
|
+
loc = location.first
|
27
|
+
locs = location.drop(1)
|
28
|
+
|
29
|
+
if locs.empty?
|
30
|
+
lookup_object(loc, ctx, session)
|
31
|
+
else
|
32
|
+
traverse_location(locs, lookup_object(loc, ctx, session), session)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def lookup_object(loc, ctx, session)
|
37
|
+
lookup, identifier = loc.split(":", 2)
|
38
|
+
|
39
|
+
case lookup
|
40
|
+
when "rider_main"
|
41
|
+
"main"
|
42
|
+
when "rider_history"
|
43
|
+
rider_history(identifier, nil, session)
|
44
|
+
when "rider_exception"
|
45
|
+
rider_exception(identifier, nil, session)
|
46
|
+
when "rider_stackframe"
|
47
|
+
ctx.__rider_bindings_stack[identifier.to_i]
|
48
|
+
when "rider_stackframe_variable"
|
49
|
+
frame_id, local_var = identifier.split(":", 2)
|
50
|
+
ctx.__rider_bindings_stack[frame_id.to_i].local_variable_get(local_var)
|
51
|
+
when "rider_array_item"
|
52
|
+
ctx[identifier.to_i]
|
53
|
+
when "rider_hash_key"
|
54
|
+
hash = identifier.to_i
|
55
|
+
ctx.keys.find { |key| key.hash == hash }
|
56
|
+
when "rider_hash_value"
|
57
|
+
hash = identifier.to_i
|
58
|
+
key = ctx.keys.find { |key| key.hash == hash }
|
59
|
+
ctx.fetch(key)
|
60
|
+
when "toplevel_const_get"
|
61
|
+
Object.const_get(identifier)
|
62
|
+
when "instance_variable_get"
|
63
|
+
ctx.instance_variable_get(identifier)
|
64
|
+
when "const_get"
|
65
|
+
ctx.const_get(identifier)
|
66
|
+
when "ancestor_find"
|
67
|
+
ctx.class.ancestors.find { |item| item.to_s == identifier }
|
68
|
+
else
|
69
|
+
raise "Unknown inspect function: #{lookup}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def rider_history(value, ctx, session)
|
74
|
+
session.get_result(value)
|
75
|
+
end
|
76
|
+
|
77
|
+
def rider_exception(id, ctx, session)
|
78
|
+
session.get_exception(id)["exception"]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rider_server/operation"
|
2
|
+
require "rider_server/response"
|
3
|
+
|
4
|
+
module RiderServer
|
5
|
+
SessionOperation.define do
|
6
|
+
name "stdin"
|
7
|
+
documentation "List all exceptions that have occurred in the session."
|
8
|
+
|
9
|
+
argument :id, :string, "The request id", required: true
|
10
|
+
argument :stdin, :string, "The input to write to the stdin of the process", required: true
|
11
|
+
|
12
|
+
def handle(session, operation)
|
13
|
+
session.stdin.write(operation["stdin"])
|
14
|
+
response = Response.new(operation)
|
15
|
+
response.status("done")
|
16
|
+
response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/rider_server/utils.rb
CHANGED
@@ -30,19 +30,19 @@ module RiderServer
|
|
30
30
|
end
|
31
31
|
module_function :create_listeners
|
32
32
|
|
33
|
-
def
|
34
|
-
if obj.respond_to?(:
|
35
|
-
obj.
|
33
|
+
def rider_display(obj)
|
34
|
+
if obj.respond_to?(:rider_display)
|
35
|
+
obj.rider_display
|
36
36
|
else
|
37
37
|
obj.inspect
|
38
38
|
end
|
39
39
|
end
|
40
|
-
module_function :
|
40
|
+
module_function :rider_display
|
41
41
|
|
42
42
|
class FixedArray < Array
|
43
|
-
def initialize(*args)
|
44
|
-
@max_size =
|
45
|
-
super
|
43
|
+
def initialize(*args, max_size: 10)
|
44
|
+
@max_size = max_size
|
45
|
+
super(*args)
|
46
46
|
end
|
47
47
|
|
48
48
|
def <<(element)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# array.rb -- Simple validation of arrays
|
5
|
+
#
|
6
|
+
# Author: Russell Sim
|
7
|
+
# Copyright (c) 2024 Russell Sim
|
8
|
+
# SPDX-License-Identifier: MIT
|
9
|
+
|
10
|
+
require "rider_server/validate/base"
|
11
|
+
|
12
|
+
module RiderServer
|
13
|
+
module Validate
|
14
|
+
class Array < Base
|
15
|
+
def initialize(element_validator)
|
16
|
+
@element_validator = element_validator
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate(data, loc = "")
|
20
|
+
fail(data, loc, "be an array") unless data.is_a?(::Array)
|
21
|
+
|
22
|
+
data.map.with_index do |element, index|
|
23
|
+
@element_validator.validate(element, "#{loc}[#{index}]")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.array(element_validator)
|
29
|
+
Array.new(element_validator)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "rider_server/validate/predicates"
|
2
|
+
|
3
|
+
module RiderServer
|
4
|
+
module Validate
|
5
|
+
class ValidationError < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
class Base
|
9
|
+
include PredicateLogic
|
10
|
+
|
11
|
+
def self.validate(data)
|
12
|
+
new.validate(data)
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate(data)
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
def fail(value, loc, reason)
|
20
|
+
if loc == ""
|
21
|
+
raise ValidationError, "#{value.inspect}, #{reason}"
|
22
|
+
else
|
23
|
+
raise ValidationError, "#{value.inspect}, found at #{loc} #{reason}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# boolean.rb -- Simple validation of booleans
|
5
|
+
#
|
6
|
+
# Author: Russell Sim
|
7
|
+
# Copyright (c) 2024 Russell Sim
|
8
|
+
# SPDX-License-Identifier: MIT
|
9
|
+
|
10
|
+
require "rider_server/validate/base"
|
11
|
+
|
12
|
+
module RiderServer
|
13
|
+
module Validate
|
14
|
+
class Boolean < Base
|
15
|
+
TRUE_STRINGS = ["yes", "true", "on"]
|
16
|
+
|
17
|
+
def default(value)
|
18
|
+
@default = value
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate(data, loc = "")
|
23
|
+
if data.nil? && @default
|
24
|
+
data = @default
|
25
|
+
elsif data.nil?
|
26
|
+
fail(data, loc, "no default value set")
|
27
|
+
end
|
28
|
+
|
29
|
+
case data
|
30
|
+
|
31
|
+
when ::TrueClass, ::FalseClass
|
32
|
+
data
|
33
|
+
when ::String
|
34
|
+
TRUE_STRINGS.member? data.downcase
|
35
|
+
when ::Integer
|
36
|
+
data > 0
|
37
|
+
else
|
38
|
+
fail(data, loc, "can't convert to a boolean")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.bool
|
44
|
+
Boolean.new
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# hash.rb -- Simple validation of hashes
|
5
|
+
#
|
6
|
+
# Author: Russell Sim
|
7
|
+
# Copyright (c) 2024 Russell Sim
|
8
|
+
# SPDX-License-Identifier: MIT
|
9
|
+
|
10
|
+
require "rider_server/validate/base"
|
11
|
+
|
12
|
+
module RiderServer
|
13
|
+
module Validate
|
14
|
+
class Hash < Base
|
15
|
+
def initialize(schema)
|
16
|
+
@schema = schema
|
17
|
+
end
|
18
|
+
|
19
|
+
def validate(data, loc = "")
|
20
|
+
@schema.map do |key, validator|
|
21
|
+
if data.key? key
|
22
|
+
[key, validator.validate(data[key], "#{loc}[#{key}]")]
|
23
|
+
end
|
24
|
+
end.to_h
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.hash(schema)
|
29
|
+
Hash.new(schema)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# integer.rb -- Simple validation of integers
|
5
|
+
#
|
6
|
+
# Author: Russell Sim
|
7
|
+
# Copyright (c) 2024 Russell Sim
|
8
|
+
# SPDX-License-Identifier: MIT
|
9
|
+
|
10
|
+
require "rider_server/validate/base"
|
11
|
+
|
12
|
+
module RiderServer
|
13
|
+
module Validate
|
14
|
+
class Integer < Base
|
15
|
+
def default(value)
|
16
|
+
@default = value
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def greater_than(value)
|
21
|
+
add_predicate { |data| [data > value, "must be greater than #{value}"] }
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def less_than(value)
|
26
|
+
add_predicate { |data| [data < value, "must be less than #{value}"] }
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate(data, loc = "")
|
31
|
+
if data.nil? && @default
|
32
|
+
data = @default
|
33
|
+
elsif data.nil?
|
34
|
+
fail(data, loc, "no default value set")
|
35
|
+
end
|
36
|
+
|
37
|
+
begin
|
38
|
+
data = data.to_i
|
39
|
+
rescue
|
40
|
+
fail(data, loc, "can't convert to an integer")
|
41
|
+
end
|
42
|
+
|
43
|
+
result, reason = check_predicates(data)
|
44
|
+
unless result
|
45
|
+
fail(data, loc, reason)
|
46
|
+
end
|
47
|
+
|
48
|
+
data
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.integer
|
53
|
+
Integer.new
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# predicates.rb -- Predicates for values
|
5
|
+
#
|
6
|
+
# Author: Russell Sim
|
7
|
+
# Copyright (c) 2024 Russell Sim
|
8
|
+
# SPDX-License-Identifier: MIT
|
9
|
+
|
10
|
+
module RiderServer
|
11
|
+
module Validate
|
12
|
+
module PredicateLogic
|
13
|
+
def add_predicate(&block)
|
14
|
+
@predicates ||= []
|
15
|
+
@predicates << block
|
16
|
+
end
|
17
|
+
|
18
|
+
def check_predicates(data)
|
19
|
+
return [true, ""] if @predicates.nil?
|
20
|
+
@predicates.each do |predicate|
|
21
|
+
result, reason = predicate.call(data)
|
22
|
+
unless result
|
23
|
+
return [result, reason]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
[true, ""]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# string.rb -- Simple validation of strings
|
5
|
+
#
|
6
|
+
# Author: Russell Sim
|
7
|
+
# Copyright (c) 2024 Russell Sim
|
8
|
+
# SPDX-License-Identifier: MIT
|
9
|
+
|
10
|
+
require "rider_server/validate/base"
|
11
|
+
|
12
|
+
module RiderServer
|
13
|
+
module Validate
|
14
|
+
class String < Base
|
15
|
+
def default(value)
|
16
|
+
@default = value
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def empty
|
21
|
+
add_predicate do |data|
|
22
|
+
[data.empty?, "must be empty"]
|
23
|
+
end
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def not_empty
|
28
|
+
add_predicate do |data|
|
29
|
+
[!data.empty?, "must not be empty"]
|
30
|
+
end
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate(data, loc = "")
|
35
|
+
if data.nil? && @default
|
36
|
+
data = @default
|
37
|
+
elsif data.nil?
|
38
|
+
fail(data, loc, "no default value set")
|
39
|
+
end
|
40
|
+
|
41
|
+
begin
|
42
|
+
data = data.to_s
|
43
|
+
rescue
|
44
|
+
fail(data, loc, "can't convert to a string")
|
45
|
+
end
|
46
|
+
|
47
|
+
result, reason = check_predicates(data)
|
48
|
+
unless result
|
49
|
+
fail(data, loc, reason)
|
50
|
+
end
|
51
|
+
|
52
|
+
data
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.string
|
57
|
+
Validate::String.new
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# symbol.rb -- Simple validation of symbols
|
5
|
+
#
|
6
|
+
# Author: Russell Sim
|
7
|
+
# Copyright (c) 2024 Russell Sim
|
8
|
+
# SPDX-License-Identifier: MIT
|
9
|
+
|
10
|
+
require "rider_server/validate/base"
|
11
|
+
|
12
|
+
module RiderServer
|
13
|
+
module Validate
|
14
|
+
class Symbol < Base
|
15
|
+
def default(value)
|
16
|
+
@default = value
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
# Require that the input be one of the +values+.
|
21
|
+
def one_of(*values)
|
22
|
+
raise ArgumentError, "one_of requires at least one value" if values.empty?
|
23
|
+
values.each do |value|
|
24
|
+
raise ArgumentError, "one_of requires all values to be symbols but #{value.inspect} is not" \
|
25
|
+
unless value.is_a?(::Symbol)
|
26
|
+
end
|
27
|
+
|
28
|
+
add_predicate do |data|
|
29
|
+
[values.member?(data), "must one of #{values.inspect}"]
|
30
|
+
end
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# Require that the input be empty.
|
35
|
+
def empty
|
36
|
+
add_predicate do |data|
|
37
|
+
[data.empty?, "must be empty"]
|
38
|
+
end
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
# Require that the input be not empty.
|
43
|
+
def not_empty
|
44
|
+
add_predicate do |data|
|
45
|
+
[!data.empty?, "must not be empty"]
|
46
|
+
end
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Convert the input to an upcase version if possible.
|
51
|
+
def upcase
|
52
|
+
@upcase = true
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def validate(data, loc = "")
|
57
|
+
if data.nil? && @default
|
58
|
+
data = @default
|
59
|
+
elsif data.nil?
|
60
|
+
fail(data, loc, "no default value set")
|
61
|
+
end
|
62
|
+
|
63
|
+
if data.respond_to?(:upcase)
|
64
|
+
begin
|
65
|
+
data = data.upcase if @upcase
|
66
|
+
rescue
|
67
|
+
fail(data, loc, "can't upcase symbol")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
begin
|
72
|
+
data = data.to_sym
|
73
|
+
rescue
|
74
|
+
fail(data, loc, "can't convert to a symbol")
|
75
|
+
end
|
76
|
+
|
77
|
+
result, reason = check_predicates(data)
|
78
|
+
unless result
|
79
|
+
fail(data, loc, reason)
|
80
|
+
end
|
81
|
+
|
82
|
+
data
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.symbol
|
87
|
+
Symbol.new
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# validate.rb -- Simple validation library
|
5
|
+
#
|
6
|
+
# Author: Russell Sim
|
7
|
+
# Copyright (c) 2024 Russell Sim
|
8
|
+
# SPDX-License-Identifier: MIT
|
9
|
+
|
10
|
+
require "rider_server/validate/array"
|
11
|
+
require "rider_server/validate/boolean"
|
12
|
+
require "rider_server/validate/hash"
|
13
|
+
require "rider_server/validate/integer"
|
14
|
+
require "rider_server/validate/string"
|
15
|
+
require "rider_server/validate/symbol"
|
data/lib/rider_server/version.rb
CHANGED