u-struct 0.7.0 → 0.11.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: f4b40b69da026b0f45f5514a8d340effc8f7d81489c4f1217237c16641186357
4
- data.tar.gz: 6a5cd7b12d2d1b16830a805b9904e5c212c685d5a32108439e8f9f2b8235dfb8
3
+ metadata.gz: 0150b18cb61a38d042a0ad2f22c9588c7269c8362a708a8ebf156cc927a312dd
4
+ data.tar.gz: 0fc97adb461433c7382ee524d3a58c4d134624013c4afa974cade30b46f09109
5
5
  SHA512:
6
- metadata.gz: 159075d6944696849893dd4f4860613b104b12f3e872c0cac65df62055af61309d9f9256a949693a01df7fb5b514e916755bf0f6f1295874d93b9bc1abb2a2b3
7
- data.tar.gz: 12db20998fcd5b1688e4786766630cee699daffacfca72d18e3e769ac387931dd310a46ff511862c7d9d9f2a458ae8667dd3e7623dbfca55802caa41fd3cfbb8
6
+ metadata.gz: 708cbec302ef69ec3d6f465ebca2d07eff62ff1a3746b4e7034b21a571e693b27b9e4dad1ada934f4ac37f2565212cc83f111d384eb84573209578aab77beac6
7
+ data.tar.gz: cec5b4750bcc98d9955fbe27bcca952b2139c36dd90d6f6c98fd3b107f9ef577fdb2e72f34c78871e15d608cdab06c034427efeab67caa5bc2c869bbaeee8026
@@ -0,0 +1,27 @@
1
+
2
+ name: build
3
+ on: [push]
4
+ jobs:
5
+ test:
6
+ runs-on: ubuntu-latest
7
+ strategy:
8
+ matrix:
9
+ ruby: [2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1.0-preview1]
10
+ steps:
11
+ - uses: actions/checkout@v2
12
+ - uses: ruby/setup-ruby@v1
13
+ with:
14
+ ruby-version: ${{ matrix.ruby }}
15
+ bundler-cache: true
16
+ - name: Test and generate coverage
17
+ run: bin/test
18
+ - name: Format coverage
19
+ if: ${{ matrix.ruby >= 3 && matrix.ruby < 3.1 }}
20
+ run: bin/prepare_coverage
21
+ - uses: paambaati/codeclimate-action@v2.7.5
22
+ if: ${{ matrix.ruby >= 3 && matrix.ruby < 3.1 }}
23
+ env:
24
+ CC_TEST_REPORTER_ID: 8ce350edeb0772e94ffd678bbaca30d9c1293b9d9051a1689c79b91c21f5afd5
25
+ with:
26
+ debug: true
27
+ coverageLocations: coverage/.resultset.json:simplecov
data/.gitignore CHANGED
@@ -6,3 +6,5 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+
10
+ Gemfile.lock
@@ -0,0 +1,8 @@
1
+ {
2
+ "cSpell.enabled": true,
3
+ "cSpell.ignoreWords": [
4
+ "paambaati",
5
+ "resultset",
6
+ "simplecov"
7
+ ]
8
+ }
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.10.0] - 2021-12-15
4
+
5
+ - To-do
6
+
7
+ ## [0.9.0] - 2021-12-14
8
+
9
+ - To-do
10
+
11
+ ## [0.8.0] - 2021-12-05
12
+
13
+ - To-do
14
+
3
15
  ## [0.7.0] - 2021-12-04
4
16
 
5
17
  - To-do
data/Gemfile CHANGED
@@ -8,4 +8,4 @@ gemspec
8
8
  gem 'rake', '~> 13.0'
9
9
 
10
10
  gem 'minitest', '~> 5.0'
11
- gem 'simplecov', '~> 0.21.2'
11
+ gem 'simplecov', '~> 0.21.2' if RUBY_VERSION >= '2.5.0'
data/README.md CHANGED
@@ -1,6 +1,24 @@
1
- # Micro::Struct
2
-
3
- Create powered Ruby structs.
1
+ <p align="center">
2
+ <h1 align="center">🧱 μ-struct</h1>
3
+ <p align="center"><i>Create powered Ruby structs.</i></p>
4
+ <br>
5
+ </p>
6
+
7
+ <p align="center">
8
+ <img src="https://img.shields.io/badge/ruby%20%3E=%202.2,%20%3C%203.2-ruby.svg?colorA=99004d&colorB=cc0066" alt="Ruby">
9
+ <a href="https://rubygems.org/gems/u-struct">
10
+ <img alt="Gem" src="https://img.shields.io/gem/v/u-struct.svg?style=flat-square">
11
+ </a>
12
+ <a href="https://github.com/serradura/u-struct/actions/workflows/ci.yml">
13
+ <img alt="Build Status" src="https://github.com/serradura/u-struct/actions/workflows/ci.yml/badge.svg">
14
+ </a>
15
+ <a href="https://codeclimate.com/github/serradura/u-struct/maintainability">
16
+ <img alt="Maintainability" src="https://api.codeclimate.com/v1/badges/2cc0204411cc2b392b7a/maintainability">
17
+ </a>
18
+ <a href="https://codeclimate.com/github/serradura/u-struct/test_coverage">
19
+ <img alt="Test Coverage" src="https://api.codeclimate.com/v1/badges/2cc0204411cc2b392b7a/test_coverage">
20
+ </a>
21
+ </p>
4
22
 
5
23
  ## Installation
6
24
 
@@ -22,7 +40,7 @@ Or install it yourself as:
22
40
 
23
41
  ```ruby
24
42
  # Like in a regular Struct, you can define one or many attributes.
25
- # But all of will be required by default.
43
+ # But all of them will be required by default.
26
44
 
27
45
  Micro::Struct.new(:first_name, :last_name, ...)
28
46
 
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ # Borrowed from https://gist.github.com/qortex/7e7c49f3731391a91ee898336183acef
4
+
5
+ # Temporary hack to get CodeClimate to work with SimpleCov 0.18 JSON format until issue is fixed
6
+ # upstream: https://github.com/codeclimate/test-reporter/issues/413
7
+
8
+ require "json"
9
+
10
+ filename = "coverage/.resultset.json"
11
+ contents = JSON.parse(File.read(filename))
12
+
13
+ def remove_lines_key(obj)
14
+ case obj
15
+ when Hash
16
+ obj.transform_values do |val|
17
+ val.is_a?(Hash) && val.key?("lines") ? val["lines"] : remove_lines_key(val)
18
+ end
19
+ else
20
+ obj
21
+ end
22
+ end
23
+
24
+ # overwrite
25
+ File.write(filename, JSON.generate(remove_lines_key(contents)))
26
+
27
+ puts Dir['coverage/.*.json']
data/bin/test ADDED
@@ -0,0 +1,8 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ rm Gemfile.lock
6
+
7
+ bundle update
8
+ bundle exec rake test
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+
8
+ gem 'u-struct', path: '..'
9
+ end
10
+
11
+ Person = Micro::Struct.new(:first_name, :last_name, optional: :age) do
12
+ def name
13
+ "#{first_name} #{last_name}"
14
+ end
15
+ end
16
+
17
+ person = Person.new(first_name: 'Rodrigo', last_name: 'Serradura')
18
+
19
+ puts format('first_name: %p', person.first_name)
20
+ puts format('last_name: %p', person.last_name)
21
+ puts format('name: %p', person.name)
22
+ puts format('age: %p', person.age)
23
+ puts
24
+
25
+ person.age = rand(18..100)
26
+
27
+ puts format('age: %p', person.age)
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+
8
+ gem 'u-struct', path: '..'
9
+ end
10
+
11
+ Person = Micro::Struct.with(:readonly, :instance_copy).new(
12
+ required: [:first_name, :last_name],
13
+ optional: [:age]
14
+ ) do
15
+ def name
16
+ "#{first_name} #{last_name}"
17
+ end
18
+ end
19
+
20
+ person = Person.new(first_name: 'Rodrigo', last_name: 'Serradura')
21
+
22
+ puts format('first_name: %p', person.first_name)
23
+ puts format('last_name: %p', person.last_name)
24
+ puts format('name: %p', person.name)
25
+ puts format('age: %p', person.age)
26
+ puts
27
+
28
+ rand_age = rand(18..100)
29
+
30
+ new_person = person.with(age: rand_age)
31
+
32
+ puts new_person.equal?(person)
33
+
34
+ puts format('age: %p', person.age)
35
+ puts format('age: %p', new_person.age)
36
+
37
+ person.age = rand_age
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RGB
4
+ Color = Micro::Struct.with(:readonly, :to_ary).new(:red, :green, :blue) do
5
+ def initialize(r, g, b)
6
+ super(
7
+ Number.new(value: r, label: 'red'),
8
+ Number.new(value: g, label: 'green'),
9
+ Number.new(value: b, label: 'blue')
10
+ )
11
+ end
12
+
13
+ def to_a
14
+ @to_a ||= super.map(&:value)
15
+ end
16
+
17
+ def to_hex
18
+ @to_hex ||= "##{red}#{green}#{blue}"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RGB
4
+ Number = Micro::Struct.with(:readonly).new(:value, :label) do
5
+ Input = Kind.object(name: 'Integer(>= 0 and <= 255)') do |value|
6
+ value.is_a?(::Integer) && value >= 0 && value <= 255
7
+ end
8
+
9
+ def initialize(value, label)
10
+ super(Input[value, label: label])
11
+ end
12
+
13
+ def to_s
14
+ @to_s ||= '%02x' % value
15
+ end
16
+
17
+ def inspect
18
+ "#<RGB::Number #{value}>"
19
+ end
20
+ end
21
+ end
data/examples/rgb_1.rb ADDED
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+
8
+ gem 'u-struct', path: '..'
9
+ gem 'kind'
10
+ end
11
+
12
+ RGBColor = Micro::Struct.with(:readonly, :to_ary).new(:red, :green, :blue) do
13
+ Number = Kind.object(name: 'Integer(>= 0 and <= 255)') do |value|
14
+ value.is_a?(::Integer) && value >= 0 && value <= 255
15
+ end
16
+
17
+ def initialize(r, g, b)
18
+ super(Number[r], Number[g], Number[b])
19
+ end
20
+
21
+ def to_hex
22
+ '#%02x%02x%02x' % self
23
+ end
24
+ end
25
+
26
+ puts
27
+
28
+ rgb_color = RGBColor.new(red: 1, green: 1, blue: 255)
29
+
30
+ p rgb_color
31
+
32
+ puts
33
+ puts format('to_a: %p', rgb_color.to_a)
34
+ puts format('to_hex: %p', rgb_color.to_hex)
35
+ puts
36
+
37
+ r, g, b = rgb_color
38
+
39
+ puts format('red: %p', r)
40
+ puts format('green: %p', g)
41
+ puts format('blue: %p', b)
42
+ puts
43
+
44
+ *rgb = rgb_color
45
+
46
+ puts rgb.inspect
47
+ puts
48
+
49
+ begin
50
+ RGBColor.new(red: 1, green: -1, blue: 255)
51
+ rescue => exception
52
+ puts exception # Kind::Error (-1 expected to be a kind of Integer(>= 0 and <= 255))
53
+ end
data/examples/rgb_2.rb ADDED
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+
8
+ gem 'u-struct', path: '..'
9
+ gem 'kind'
10
+ end
11
+
12
+ RGBNumber = Micro::Struct.with(:readonly).new(:value) do
13
+ Input = Kind.object(name: 'Integer(>= 0 and <= 255)') do |value|
14
+ value.is_a?(::Integer) && value >= 0 && value <= 255
15
+ end
16
+
17
+ def initialize(value)
18
+ super(Input[value])
19
+ end
20
+
21
+ def to_s
22
+ '%02x' % value
23
+ end
24
+
25
+ def inspect
26
+ "#<RGBNumber #{value}>"
27
+ end
28
+ end
29
+
30
+ RGBColor = Micro::Struct.with(:readonly, :to_ary).new(:red, :green, :blue) do
31
+ def self.new(r:, g:, b:)
32
+ __new__(
33
+ red: RGBNumber.new(value: r),
34
+ green: RGBNumber.new(value: g),
35
+ blue: RGBNumber.new(value: b)
36
+ )
37
+ end
38
+
39
+ def to_a
40
+ [red.value, green.value, blue.value]
41
+ end
42
+
43
+ def to_hex
44
+ "##{red}#{green}#{blue}"
45
+ end
46
+ end
47
+
48
+ puts
49
+
50
+ rgb_color = RGBColor.new(r: 1, g: 1, b: 255)
51
+
52
+ p rgb_color
53
+
54
+ puts
55
+ puts format('to_a: %p', rgb_color.to_a)
56
+ puts format('to_hex: %p', rgb_color.to_hex)
57
+ puts
58
+
59
+ r, g, b = rgb_color
60
+
61
+ puts format('red: %p', r)
62
+ puts format('green: %p', g)
63
+ puts format('blue: %p', b)
64
+ puts
65
+
66
+ *rgb = rgb_color
67
+
68
+ puts rgb.inspect
69
+ puts
70
+
71
+ begin
72
+ RGBColor.new(r: 1, g: -1, b: 255)
73
+ rescue => exception
74
+ puts exception # Kind::Error (-1 expected to be a kind of Integer(>= 0 and <= 255))
75
+ end
data/examples/rgb_3.rb ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+
8
+ gem 'u-struct', path: '..'
9
+ gem 'kind'
10
+ end
11
+
12
+ require_relative 'rgb/number'
13
+ require_relative 'rgb/color'
14
+
15
+ puts
16
+
17
+ rgb_color = RGB::Color.new(red: 1, green: 1, blue: 255)
18
+
19
+ p rgb_color
20
+
21
+ puts
22
+ puts format('to_a: %p', rgb_color.to_a)
23
+ puts format('to_hex: %p', rgb_color.to_hex)
24
+ puts
25
+
26
+ r, g, b = rgb_color
27
+
28
+ puts format('red: %p', r)
29
+ puts format('green: %p', g)
30
+ puts format('blue: %p', b)
31
+ puts
32
+
33
+ *rgb = rgb_color
34
+
35
+ puts rgb.inspect
36
+ puts
37
+
38
+ begin
39
+ RGB::Color.new(red: 1, green: -1, blue: 255)
40
+ rescue => exception
41
+ puts exception # Kind::Error (green: -1 expected to be a kind of Integer(>= 0 and <= 255))
42
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Micro::Struct::Factory
4
+ module CreateStruct
5
+ extend self
6
+
7
+ def with(members, block, features)
8
+ struct = ::Struct.new(*members.required_and_optional)
9
+
10
+ ClassScope.def_new(struct, members)
11
+ ClassScope.def_to_proc(struct) if features[:to_proc]
12
+ ClassScope.def_private_writers(struct) if features[:readonly]
13
+
14
+ InstanceScope.def_with(struct) if features[:instance_copy]
15
+ InstanceScope.def_to_ary(struct) if features[:to_ary]
16
+ InstanceScope.def_to_hash(struct) if features[:to_hash]
17
+
18
+ ClassScope.evaluate(struct, block)
19
+
20
+ struct
21
+ end
22
+
23
+ module ClassScope
24
+ def self.def_new(struct, members)
25
+ # The .new() method will require all required keyword arguments.
26
+ # We are doing this because the Struct constructor keyword init option treats everything as optional.
27
+ #
28
+ struct.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
29
+ class << self
30
+ undef_method :new
31
+
32
+ def new(#{members.to_eval.keyword_args}) # def new(a:, b:, c: nil) do
33
+ instance = allocate # instance = allocate
34
+ instance.send(:initialize, #{members.to_eval.positional_args}) # instance.send(:initialize, a, b, c)
35
+ instance # instance
36
+ end # end
37
+
38
+ alias __new__ new
39
+ end
40
+ RUBY
41
+ end
42
+
43
+ def self.def_to_proc(struct)
44
+ struct.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
45
+ def self.to_proc
46
+ ->(hash) { new(**hash) }
47
+ end
48
+ RUBY
49
+ end
50
+
51
+ def self.def_private_writers(struct)
52
+ struct.send(:private, *struct.members.map { |member| "#{member}=" })
53
+ end
54
+
55
+ def self.evaluate(struct, block)
56
+ struct.class_eval(&block) if block
57
+ end
58
+ end
59
+
60
+ module InstanceScope
61
+ def self.def_to_ary(struct)
62
+ struct.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
63
+ def to_ary
64
+ to_a
65
+ end
66
+ RUBY
67
+ end
68
+
69
+ def self.def_to_hash(struct)
70
+ struct.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
71
+ def to_hash
72
+ to_h
73
+ end
74
+ RUBY
75
+ end
76
+
77
+ def self.def_with(struct)
78
+ struct.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
79
+ def with(**members)
80
+ self.class.new(**to_h.merge(members))
81
+ end
82
+ RUBY
83
+ end
84
+ end
85
+ end
86
+
87
+ private_constant :CreateStruct
88
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro::Struct
4
+ class Factory
5
+ class Members
6
+ attr_reader :required_and_optional
7
+
8
+ Names = ->(values) { NormalizeNames::AsSymbols.(values, context: 'member') }
9
+
10
+ def initialize(required_members, required_option, optional_option)
11
+ @required = Names[required_members] + Names[required_option]
12
+ @optional = Names[optional_option]
13
+
14
+ @required_and_optional = @required + @optional
15
+ end
16
+
17
+ ToEval = ::Struct.new(:required, :optional, :required_and_optional) do
18
+ def keyword_args
19
+ required_kargs = "#{required.join(':, ')}#{':' unless required.empty?}"
20
+ optional_kargs = "#{optional.join(': nil, ')}#{': nil' unless optional.empty?}"
21
+
22
+ [required_kargs, optional_kargs].reject(&:empty?).join(', ')
23
+ end
24
+
25
+ def positional_args
26
+ required_and_optional.join(', ')
27
+ end
28
+ end
29
+
30
+ def to_eval
31
+ @to_eval ||= ToEval.new(@required, @optional, required_and_optional)
32
+ end
33
+ end
34
+
35
+ private_constant :Members
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro::Struct
4
+ class Factory
5
+ require_relative 'factory/members'
6
+ require_relative 'factory/create_struct'
7
+
8
+ def initialize(features)
9
+ @features = Features.require(features)
10
+ end
11
+
12
+ def new(*required_members, required: nil, optional: nil, &struct_block)
13
+ members = Members.new(required_members, required, optional)
14
+
15
+ CreateStruct.with(members, struct_block, @features)
16
+ end
17
+ end
18
+
19
+ private_constant :Factory
20
+ end
@@ -7,8 +7,7 @@ module Micro::Struct
7
7
  to_hash: false,
8
8
  to_proc: false,
9
9
  readonly: false,
10
- instance_copy: false
11
- }.freeze
10
+ instance_copy: false }.freeze
12
11
 
13
12
  Check = ->(to_ary:, to_hash:, to_proc:, readonly:, instance_copy:) do
14
13
  { to_ary: to_ary,
@@ -18,13 +17,12 @@ module Micro::Struct
18
17
  instance_copy: instance_copy }
19
18
  end
20
19
 
21
- NormalizeFeatureNames = ->(values) do
20
+ Names = ->(values) do
22
21
  NormalizeNames::AsSymbols.(values, context: 'feature')
23
22
  end
24
23
 
25
- def self.require(names)
26
- to_enable =
27
- NormalizeFeatureNames[names].each_with_object({}) { |name, memo| memo[name] = true }
24
+ def self.require(values)
25
+ to_enable = Names[values].each_with_object({}) { |name, memo| memo[name] = true }
28
26
 
29
27
  Check.(**DISABLED.merge(to_enable))
30
28
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Micro
4
4
  module Struct
5
- VERSION = '0.7.0'
5
+ VERSION = '0.11.0'
6
6
  end
7
7
  end
data/lib/micro/struct.rb CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  require_relative 'struct/version'
4
4
  require_relative 'struct/features'
5
- require_relative 'struct/creator'
5
+ require_relative 'struct/factory'
6
6
  require_relative 'struct/normalize_names'
7
7
 
8
8
  module Micro
9
9
  # Like in a regular Struct, you can define one or many attributes.
10
- # But all of will be required by default.
10
+ # But all of them will be required by default.
11
11
  #
12
12
  # Micro::Struct.new(:first_name, :last_name, ...)
13
13
  #
@@ -62,7 +62,7 @@ module Micro
62
62
  end
63
63
 
64
64
  def self.with(*features)
65
- Creator.new(features)
65
+ Factory.new(features)
66
66
  end
67
67
  end
68
68
  end
data/u-struct.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = %q{Create powered Ruby structs.}
13
13
  spec.homepage = 'https://github.com/serradura/u-struct'
14
14
  spec.license = 'MIT'
15
- spec.required_ruby_version = '>= 2.4.0'
15
+ spec.required_ruby_version = '>= 2.2.0'
16
16
 
17
17
  spec.metadata['homepage_uri'] = spec.homepage
18
18
  spec.metadata['source_code_uri'] = 'https://github.com/serradura/u-struct'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-04 00:00:00.000000000 Z
11
+ date: 2021-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -45,20 +45,30 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".github/workflows/ci.yml"
48
49
  - ".gitignore"
50
+ - ".vscode/settings.json"
49
51
  - CHANGELOG.md
50
52
  - CODE_OF_CONDUCT.md
51
53
  - Gemfile
52
- - Gemfile.lock
53
54
  - LICENSE.txt
54
55
  - README.md
55
56
  - Rakefile
56
57
  - bin/console
58
+ - bin/prepare_coverage
57
59
  - bin/setup
60
+ - bin/test
61
+ - examples/person_1.rb
62
+ - examples/person_2.rb
63
+ - examples/rgb/color.rb
64
+ - examples/rgb/number.rb
65
+ - examples/rgb_1.rb
66
+ - examples/rgb_2.rb
67
+ - examples/rgb_3.rb
58
68
  - lib/micro/struct.rb
59
- - lib/micro/struct/creator.rb
60
- - lib/micro/struct/creator/create_module.rb
61
- - lib/micro/struct/creator/create_struct.rb
69
+ - lib/micro/struct/factory.rb
70
+ - lib/micro/struct/factory/create_struct.rb
71
+ - lib/micro/struct/factory/members.rb
62
72
  - lib/micro/struct/features.rb
63
73
  - lib/micro/struct/normalize_names.rb
64
74
  - lib/micro/struct/version.rb
@@ -79,14 +89,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
79
89
  requirements:
80
90
  - - ">="
81
91
  - !ruby/object:Gem::Version
82
- version: 2.4.0
92
+ version: 2.2.0
83
93
  required_rubygems_version: !ruby/object:Gem::Requirement
84
94
  requirements:
85
95
  - - ">="
86
96
  - !ruby/object:Gem::Version
87
97
  version: '0'
88
98
  requirements: []
89
- rubygems_version: 3.2.21
99
+ rubygems_version: 3.2.22
90
100
  signing_key:
91
101
  specification_version: 4
92
102
  summary: Create powered Ruby structs.
data/Gemfile.lock DELETED
@@ -1,30 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- u-struct (0.7.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- docile (1.4.0)
10
- minitest (5.14.4)
11
- rake (13.0.6)
12
- simplecov (0.21.2)
13
- docile (~> 1.1)
14
- simplecov-html (~> 0.11)
15
- simplecov_json_formatter (~> 0.1)
16
- simplecov-html (0.12.3)
17
- simplecov_json_formatter (0.1.3)
18
-
19
- PLATFORMS
20
- x86_64-darwin-19
21
-
22
- DEPENDENCIES
23
- bundler
24
- minitest (~> 5.0)
25
- rake (~> 13.0)
26
- simplecov (~> 0.21.2)
27
- u-struct!
28
-
29
- BUNDLED WITH
30
- 2.2.32
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Micro::Struct::Creator
4
- module CreateModule
5
- extend self
6
-
7
- def with(required_members, optional_members, features)
8
- container = Module.new
9
-
10
- def_initialize_and_members(container, required_members, optional_members)
11
-
12
- def_to_proc(container) if features[:to_proc]
13
-
14
- container
15
- end
16
-
17
- private
18
-
19
- def def_initialize_and_members(container, required_members, optional_members)
20
- required = "#{required_members.join(':, ')}#{':' unless required_members.empty?}"
21
- optional = "#{optional_members.join(': nil, ')}#{': nil' unless optional_members.empty?}"
22
-
23
- method_arguments = [required, optional].reject(&:empty?).join(', ')
24
- struct_arguments = (required_members + optional_members).join(', ')
25
-
26
- container.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
27
- # The .new() method will require all required keyword arguments.
28
- # We are doing this because the Struct constructor keyword init option treats everything as optional.
29
- #
30
- def self.new(#{method_arguments}) # def self.new(a:, b:) do
31
- Struct.send(:new, #{struct_arguments}) # Struct.send(:new, a, b)
32
- end # end
33
-
34
- def self.members
35
- Struct.members
36
- end
37
- RUBY
38
- end
39
-
40
- def def_to_proc(container)
41
- container.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
42
- def self.to_proc
43
- ->(hash) { new(**hash) }
44
- end
45
- RUBY
46
- end
47
- end
48
-
49
- private_constant :CreateModule
50
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Micro::Struct::Creator
4
- module CreateStruct
5
- extend self
6
-
7
- def with(required_members, optional_members, features, &block)
8
- struct = ::Struct.new(*(required_members + optional_members), &block)
9
- struct.send(:private_class_method, :new)
10
-
11
- def_to_ary(struct) if features[:to_ary]
12
- def_to_hash(struct) if features[:to_hash]
13
- def_readonly(struct) if features[:readonly]
14
- def_instance_copy(struct) if features[:readonly] || features[:instance_copy]
15
-
16
- struct
17
- end
18
-
19
- private
20
-
21
- def def_to_ary(struct)
22
- struct.send(:alias_method, :to_ary, :to_a)
23
- end
24
-
25
- def def_to_hash(struct)
26
- struct.send(:alias_method, :to_hash, :to_h)
27
- end
28
-
29
- def def_readonly(struct)
30
- struct.send(:private, *struct.members.map { |member| "#{member}=" })
31
- end
32
-
33
- def def_instance_copy(struct)
34
- struct.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
35
- def with(**members)
36
- self.class.const_get(:Container, false).new(**to_h.merge(members))
37
- end
38
- RUBY
39
- end
40
- end
41
-
42
- private_constant :CreateStruct
43
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Micro::Struct
4
- class Creator
5
- require_relative 'creator/create_module'
6
- require_relative 'creator/create_struct'
7
-
8
- def initialize(features)
9
- @features = Features.require(features)
10
- end
11
-
12
- NormalizeMemberNames = ->(values) do
13
- NormalizeNames::AsSymbols.(values, context: 'member')
14
- end
15
-
16
- def new(*members, required: nil, optional: nil, &block)
17
- optional_members = NormalizeMemberNames[optional]
18
- required_members = NormalizeMemberNames[members] + NormalizeMemberNames[required]
19
-
20
- container = CreateModule.with(required_members, optional_members, @features)
21
- struct = CreateStruct.with(required_members, optional_members, @features, &block)
22
-
23
- container.const_set(:Struct, struct)
24
- struct.const_set(:Container, container)
25
- end
26
- end
27
-
28
- private_constant :Creator
29
- end