bed 0.1.0 → 0.2.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 +4 -4
- data/bed.gemspec +27 -0
- data/lib/bed/builder.rb +23 -0
- data/lib/bed/caster.rb +46 -0
- data/lib/bed/data.rb +21 -0
- data/lib/bed/definition.rb +139 -0
- data/lib/bed/flex/builder.rb +157 -0
- data/lib/bed/version.rb +2 -2
- data/lib/bed.rb +57 -3
- metadata +9 -10
- data/CODE_OF_CONDUCT.md +0 -47
- data/Rakefile +0 -8
- data/lib/bed/schema.rb +0 -99
- data/sig/bed.rbs +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16f810a2dd158bace211c2f593aa1cf740f38416e628b2f3d61b75efcd02339a
|
4
|
+
data.tar.gz: 83bf31b7eee26f2417a70aed78de72d3c9cfc56bf35224ffd52ed45604062734
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8534d64f120fc45d16e4ce4d565f9184f878f035221eddf73e9d2954c8189c157c781985489cc28a795d518cbf381809b755481ea7592f158f2eaa5ee181f164
|
7
|
+
data.tar.gz: '095927d43916dfbf51ec56dbc92b8b094fe8154291a0a0aa935d154f923e79447b3b5ae4dcd826de28c726568f06948b560e14d0306d820b080db926b12ffe09'
|
data/bed.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative "lib/bed/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "bed"
|
6
|
+
spec.version = Bed::VERSION
|
7
|
+
spec.platform = Gem::Platform::RUBY # Add this line
|
8
|
+
spec.authors = ["David Gillis"]
|
9
|
+
spec.email = ["david.gillis@hey.com"]
|
10
|
+
spec.summary = "A simple, modern schema library built on top of Data class"
|
11
|
+
spec.description = "Bed is a simple, modern schema library built on top of Data. It provides a simple, declarative way to define schemas for your data, and a way to validate that data against those schemas."
|
12
|
+
spec.required_ruby_version = ">= 3.0.0"
|
13
|
+
spec.homepage = "https://github.com/gillisd/bed"
|
14
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = Dir.glob([
|
18
|
+
"lib/**/*",
|
19
|
+
"README.md",
|
20
|
+
"LICENSE.txt",
|
21
|
+
"*.gemspec"
|
22
|
+
]).reject { |f| File.directory?(f) }
|
23
|
+
|
24
|
+
spec.bindir = "exe"
|
25
|
+
spec.executables = Dir.glob("exe/*").map { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ["lib"]
|
27
|
+
end
|
data/lib/bed/builder.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Bed
|
2
|
+
class Builder
|
3
|
+
def initialize(schema, &block)
|
4
|
+
@schema = schema
|
5
|
+
end
|
6
|
+
|
7
|
+
def define_methods
|
8
|
+
@schema.deconstruct_keys(nil).each do |key, value|
|
9
|
+
case value
|
10
|
+
in Data
|
11
|
+
Bed::Builder.new()
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def member?(name)
|
18
|
+
@schema.members.include?(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/bed/caster.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Bed
|
2
|
+
class Caster
|
3
|
+
def self.cast(buildable)
|
4
|
+
new(buildable).cast
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(buildable)
|
8
|
+
@buildable = buildable
|
9
|
+
end
|
10
|
+
|
11
|
+
def cast
|
12
|
+
raise TypeError, "#{@buildable} does not respond to to_h" unless @buildable.respond_to?(:to_h)
|
13
|
+
|
14
|
+
attributes = @buildable.to_h.transform_values do |value|
|
15
|
+
case value
|
16
|
+
in Hash
|
17
|
+
self.class.cast(value)
|
18
|
+
in Array
|
19
|
+
value.map do |v|
|
20
|
+
begin
|
21
|
+
self.class.cast(v)
|
22
|
+
rescue TypeError
|
23
|
+
v
|
24
|
+
end
|
25
|
+
end
|
26
|
+
else
|
27
|
+
value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
cache_key = [attributes.keys]
|
32
|
+
|
33
|
+
Thread.current[:__bed_cast_cache] ||= {}
|
34
|
+
Thread.current[:__bed_cast_cache][cache_key] ||= (
|
35
|
+
Data.define(*attributes.keys, &method(:definition))
|
36
|
+
)
|
37
|
+
Thread.current[:__bed_cast_cache][cache_key].new(**attributes)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def definition(instance)
|
43
|
+
instance
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/bed/data.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Bed
|
2
|
+
if defined?(::Data)
|
3
|
+
Data = ::Data
|
4
|
+
else
|
5
|
+
Data = ::Struct
|
6
|
+
Data.class_eval do
|
7
|
+
def self.define(*args, &block)
|
8
|
+
new(*args, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def []=(key, value)
|
12
|
+
self[key] = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_data
|
16
|
+
self
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,139 @@
|
|
1
|
+
class Object
|
2
|
+
class << self
|
3
|
+
alias_method :original_method_missing, :method_missing
|
4
|
+
|
5
|
+
def method_missing(method_name, *args, &block)
|
6
|
+
if method_name == :String
|
7
|
+
puts "Intercepted call to String with argument: #{args.first}"
|
8
|
+
define_method(args.first) do
|
9
|
+
"This is a dynamically defined method: #{args.first}"
|
10
|
+
end
|
11
|
+
else
|
12
|
+
original_method_missing(method_name, *args, &block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Bed
|
19
|
+
class Schema
|
20
|
+
attr_reader :fields
|
21
|
+
|
22
|
+
def initialize(fields)
|
23
|
+
@fields = fields
|
24
|
+
end
|
25
|
+
|
26
|
+
def pattern
|
27
|
+
fields.map { |_, v| v.is_a?(Schema) ? v.pattern : '_' }.join(', ')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Type
|
32
|
+
class << self
|
33
|
+
attr_reader :schema
|
34
|
+
|
35
|
+
def define(schema)
|
36
|
+
@schema = schema
|
37
|
+
Data.define(*schema.fields.keys) do
|
38
|
+
|
39
|
+
def initialize(...)
|
40
|
+
super
|
41
|
+
validate
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method(:deconstruct) do
|
45
|
+
self.class.schema.fields.keys.map do |key|
|
46
|
+
value = public_send(key)
|
47
|
+
if value.is_a?(Data) && value.class.respond_to?(:schema)
|
48
|
+
value.deconstruct
|
49
|
+
else
|
50
|
+
value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
define_method(:deconstruct_keys) do |keys = nil|
|
56
|
+
keys ||= self.class.schema.fields.keys
|
57
|
+
keys.each_with_object({}) do |key, hash|
|
58
|
+
if self.class.schema.fields.key?(key)
|
59
|
+
value = public_send(key)
|
60
|
+
hash[key] = if value.is_a?(Data) && value.class.respond_to?(:schema)
|
61
|
+
value.deconstruct_keys
|
62
|
+
else
|
63
|
+
value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
define_method(:to_hash) do
|
70
|
+
self.class.schema.fields.keys.each_with_object({}) do |key, hash|
|
71
|
+
value = public_send(key)
|
72
|
+
hash[key] = if value.is_a?(Data) && value.class.respond_to?(:schema)
|
73
|
+
value.to_hash
|
74
|
+
else
|
75
|
+
value
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
define_method(:validate) do
|
81
|
+
pattern = "case self\nin [#{self.class.schema.pattern}]\ntrue\nelse\nfalse\nend"
|
82
|
+
eval(pattern)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Class variable to store the schema
|
86
|
+
class_variable_set(:@@schema, schema)
|
87
|
+
|
88
|
+
# Class method to access the schema
|
89
|
+
define_singleton_method(:schema) do
|
90
|
+
class_variable_get(:@@schema)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
Field = Data.define(:name, :type, :required, :enable_default, :default_value, :allow_nil) do
|
98
|
+
def initialize(name:, type:, required: true, enable_default: false, default_value: nil, allow_nil: false)
|
99
|
+
super
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class SchemaBuilder
|
104
|
+
attr_reader :fields
|
105
|
+
|
106
|
+
def initialize
|
107
|
+
@fields = {}
|
108
|
+
end
|
109
|
+
|
110
|
+
Object.constants.each do |const|
|
111
|
+
define_method(const) do |field_name, **args|
|
112
|
+
define_field(Object.const_get(const), field_name, **args)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def compile(&block)
|
117
|
+
instance_eval(&block)
|
118
|
+
end
|
119
|
+
|
120
|
+
def to_schema
|
121
|
+
Schema.new(@fields)
|
122
|
+
end
|
123
|
+
|
124
|
+
def define_field(type, field_name, required: true, enable_default: false, default_value: nil, allow_nil: false)
|
125
|
+
@fields[field_name] = Field.new(name: field_name, type: type, required: required, enable_default: enable_default, default_value: default_value, allow_nil: allow_nil)
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def const_missing(type)
|
131
|
+
Object.const_get(type)
|
132
|
+
end
|
133
|
+
|
134
|
+
def method_missing(type, *args)
|
135
|
+
field_name = args.first
|
136
|
+
@fields[field_name] = Object.const_get(type)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module Bed
|
2
|
+
module Flex
|
3
|
+
class Builder
|
4
|
+
def initialize(*args, **kwargs, &blk)
|
5
|
+
@whitelisted_attributes = []
|
6
|
+
@attributes = {}
|
7
|
+
@locked = false
|
8
|
+
@converged = false
|
9
|
+
result = if block_given?
|
10
|
+
block = blk
|
11
|
+
if block.arity.zero?
|
12
|
+
instance_eval(&block)
|
13
|
+
else
|
14
|
+
yield self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
converge(result) if should_converge?(result)
|
19
|
+
@locked = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def converge(value)
|
23
|
+
@converged = true
|
24
|
+
@attributes[:_converged] = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def get(path)
|
28
|
+
path.to_s.split('.').inject(self) { |obj_self, attr| obj_self.public_send(attr) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_h
|
32
|
+
return @attributes[:_converged] if @converged
|
33
|
+
@attributes.transform_values { |v| v.is_a?(Builder) ? v.to_h : v }
|
34
|
+
end
|
35
|
+
|
36
|
+
# alias_method :inspect, :to_h
|
37
|
+
alias_method :to_s, :to_h
|
38
|
+
|
39
|
+
def deep_dup
|
40
|
+
self.class.new.tap do |new_builder|
|
41
|
+
@attributes.each do |key, value|
|
42
|
+
new_builder.send(:"#{key}=", value.is_a?(Builder) ? value.deep_dup : value.dup)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def pretty_print(pp)
|
48
|
+
pp.object_address_group(self) do
|
49
|
+
pp.seplist(@attributes, -> { pp.text ',' }) do |k, v|
|
50
|
+
pp.breakable
|
51
|
+
pp.group(1) do
|
52
|
+
pp.text k.to_s
|
53
|
+
pp.text ':'
|
54
|
+
pp.breakable
|
55
|
+
pp.pp v
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private alias_method :old_inspect, :inspect
|
62
|
+
|
63
|
+
def inspect
|
64
|
+
case @attributes
|
65
|
+
in {} then '{}'
|
66
|
+
in { _converged: value } then value
|
67
|
+
else
|
68
|
+
old_inspect
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# def to_ary
|
73
|
+
# [to_h]
|
74
|
+
# end
|
75
|
+
def []=(name, value)
|
76
|
+
set_attribute(name, value)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def should_converge?(result)
|
82
|
+
case [@attributes, result]
|
83
|
+
# E.g.
|
84
|
+
# b.foo do
|
85
|
+
# b.bar 'a string'
|
86
|
+
# end
|
87
|
+
in {}, Builder | nil then false
|
88
|
+
# E.g.
|
89
|
+
# b.foo do
|
90
|
+
# 'a string'
|
91
|
+
# end
|
92
|
+
in {}, _ then true
|
93
|
+
else false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def respond_to_missing?(name, include_private = false)
|
98
|
+
return false if name == :to_ary
|
99
|
+
@whitelisted_attributes.empty? || @whitelisted_attributes.include?(name) || super
|
100
|
+
end
|
101
|
+
|
102
|
+
def method_missing(name, *args, &block)
|
103
|
+
return super if !@whitelisted_attributes.empty? && !@whitelisted_attributes.include?(name)
|
104
|
+
|
105
|
+
if name.end_with?('=')
|
106
|
+
attribute_name = name.to_s.chomp('=').to_sym
|
107
|
+
set_attribute(attribute_name, args.first)
|
108
|
+
else
|
109
|
+
get_or_set_attribute(name, *args, &block)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def to_ary
|
114
|
+
[inspect]
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_or_set_attribute(name, *args, &block)
|
118
|
+
if args.empty? && !block
|
119
|
+
value = @attributes[name]
|
120
|
+
|
121
|
+
if value.nil? && @locked
|
122
|
+
raise NoMethodError, "#{name} is not defined"
|
123
|
+
end
|
124
|
+
else
|
125
|
+
value = if block
|
126
|
+
if block.arity == 0
|
127
|
+
args.size > 0 ? [*args,->{Builder.new(&block)}] : Builder.new(&block)
|
128
|
+
else
|
129
|
+
Builder.new.tap { |b| block.call(b) }
|
130
|
+
end
|
131
|
+
else
|
132
|
+
args.size == 1 ? args.first : args
|
133
|
+
end
|
134
|
+
set_attribute(name, value)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def set_attribute(name, value)
|
139
|
+
@attributes[name.to_sym] = value
|
140
|
+
|
141
|
+
define_attribute_method(name)
|
142
|
+
self
|
143
|
+
end
|
144
|
+
|
145
|
+
def define_attribute_method(name)
|
146
|
+
singleton_class.define_method(name) do |*args, &block|
|
147
|
+
if args.empty? && !block
|
148
|
+
name.to_s
|
149
|
+
@attributes[name]
|
150
|
+
else
|
151
|
+
get_or_set_attribute(name, *args, &block)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
data/lib/bed/version.rb
CHANGED
data/lib/bed.rb
CHANGED
@@ -1,9 +1,63 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'json'
|
4
|
+
require 'active_support/all'
|
5
|
+
require_relative 'bed/data'
|
6
|
+
require_relative 'bed/definition'
|
7
|
+
require_relative 'bed/caster'
|
8
|
+
require_relative 'bed/flex/builder'
|
4
9
|
require_relative "bed/version"
|
5
10
|
|
6
|
-
|
11
|
+
module Bed
|
7
12
|
class Error < StandardError; end
|
8
|
-
|
13
|
+
|
14
|
+
def self.define(**kwargs)
|
15
|
+
schema = Schema.new(kwargs)
|
16
|
+
Type.define(schema)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.schema(&block)
|
20
|
+
if block_given?
|
21
|
+
builder = SchemaBuilder.new
|
22
|
+
builder.compile(&block)
|
23
|
+
schema = builder.to_schema
|
24
|
+
define(**schema.fields)
|
25
|
+
else
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.flex(&block)
|
31
|
+
buildable = Flex::Builder.new(&block)
|
32
|
+
Caster.cast(buildable)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.infer_file(pathname)
|
36
|
+
infer(pathname)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.infer(inferrable)
|
40
|
+
buildable = get_buildable(inferrable)
|
41
|
+
|
42
|
+
Caster.cast(buildable)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.get_buildable(inferrable)
|
46
|
+
if looks_like_json?(inferrable)
|
47
|
+
return JSON.parse(inferrable, symbolize_names: true)
|
48
|
+
end
|
49
|
+
|
50
|
+
case inferrable
|
51
|
+
in String
|
52
|
+
JSON.load_file(inferrable, symbolize_names: true)
|
53
|
+
in Hash
|
54
|
+
inferrable
|
55
|
+
else
|
56
|
+
raise ArgumentError, "inferrable must be a String, Hash, JSON file path, or JSON string"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.looks_like_json?(str)
|
61
|
+
str.start_with?('{') || str.start_with?('[')
|
62
|
+
end
|
9
63
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Gillis
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date: 2024-
|
10
|
+
date: 2024-12-22 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
12
|
description: Bed is a simple, modern schema library built on top of Data. It provides
|
14
13
|
a simple, declarative way to define schemas for your data, and a way to validate
|
@@ -19,20 +18,21 @@ executables: []
|
|
19
18
|
extensions: []
|
20
19
|
extra_rdoc_files: []
|
21
20
|
files:
|
22
|
-
- CODE_OF_CONDUCT.md
|
23
21
|
- LICENSE.txt
|
24
22
|
- README.md
|
25
|
-
-
|
23
|
+
- bed.gemspec
|
26
24
|
- lib/bed.rb
|
27
|
-
- lib/bed/
|
25
|
+
- lib/bed/builder.rb
|
26
|
+
- lib/bed/caster.rb
|
27
|
+
- lib/bed/data.rb
|
28
|
+
- lib/bed/definition.rb
|
29
|
+
- lib/bed/flex/builder.rb
|
28
30
|
- lib/bed/version.rb
|
29
|
-
- sig/bed.rbs
|
30
31
|
homepage: https://github.com/gillisd/bed
|
31
32
|
licenses:
|
32
33
|
- MIT
|
33
34
|
metadata:
|
34
35
|
homepage_uri: https://github.com/gillisd/bed
|
35
|
-
post_install_message:
|
36
36
|
rdoc_options: []
|
37
37
|
require_paths:
|
38
38
|
- lib
|
@@ -47,8 +47,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '0'
|
49
49
|
requirements: []
|
50
|
-
rubygems_version: 3.
|
51
|
-
signing_key:
|
50
|
+
rubygems_version: 3.6.0.dev
|
52
51
|
specification_version: 4
|
53
52
|
summary: A simple, modern schema library built on top of Data class
|
54
53
|
test_files: []
|
data/CODE_OF_CONDUCT.md
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
# Code of Conduct
|
2
|
-
|
3
|
-
## Our Commitment
|
4
|
-
|
5
|
-
We are committed to fostering a respectful and productive environment for all project contributors.
|
6
|
-
|
7
|
-
## Expected Behavior
|
8
|
-
|
9
|
-
Contributors are expected to:
|
10
|
-
|
11
|
-
- Treat others with respect and professionalism
|
12
|
-
- Provide and accept constructive feedback graciously
|
13
|
-
- Own their actions and decisions
|
14
|
-
- Prioritize the needs of the project
|
15
|
-
- Keep discussions and contributions focused on the project or task at hand
|
16
|
-
|
17
|
-
## Unacceptable Behavior
|
18
|
-
|
19
|
-
The following behaviors are considered unacceptable:
|
20
|
-
|
21
|
-
- Harassment or discrimination of any kind
|
22
|
-
- Offensive comments or personal attacks
|
23
|
-
- Sharing others' private information without consent
|
24
|
-
- Any conduct deemed inappropriate in a professional setting
|
25
|
-
- Engaging in political discussions
|
26
|
-
- Integrating personal political views into contributions
|
27
|
-
|
28
|
-
## Enforcement
|
29
|
-
|
30
|
-
Project maintainers are responsible for enforcing these standards. They may take appropriate action in response to any
|
31
|
-
behavior that violates this Code of Conduct, including temporary or permanent bans from project communication channels
|
32
|
-
or from contributing to the project itself.
|
33
|
-
|
34
|
-
## Reporting Violations
|
35
|
-
|
36
|
-
Violations can be reported to the repository owner or project maintainers.
|
37
|
-
|
38
|
-
All reports will be reviewed promptly and treated confidentially.
|
39
|
-
|
40
|
-
## Scope
|
41
|
-
|
42
|
-
This Code of Conduct applies to all communication channels related to the project and when representing the project in
|
43
|
-
public spaces.
|
44
|
-
|
45
|
-
## Attribution
|
46
|
-
|
47
|
-
This Code of Conduct is adapted from the Contributor Covenant, version 2.1.
|
data/Rakefile
DELETED
data/lib/bed/schema.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
class Bed::Schema < Data
|
2
|
-
def self.define_with_types(**kwargs)
|
3
|
-
puts 'defining...'
|
4
|
-
old_kwdargs = kwargs
|
5
|
-
kwargs = kwargs.transform_values do |v|
|
6
|
-
v.superclass == Data ? v.new : v
|
7
|
-
end
|
8
|
-
|
9
|
-
keys = kwargs.keys
|
10
|
-
|
11
|
-
puts kwargs
|
12
|
-
|
13
|
-
init_block = Proc.new do
|
14
|
-
define_method :initialize do |args = nil|
|
15
|
-
case args
|
16
|
-
in Hash
|
17
|
-
super(**kwargs.merge(args))
|
18
|
-
in Array
|
19
|
-
super(kwargs.merge(args))
|
20
|
-
else
|
21
|
-
super(**kwargs)
|
22
|
-
end
|
23
|
-
|
24
|
-
unless args.nil?
|
25
|
-
# raise ArgumentError, 'Invalid arguments' unless validate
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
alias_method :_deconstruct, :deconstruct
|
30
|
-
|
31
|
-
define_method :deconstruct do
|
32
|
-
puts 'deconstructing...'
|
33
|
-
val = _deconstruct
|
34
|
-
case val
|
35
|
-
in *beginning, Class => data, *ending
|
36
|
-
[*beginning, *data.deconstruct, *ending]
|
37
|
-
in [*rest, Data => data]
|
38
|
-
[*rest, *data.deconstruct]
|
39
|
-
in [Data => data, *rest]
|
40
|
-
[*data.deconstruct, *rest]
|
41
|
-
else
|
42
|
-
_deconstruct
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
alias_method :_deconstruct_keys, :deconstruct_keys
|
47
|
-
|
48
|
-
define_method :deconstruct_keys do |keys = self.class.schema.keys|
|
49
|
-
puts keys
|
50
|
-
_deconstruct_keys(keys)
|
51
|
-
# _deconstruct_keys(keys).transform_values do |v|
|
52
|
-
# v.respond_to?(:deconstruct_keys) ? v.deconstruct_keys(keys) : v
|
53
|
-
# end
|
54
|
-
end
|
55
|
-
|
56
|
-
define_method :to_hash do
|
57
|
-
to_h.transform_values do |v|
|
58
|
-
v.respond_to?(:to_hash) ? v.to_hash : v
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
define_method :validate do
|
63
|
-
arr = self.class.new.deconstruct
|
64
|
-
pattern = <<-RUBY
|
65
|
-
case self
|
66
|
-
in #{arr}
|
67
|
-
true
|
68
|
-
else
|
69
|
-
false
|
70
|
-
end
|
71
|
-
RUBY
|
72
|
-
eval(pattern)
|
73
|
-
end
|
74
|
-
|
75
|
-
define_singleton_method :schema do
|
76
|
-
old_kwdargs
|
77
|
-
end
|
78
|
-
|
79
|
-
define_singleton_method :create_nested_objects do |grouped_data|
|
80
|
-
grouped_data.to_a.reverse.reduce(nil) do |inner, (klass, values)|
|
81
|
-
args = values.map(&:first)
|
82
|
-
args << inner if inner
|
83
|
-
klass.new(*args)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
define_singleton_method :go do
|
88
|
-
schema.values.map { |v| v.respond_to?(:superclass) && v.superclass == Data ? v.go : self }.flatten
|
89
|
-
end
|
90
|
-
|
91
|
-
define_singleton_method :reconstruct do |*args|
|
92
|
-
grouped = args.zip(go).group_by(&:last)
|
93
|
-
|
94
|
-
create_nested_objects(grouped)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
Data.define(*keys, &init_block)
|
98
|
-
end
|
99
|
-
end
|
data/sig/bed.rbs
DELETED