l43_base 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 80a1f55728d1bde85d95be0c9a6578ebc5c48741224cdbef3f3ea3cee4208140
4
+ data.tar.gz: 900b22d8c1623ace5f39e0d4e31f9913140dcdda3f26f62abd30eb095ccffe5d
5
+ SHA512:
6
+ metadata.gz: '035865b356f7c7ab01611faafffae4bebca2581a9b5769540fd2db4e518d2542af07798cee6ace287a7f2e2ba36d892ecc4f4c9a1e3e2e09515820165a2d73e1'
7
+ data.tar.gz: 610e0f965e14ac7ca81e9ee53f6e560a8fd836c9b15fd6ed6a4205c3e9f54d3ac0eb7856f1366e304c0e6d17d4d93545bd64fecd3352899dc8d13bb113c7260d
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module L43
4
+ module Base
5
+ module DataClass
6
+ class DataClassClass
7
+
8
+ def ==(other)
9
+ return false unless self.class === other
10
+ other.to_h == to_h
11
+ end
12
+
13
+ def update_attribute(attribute, &blk)
14
+ raise ArgumentError, "cannot update attribute #{attribute.inspect} without a block" unless blk
15
+ update(attribute => blk.(to_h[attribute]))
16
+ end
17
+
18
+ private
19
+ def check_instance! = nil
20
+ end
21
+ end
22
+ end
23
+ end
24
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './data_class_class'
4
+ module L43
5
+ module Base
6
+ module DataClass
7
+ class DataClassMaker
8
+
9
+ attr_reader :block_name, :klass
10
+
11
+ def define(*required, **defaulted, &blk)
12
+ @klass = Class.new(DataClassClass)
13
+ define_klass(required:, defaulted:)
14
+ klass.module_eval(&blk) if blk
15
+ klass.freeze
16
+ end
17
+
18
+ private
19
+ def initialize(block_name: nil)
20
+ @block_name = block_name
21
+ end
22
+
23
+ def define_accessors(names:)
24
+ klass.instance_eval {
25
+ attr_reader(*names)
26
+ }
27
+ end
28
+
29
+ def define_klass(required:, defaulted:)
30
+ delta = required.intersection(defaulted.keys)
31
+ raise ArgumentError, "incoherant attribute definition, arg must not be required and defaulted, violating args: #{delta.inspect}" unless delta.empty?
32
+
33
+ init_instance(block_name:, required:, defaulted:)
34
+ names = required + defaulted.keys
35
+ names = names << block_name if block_name
36
+ define_update(names:)
37
+ define_accessors(names:)
38
+ define_to_h(names:)
39
+ end
40
+
41
+ def define_to_h(names:)
42
+ klass.define_method :to_h do |*|
43
+ names.inject({}) do |r, k|
44
+ r.update(k => instance_variable_get("@#{k}"))
45
+ end
46
+ end
47
+ klass.alias_method :deconstruct_keys, :to_h
48
+ end
49
+
50
+ def define_update(names:)
51
+ klass.define_method :update do |**kwds|
52
+ spurious = kwds.keys - names
53
+ raise ArgumentError, "undefined attributes: #{spurious.inspect}" unless spurious.empty?
54
+ if frozen?
55
+ new_values = to_h.merge(**kwds)
56
+ self.class.new(**new_values)
57
+ else
58
+ kwds.each do |k, v|
59
+ instance_variable_set("@#{k}", v)
60
+ end
61
+ self
62
+ end
63
+ end
64
+ end
65
+
66
+ def init_instance(block_name:, required:, defaulted:)
67
+ klass.define_method :initialize do |**kwds, &blk|
68
+ if block_name
69
+ if blk
70
+ b = -> { instance_exec(&blk) }
71
+ instance_variable_set("@#{block_name}", b)
72
+ end
73
+ else
74
+ raise ArgumentError, "block argument not supported" if blk
75
+ end
76
+
77
+ missing = required - kwds.keys
78
+ raise ArgumentError, "missing required keyword parameters: #{missing.inspect}" unless missing.empty?
79
+ spurious = kwds.keys - required - defaulted.keys
80
+ raise ArgumentError, "spurious keyword parameters: #{spurious.inspect}" unless spurious.empty?
81
+
82
+ values = defaulted.merge(kwds)
83
+ values.each do |key, value|
84
+ instance_variable_set("@#{key}", value)
85
+ end
86
+
87
+ error = check_instance!
88
+ raise ArgumentError, Array(error).join("\n") if error
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'data_class/data_class_maker'
4
+ module L43
5
+ module Base
6
+ module DataClass extend self
7
+
8
+ def define(*a, **k, &b)
9
+ DataClassMaker.new.define(*a, **k, &b)
10
+ end
11
+
12
+ def with_block(block_name)
13
+ DataClassMaker.new(block_name:)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module L43
4
+ module Base
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
8
+ # SPDX-License-Identifier: AGPL-3.0-or-later
data/lib/l43/base.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'r'
4
+ module L43
5
+ require_all __FILE__
6
+ module Base
7
+ def DataClass(*a, **k, &b) = DataClass.define(*a, **k, &b)
8
+ end
9
+ end
10
+ # SPDX-License-Identifier: AGPL-3.0-or-later
data/lib/l43/r.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module L43
4
+ def self.require_all(file, descend: false)
5
+ dir = file.sub(/\.[^.]*\z/, '')
6
+ wc = descend ? '/**/*.rb' : '/*.rb'
7
+ Dir.glob(File.join(dir, wc)).each { require it }
8
+ end
9
+ end
10
+ # SPDX-License-Identifier: AGPL-3.0-or-later
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: l43_base
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Robert Dober
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-12-03 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ostruct
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 0.6.3
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.6.3
26
+ description: 'Basic Ruby Building Blocks
27
+
28
+ '
29
+ email: robert.dober@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/l43/base.rb
35
+ - lib/l43/base/data_class.rb
36
+ - lib/l43/base/data_class/data_class_class.rb
37
+ - lib/l43/base/data_class/data_class_maker.rb
38
+ - lib/l43/base/version.rb
39
+ - lib/l43/r.rb
40
+ homepage: https://codeberg.org/lab419/l43_base
41
+ licenses:
42
+ - AGPL-3.0-or-later
43
+ metadata: {}
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 3.4.5
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubygems_version: 3.7.2
59
+ specification_version: 4
60
+ summary: Basic Ruby Building Blocks
61
+ test_files: []