solid-adapters 1.0.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 +7 -0
- data/.rubocop.yml +3 -0
- data/.standard.yml +5 -0
- data/CHANGELOG.md +10 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +418 -0
- data/Rakefile +14 -0
- data/examples/README.md +15 -0
- data/examples/anti_corruption_layer/README.md +217 -0
- data/examples/anti_corruption_layer/Rakefile +30 -0
- data/examples/anti_corruption_layer/app/models/payment/charge_credit_card.rb +36 -0
- data/examples/anti_corruption_layer/config.rb +19 -0
- data/examples/anti_corruption_layer/lib/payment_gateways/adapters/circle_up.rb +19 -0
- data/examples/anti_corruption_layer/lib/payment_gateways/adapters/pay_friend.rb +19 -0
- data/examples/anti_corruption_layer/lib/payment_gateways/contract.rb +15 -0
- data/examples/anti_corruption_layer/lib/payment_gateways/response.rb +5 -0
- data/examples/anti_corruption_layer/lib/payment_gateways.rb +11 -0
- data/examples/anti_corruption_layer/vendor/circle_up/client.rb +11 -0
- data/examples/anti_corruption_layer/vendor/pay_friend/client.rb +11 -0
- data/examples/ports_and_adapters/README.md +157 -0
- data/examples/ports_and_adapters/Rakefile +66 -0
- data/examples/ports_and_adapters/app/models/user/record/repository.rb +13 -0
- data/examples/ports_and_adapters/app/models/user/record.rb +7 -0
- data/examples/ports_and_adapters/config.rb +32 -0
- data/examples/ports_and_adapters/db/setup.rb +16 -0
- data/examples/ports_and_adapters/lib/user/creation.rb +19 -0
- data/examples/ports_and_adapters/lib/user/data.rb +5 -0
- data/examples/ports_and_adapters/lib/user/repository.rb +14 -0
- data/examples/ports_and_adapters/test/user_test/repository.rb +21 -0
- data/lib/solid/adapters/configurable/options.rb +44 -0
- data/lib/solid/adapters/configurable.rb +19 -0
- data/lib/solid/adapters/core/config.rb +35 -0
- data/lib/solid/adapters/core/proxy.rb +25 -0
- data/lib/solid/adapters/interface.rb +57 -0
- data/lib/solid/adapters/proxy.rb +11 -0
- data/lib/solid/adapters/version.rb +7 -0
- data/lib/solid/adapters.rb +28 -0
- metadata +85 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/all'
|
4
|
+
|
5
|
+
ActiveRecord::Base.establish_connection(
|
6
|
+
host: 'localhost',
|
7
|
+
adapter: 'sqlite3',
|
8
|
+
database: ':memory:'
|
9
|
+
)
|
10
|
+
|
11
|
+
ActiveRecord::Schema.define do
|
12
|
+
create_table :users do |t|
|
13
|
+
t.column :name, :string
|
14
|
+
t.column :email, :string
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module User
|
4
|
+
class Creation
|
5
|
+
def initialize(repository:)
|
6
|
+
repository => Repository
|
7
|
+
|
8
|
+
@repository = repository
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(name:, email:)
|
12
|
+
user_data = @repository.create(name:, email:)
|
13
|
+
|
14
|
+
puts "Created user: #{user_data.inspect}"
|
15
|
+
|
16
|
+
user_data
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module User::Repository
|
4
|
+
include Solid::Adapters::Interface
|
5
|
+
|
6
|
+
module Methods
|
7
|
+
def create(name:, email:)
|
8
|
+
name => String
|
9
|
+
email => String
|
10
|
+
|
11
|
+
super.tap { _1 => ::User::Data[id: Integer, name: String, email: String] }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module UserTest
|
4
|
+
class Repository
|
5
|
+
include ::User::Repository
|
6
|
+
|
7
|
+
attr_reader :records
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@records = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def create(name:, email:)
|
14
|
+
id = @records.size + 1
|
15
|
+
|
16
|
+
@records[id] = { id:, name:, email: }
|
17
|
+
|
18
|
+
::User::Data.new(id:, name:, email:)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Solid::Adapters::Configurable::Options
|
4
|
+
MapOption = ->(key) { key.end_with?("=") ? key[0..-2].to_sym : key }
|
5
|
+
MapValue = ->(value) { value.is_a?(::Proc) ? value.call : value }
|
6
|
+
|
7
|
+
def initialize(**options)
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_h
|
12
|
+
@options.dup
|
13
|
+
end
|
14
|
+
|
15
|
+
def key?(name)
|
16
|
+
@options.key?(name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](name)
|
20
|
+
@options[name].then(&MapValue)
|
21
|
+
end
|
22
|
+
|
23
|
+
def fetch(name, &block)
|
24
|
+
@options.fetch(name, &block).then(&MapValue)
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_missing(method_name, value = nil, &block)
|
28
|
+
return fetch(method_name) { super } if !method_name.end_with?("=") && !block
|
29
|
+
|
30
|
+
option_name = MapOption[method_name]
|
31
|
+
|
32
|
+
@options[option_name] = block || value
|
33
|
+
end
|
34
|
+
|
35
|
+
def respond_to_missing?(method_name, include_private = false)
|
36
|
+
(method_name.end_with?("=") || key?(method_name)) || super
|
37
|
+
end
|
38
|
+
|
39
|
+
def freeze
|
40
|
+
@options.freeze
|
41
|
+
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solid::Adapters
|
4
|
+
module Configurable
|
5
|
+
require_relative "configurable/options"
|
6
|
+
|
7
|
+
def config
|
8
|
+
@config ||= Options.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def configuration(freeze: true)
|
12
|
+
yield(config)
|
13
|
+
|
14
|
+
config.tap { _1.freeze if freeze }
|
15
|
+
end
|
16
|
+
|
17
|
+
alias_method :configure, :configuration
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solid::Adapters::Core
|
4
|
+
class Config
|
5
|
+
attr_accessor :proxy_enabled, :interface_enabled
|
6
|
+
|
7
|
+
def initialize(proxy_enabled: true, interface_enabled: true)
|
8
|
+
self.proxy_enabled = proxy_enabled
|
9
|
+
self.interface_enabled = interface_enabled
|
10
|
+
end
|
11
|
+
|
12
|
+
def proxy_enabled?
|
13
|
+
proxy_enabled
|
14
|
+
end
|
15
|
+
|
16
|
+
def interface_enabled?
|
17
|
+
interface_enabled
|
18
|
+
end
|
19
|
+
|
20
|
+
def options
|
21
|
+
{
|
22
|
+
proxy_enabled: proxy_enabled,
|
23
|
+
interface_enabled: interface_enabled
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def inspect
|
28
|
+
"#<#{self.class.name} proxy_enabled=#{proxy_enabled}, interface_enabled=#{interface_enabled}>"
|
29
|
+
end
|
30
|
+
|
31
|
+
@instance = new
|
32
|
+
|
33
|
+
singleton_class.send(:attr_reader, :instance)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solid::Adapters::Core
|
4
|
+
module Proxy
|
5
|
+
module ClassMethods
|
6
|
+
def [](object)
|
7
|
+
new(object)
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_proc
|
11
|
+
->(object) { new(object) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Base
|
16
|
+
extend ClassMethods
|
17
|
+
|
18
|
+
attr_reader :object
|
19
|
+
|
20
|
+
def initialize(object)
|
21
|
+
@object = object
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
4
|
+
|
5
|
+
module Solid::Adapters
|
6
|
+
module Interface
|
7
|
+
module Callbacks
|
8
|
+
def extended(impl)
|
9
|
+
impl.singleton_class.prepend(self::Methods)
|
10
|
+
end
|
11
|
+
|
12
|
+
def included(impl)
|
13
|
+
impl.prepend(self::Methods)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
def [](object)
|
19
|
+
const_get(:Proxy, false).new(object).extend(self)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module ProxyDisabled
|
24
|
+
extend Core::Proxy::ClassMethods
|
25
|
+
|
26
|
+
def self.new(object)
|
27
|
+
object
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
DEFINE = lambda do |interface, enabled:|
|
32
|
+
proxy = ProxyDisabled
|
33
|
+
|
34
|
+
if enabled
|
35
|
+
proxy = ::Class.new(::SimpleDelegator)
|
36
|
+
proxy.extend(Core::Proxy::ClassMethods)
|
37
|
+
|
38
|
+
interface.extend(Callbacks)
|
39
|
+
end
|
40
|
+
|
41
|
+
interface.const_set(:Proxy, proxy)
|
42
|
+
interface.extend(ClassMethods)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.included(interface)
|
46
|
+
DEFINE[interface, enabled: Core::Config.instance.interface_enabled]
|
47
|
+
end
|
48
|
+
|
49
|
+
module AlwaysEnabled
|
50
|
+
def self.included(interface)
|
51
|
+
DEFINE[interface, enabled: true]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private_constant :Callbacks, :ClassMethods, :ProxyDisabled, :DEFINE
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "adapters/version"
|
4
|
+
|
5
|
+
module Solid
|
6
|
+
module Adapters
|
7
|
+
module Core
|
8
|
+
require_relative "adapters/core/config"
|
9
|
+
require_relative "adapters/core/proxy"
|
10
|
+
end
|
11
|
+
|
12
|
+
require_relative "adapters/configurable"
|
13
|
+
require_relative "adapters/interface"
|
14
|
+
require_relative "adapters/proxy"
|
15
|
+
|
16
|
+
def self.config
|
17
|
+
Core::Config.instance
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.configuration(freeze: true)
|
21
|
+
yield(config)
|
22
|
+
|
23
|
+
config.tap { _1.freeze if freeze }
|
24
|
+
end
|
25
|
+
|
26
|
+
singleton_class.send(:alias_method, :configure, :configuration)
|
27
|
+
end
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: solid-adapters
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rodrigo Serradura
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-06-24 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Write interface contracts using pure Ruby.
|
14
|
+
email:
|
15
|
+
- rodrigo.serradura@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".rubocop.yml"
|
21
|
+
- ".standard.yml"
|
22
|
+
- CHANGELOG.md
|
23
|
+
- CODE_OF_CONDUCT.md
|
24
|
+
- LICENSE.txt
|
25
|
+
- README.md
|
26
|
+
- Rakefile
|
27
|
+
- examples/README.md
|
28
|
+
- examples/anti_corruption_layer/README.md
|
29
|
+
- examples/anti_corruption_layer/Rakefile
|
30
|
+
- examples/anti_corruption_layer/app/models/payment/charge_credit_card.rb
|
31
|
+
- examples/anti_corruption_layer/config.rb
|
32
|
+
- examples/anti_corruption_layer/lib/payment_gateways.rb
|
33
|
+
- examples/anti_corruption_layer/lib/payment_gateways/adapters/circle_up.rb
|
34
|
+
- examples/anti_corruption_layer/lib/payment_gateways/adapters/pay_friend.rb
|
35
|
+
- examples/anti_corruption_layer/lib/payment_gateways/contract.rb
|
36
|
+
- examples/anti_corruption_layer/lib/payment_gateways/response.rb
|
37
|
+
- examples/anti_corruption_layer/vendor/circle_up/client.rb
|
38
|
+
- examples/anti_corruption_layer/vendor/pay_friend/client.rb
|
39
|
+
- examples/ports_and_adapters/README.md
|
40
|
+
- examples/ports_and_adapters/Rakefile
|
41
|
+
- examples/ports_and_adapters/app/models/user/record.rb
|
42
|
+
- examples/ports_and_adapters/app/models/user/record/repository.rb
|
43
|
+
- examples/ports_and_adapters/config.rb
|
44
|
+
- examples/ports_and_adapters/db/setup.rb
|
45
|
+
- examples/ports_and_adapters/lib/user/creation.rb
|
46
|
+
- examples/ports_and_adapters/lib/user/data.rb
|
47
|
+
- examples/ports_and_adapters/lib/user/repository.rb
|
48
|
+
- examples/ports_and_adapters/test/user_test/repository.rb
|
49
|
+
- lib/solid/adapters.rb
|
50
|
+
- lib/solid/adapters/configurable.rb
|
51
|
+
- lib/solid/adapters/configurable/options.rb
|
52
|
+
- lib/solid/adapters/core/config.rb
|
53
|
+
- lib/solid/adapters/core/proxy.rb
|
54
|
+
- lib/solid/adapters/interface.rb
|
55
|
+
- lib/solid/adapters/proxy.rb
|
56
|
+
- lib/solid/adapters/version.rb
|
57
|
+
homepage: https://github.com/serradura/solid-adapters
|
58
|
+
licenses:
|
59
|
+
- MIT
|
60
|
+
metadata:
|
61
|
+
allowed_push_host: https://rubygems.org
|
62
|
+
homepage_uri: https://github.com/serradura/solid-adapters
|
63
|
+
source_code_uri: https://github.com/serradura/solid-adapters
|
64
|
+
changelog_uri: https://github.com/solid-process/solid-adapters/blob/main/CHANGELOG.md
|
65
|
+
rubygems_mfa_required: 'true'
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 2.7.0
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubygems_version: 3.5.14
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: Write interface contracts using pure Ruby.
|
85
|
+
test_files: []
|