philosophal 1.0.1 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 560c41ed6154b813e0475f754e2e54de3c2fe0a2664983de21bcead6d281bfa8
4
- data.tar.gz: 5ae413ecbd701f3a14a8d80210aa2b01a9ab9f53c70dbf577591a1f3178c7a85
3
+ metadata.gz: 1df7f3c754eeef6776d0e3a18bcfdb81124e413187beb2f580dd550cbdcd046e
4
+ data.tar.gz: 03ed60c26e12f8225145e6f00a138da84e3d1aa11ffd1ab1be878df0032e6896
5
5
  SHA512:
6
- metadata.gz: ff0f7ba5322a942f64467fd87db1e801887668f4fe50a701d0c0b6798e82baf00ffa21559ea5404ae356400f88d6f3a1d1d1ce9b7ab78f530f8ea91dacccdd9a
7
- data.tar.gz: 15e28d5afe28ee4c674d05f8b663b9dbe59392df42ba82c857e32dab2ff8fefa82c816c9a56afc8c6de1ade6fbbba53c5202551ac1433403a6b0cf6e30a5baf0
6
+ metadata.gz: ab3fd3bf30dbaba5d2936979b832b2f9a715b7dbab19eba5d08c7feb4e84aa5affd41247b294ffc7ff9a4c054dcaba932ba2cb98d9c8699b5825d1dbad4c0a9b
7
+ data.tar.gz: 2b372e50b9bcf123531cdc0df806061893e86a3ddc70eddc2cc47731a017cff18dea606aea8c3477c2d8f2adf1faaa051c3728ad8645b166a0c5c120e583f951
data/.rubocop.yml CHANGED
@@ -6,4 +6,7 @@ require:
6
6
 
7
7
  AllCops:
8
8
  TargetRubyVersion: 3.1
9
- NewCops: enable
9
+ NewCops: enable
10
+
11
+ Style/Documentation:
12
+ Enabled: false
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.1.2
1
+ 3.1.7
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.1.2
1
+ ruby 3.1.7
data/README.md CHANGED
@@ -22,9 +22,9 @@ class Person
22
22
  end
23
23
 
24
24
  maxime = Person.new
25
- maxime.first_name = "Maxime"
26
- maxime.last_name = "Désécot"
27
- maxime.age = "40"
25
+ maxime.first_name = 'Maxime'
26
+ maxime.last_name = 'Désécot'
27
+ maxime.age = '40'
28
28
  puts maxime.inspect
29
29
  #<Person:0x00007da7088eed88 @first_name="maxime", @last_name="DÉSÉCOT", @age=40>
30
30
  ````
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.2.0
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Philosophal
4
+ module Loaders
5
+ class LoadError < StandardError; end
6
+ end
7
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Philosophal
4
+ module Loaders
5
+ class JsonLoader
6
+ def initialize(klass)
7
+ @klass = klass
8
+ end
9
+
10
+ def load(json)
11
+ return load_from_hash(json) if json.is_a?(Hash)
12
+ return load_from_array(json) if json.is_a?(Array)
13
+
14
+ raise LoadError, 'invalid json parameter' unless json.is_a?(String)
15
+
16
+ first_char = json[0]
17
+
18
+ return load_from_json(json) if first_char == '{'
19
+
20
+ return load_from_json_collection(json) if first_char == '['
21
+
22
+ load_from_path(json)
23
+ end
24
+
25
+ private
26
+
27
+ def load_from_array(array)
28
+ raise LoadError, 'invalid json parameter' if array.find { |hash| !hash.is_a?(Hash) }
29
+
30
+ array.map! do |hash|
31
+ load_from_hash(hash)
32
+ end
33
+ end
34
+
35
+ def load_from_hash(hash)
36
+ obj = @klass.new
37
+
38
+ hash.each_key do |key|
39
+ setter = setter_from_key(key)
40
+ next unless obj.respond_to?(setter)
41
+
42
+ obj.public_send(setter, hash.delete(key))
43
+ end
44
+
45
+ obj
46
+ end
47
+
48
+ def setter_from_key(key)
49
+ real_key = @klass.philosophal_properties.json_names_h[key]
50
+ property = @klass.philosophal_properties[real_key]
51
+
52
+ return :"#{property.name}=" if property
53
+
54
+ :"#{key}="
55
+ end
56
+
57
+ def load_from_json(str)
58
+ hash = JSON.parse(str, symbolize_names: true)
59
+ load_from_hash(hash)
60
+ end
61
+
62
+ def load_from_json_collection(json)
63
+ array = JSON.parse(json, symbolize_names: true)
64
+ load_from_array(array)
65
+ end
66
+
67
+ def load_from_path(path)
68
+ raise LoadError, "no such file #{path}" unless File.exist?(path)
69
+
70
+ str = File.read(path)
71
+ load_from_json(str)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Philosophal
4
+ module Loaders
5
+ autoload :JsonLoader, 'philosophal/loaders/json_loader'
6
+ autoload :LoadError, 'philosophal/loaders/errors'
7
+ end
8
+ end
@@ -29,11 +29,23 @@ module Philosophal
29
29
  end
30
30
 
31
31
  def immutables
32
- @properties_index.select { |_, v| v.immutable }
32
+ return @immutables if defined?(@immutables)
33
+
34
+ @immutables = @properties_index.select { |_, v| v.immutable }
33
35
  end
34
36
 
35
37
  def mutables
36
- @properties_index.reject { |_, v| v.immutable }
38
+ return @mutables if defined?(@mutables)
39
+
40
+ @mutables = @properties_index.reject { |_, v| v.immutable }
41
+ end
42
+
43
+ def json_names_h
44
+ return @json_names_h if defined?(@json_names_h)
45
+
46
+ @json_names_h = @properties_index.to_h do |key, property|
47
+ [property.json_name, key]
48
+ end
37
49
  end
38
50
  end
39
51
  end
@@ -3,10 +3,11 @@
3
3
  module Philosophal
4
4
  module Properties
5
5
  autoload :Schema, 'philosophal/properties/schema'
6
+ autoload :JSONLoader, 'philosophal/loaders/json_loader'
6
7
 
7
8
  include Philosophal::Types
8
9
 
9
- def cprop(name, type, default: nil, transform: nil, immutable: false)
10
+ def cprop(name, type, default: nil, transform: nil, immutable: false, description: nil, json: false)
10
11
  default.freeze if default && !(default.is_a?(Proc) || default.frozen?)
11
12
 
12
13
  if transform && !(transform.is_a?(Proc) || transform.is_a?(Symbol))
@@ -17,7 +18,21 @@ module Philosophal
17
18
  raise Philosophal::ArgumentError, 'immutable param must be true or false.'
18
19
  end
19
20
 
20
- property = __philosophal_property_class__.new(name:, type:, default:, transform:, immutable:)
21
+ if description
22
+ raise Philosophal::ArgumentError, 'description param must be a string.' unless description.is_a?(String)
23
+
24
+ description.freeze unless description.frozen?
25
+ end
26
+
27
+ if json
28
+ unless json.is_a?(TrueClass) || json.is_a?(String) || json.is_a?(Symbol)
29
+ raise Philosophal::ArgumentError, 'json param must be true or a String or a Symbol.'
30
+ end
31
+
32
+ json = json.to_sym if json.is_a?(String)
33
+ end
34
+
35
+ property = __philosophal_property_class__.new(name:, type:, default:, transform:, immutable:, description:, json:)
21
36
 
22
37
  philosophal_properties << property
23
38
  __define_philosophal_methods__(property)
@@ -34,6 +49,26 @@ module Philosophal
34
49
  end
35
50
  end
36
51
 
52
+ def philosophal_descriptions
53
+ return @philosophal_descriptions if defined?(@philosophal_descriptions)
54
+
55
+ @philosophal_descriptions = philosophal_properties.properties_index.values
56
+ .select(&:description)
57
+ .to_h do |property|
58
+ [
59
+ property.name,
60
+ property.description
61
+ ]
62
+ end
63
+ end
64
+ alias cprop_descriptions philosophal_descriptions
65
+
66
+ def json
67
+ return @json if defined?(@json)
68
+
69
+ @json = Philosophal::Loaders::JsonLoader.new(self)
70
+ end
71
+
37
72
  private
38
73
 
39
74
  def __philosophal_property_class__
@@ -68,12 +103,12 @@ module Philosophal
68
103
  end
69
104
 
70
105
  keys_str = keys_map.map { |k, v| [k, v.inspect].join(': ') }.join(', ')
71
- "#{self.class}:#{format('0x00%x', (object_id << 1))} #{keys_str}"
106
+ "#{self.class}:#{format('0x00%x', object_id << 1)} #{keys_str}"
72
107
  end
73
108
  alias cprop_inspect philosophal_inspect
74
109
 
75
110
  def philosophal_inspect_map
76
- self.class.philosophal_properties.properties_index.values.to_h do |property|
111
+ philosophal_values.to_h do |property|
77
112
  [
78
113
  property.name,
79
114
  send(property.name)
@@ -81,6 +116,23 @@ module Philosophal
81
116
  end
82
117
  end
83
118
  alias cprop_inspect_map philosophal_inspect_map
119
+
120
+ def philosophal_values
121
+ self.class.philosophal_properties.properties_index.values
122
+ end
123
+
124
+ def to_json_hash
125
+ philosophal_values.select(&:json).to_h do |property|
126
+ [
127
+ property.json_name,
128
+ send(property.name)
129
+ ]
130
+ end
131
+ end
132
+
133
+ def to_json(*_args)
134
+ to_json_hash.to_json
135
+ end
84
136
  end
85
137
  end
86
138
  end
@@ -94,8 +146,11 @@ module Philosophal
94
146
  end
95
147
 
96
148
  new_property.generate_reader_method(buffer)
149
+
97
150
  new_property.generate_boolean_method(buffer) if new_property.type == Philosophal::Types::BooleanType::Instance
98
151
 
152
+ new_property.generate_description_method(buffer) if new_property.description
153
+
99
154
  # puts buffer
100
155
 
101
156
  buffer
@@ -2,15 +2,23 @@
2
2
 
3
3
  module Philosophal
4
4
  class Property
5
- def initialize(name:, type:, default:, transform:, immutable:)
5
+ def initialize(name:, type:, default:, transform:, immutable:, description:, json:)
6
6
  @name = name
7
7
  @type = type
8
8
  @default = default
9
9
  @transform = transform
10
10
  @immutable = immutable
11
+ @description = description
12
+ @json = json
11
13
  end
12
14
 
13
- attr_reader :name, :type, :default, :transform, :immutable
15
+ attr_reader :name, :type, :default, :transform, :immutable, :description, :json
16
+
17
+ def json_name
18
+ return @json if @json.is_a?(Symbol)
19
+
20
+ @name
21
+ end
14
22
 
15
23
  def default?
16
24
  @default != nil
@@ -74,5 +82,14 @@ module Philosophal
74
82
  '!!@' << @name.name <<
75
83
  "\nend\n"
76
84
  end
85
+
86
+ def generate_description_method(buffer = +'')
87
+ buffer <<
88
+ ' def ' <<
89
+ @name.name <<
90
+ "_description\n " \
91
+ '%(' << @description << ')' \
92
+ "\nend\n"
93
+ end
77
94
  end
78
95
  end
data/lib/philosophal.rb CHANGED
@@ -4,6 +4,7 @@ require 'date'
4
4
  require 'pathname'
5
5
  require 'set'
6
6
  require 'time'
7
+ require 'json'
7
8
 
8
9
  module Philosophal
9
10
  autoload :Convertor, 'philosophal/convertor'
@@ -13,6 +14,7 @@ module Philosophal
13
14
  autoload :Property, 'philosophal/property'
14
15
 
15
16
  autoload :Types, 'philosophal/types'
17
+ autoload :Loaders, 'philosophal/loaders'
16
18
 
17
19
  autoload :TypeError, 'philosophal/errors/type_error'
18
20
  autoload :ArgumentError, 'philosophal/errors/argument_error'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philosophal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxime Désécot
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-06-23 00:00:00.000000000 Z
11
+ date: 2026-06-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Auto convert value on setter method call
14
14
  email:
@@ -29,6 +29,9 @@ files:
29
29
  - lib/philosophal/convertor.rb
30
30
  - lib/philosophal/errors/argument_error.rb
31
31
  - lib/philosophal/errors/type_error.rb
32
+ - lib/philosophal/loaders.rb
33
+ - lib/philosophal/loaders/errors.rb
34
+ - lib/philosophal/loaders/json_loader.rb
32
35
  - lib/philosophal/properties.rb
33
36
  - lib/philosophal/properties/schema.rb
34
37
  - lib/philosophal/property.rb
@@ -61,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
64
  - !ruby/object:Gem::Version
62
65
  version: '0'
63
66
  requirements: []
64
- rubygems_version: 3.3.7
67
+ rubygems_version: 3.3.27
65
68
  signing_key:
66
69
  specification_version: 4
67
70
  summary: Philosophal setter convertor