uinit-type 0.1.4 → 0.1.6

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: 2c7881f9a5e13a64bcf4d2ccd9e330403bdd1da330b2794cb97fcb08a85682b2
4
- data.tar.gz: 7612f19bf51686197479c68fe7022de018ef5dfad9fddce4159f6cb4a51df0da
3
+ metadata.gz: 3d2fa003157324858ef9690e02461f5a12891514570425c7356d1c6eef2027f2
4
+ data.tar.gz: b0e075b89b209a0c0aefbad71973d91da29fc8aba4adaecb6ed3f87e9051b1c8
5
5
  SHA512:
6
- metadata.gz: bf8e5041e730686dbaa48ed891d4363aa36c4d88515b9a263db7aed593d60fac3fd3601a672d961a6ab6be6674381ccca632848c82ca9bc18e6c918cffff352e
7
- data.tar.gz: befcdcc0f310459d63b5bfe72cadcc8c9a94bc10898f1bd6de61839a7d82188dfe5f72adba38a3b3cd15dda28bbf21ad6cd30059b06295220b9ac9531a1536d7
6
+ metadata.gz: d437e365ed02140daa4da4b1d7524bfc4e560df4bf12eb3151bd7ddeb17d6d728d77af3d569c5f9cc82c0af52cd9e4b434b5e19216cad7ce7ad34b6cc0b16fcf
7
+ data.tar.gz: 91735badafaecd283b095cfa61c965655be2afc337bd3c0c4092a9195f365d520e9776e1af7b6a16b99eb54c430cd51aa63aa1bc433c0d73fb37031a00ecf01a
data/README.md CHANGED
@@ -2,6 +2,3 @@
2
2
 
3
3
  Dynamic type checker
4
4
 
5
-
6
- ## TODO
7
- - type Map, an generic hash (key, value types)
@@ -44,8 +44,6 @@ module Uinit
44
44
  is
45
45
  end
46
46
 
47
- # rubocop:disable Metrics/AbcSize
48
- # rubocop:disable Metrics/CyclomaticComplexity
49
47
  # rubocop:disable Metrics/PerceivedComplexity
50
48
  def check!(value, depth)
51
49
  errors = []
@@ -5,10 +5,7 @@ module Uinit
5
5
  module Context
6
6
  Nil = Const[nil].freeze
7
7
  Boolean = (Const[true] | Const[false]).freeze
8
- Str = TypeOf[String].freeze
9
8
  Sym = TypeOf[Symbol].freeze
10
- Int = TypeOf[Integer].freeze
11
- Float = TypeOf[Float].freeze
12
9
  Hsh = TypeOf[Hash].freeze
13
10
  Arr = TypeOf[Array].freeze
14
11
 
@@ -32,15 +29,15 @@ module Uinit
32
29
  Fn.new(arity)
33
30
  end
34
31
 
35
- def hash_of(schema, strict: false)
36
- HashOf.new(schema, strict:)
32
+ def schema(schema, strict: false)
33
+ Schema.new(schema, strict:)
37
34
  end
38
35
 
39
36
  def impl(*, **)
40
37
  Impl.new(*, **)
41
38
  end
42
39
 
43
- def set_of(type) # rubocop:disable Naming/AccessorMethodName
40
+ def set_of(type)
44
41
  SetOf.new(type)
45
42
  end
46
43
 
@@ -52,6 +49,20 @@ module Uinit
52
49
  TypeOf.new(type)
53
50
  end
54
51
 
52
+ def string(**)
53
+ String.new(**)
54
+ end
55
+ alias str string
56
+
57
+ def integer(**)
58
+ Integer.new(**)
59
+ end
60
+ alias int integer
61
+
62
+ def float(**)
63
+ Float.new(**)
64
+ end
65
+
55
66
  def nilable
56
67
  Nil
57
68
  end
@@ -63,20 +74,6 @@ module Uinit
63
74
  end
64
75
  alias bool boolean
65
76
 
66
- def string
67
- Str
68
- end
69
- alias str string
70
-
71
- def integer
72
- Int
73
- end
74
- alias int integer
75
-
76
- def float
77
- Float
78
- end
79
-
80
77
  def hash
81
78
  Hsh
82
79
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uinit
4
+ module Type
5
+ class Float < TypeOf
6
+ # rubocop:disable Metrics/ParameterLists
7
+ def initialize(min: nil, max: nil, positive: nil, negative: nil, zero: nil, precision: nil, finite: true)
8
+ super(::Float)
9
+
10
+ @min = min
11
+ @max = max
12
+ @positive = positive
13
+ @negative = negative
14
+ @zero = zero
15
+ @precision = precision
16
+ @finite = finite
17
+ end
18
+ # rubocop:enable Metrics/ParameterLists
19
+
20
+ attr_reader :min, :max, :positive, :negative, :zero, :precision, :finite
21
+
22
+ # rubocop:disable Metrics/PerceivedComplexity
23
+ def is?(value)
24
+ return false unless super
25
+
26
+ return false if finite && !value.finite?
27
+ return false if min && value < min
28
+ return false if max && value > max
29
+ return false if positive == false && value.positive?
30
+ return false if positive == true && value <= 0
31
+ return false if negative == false && value.negative?
32
+ return false if negative == true && value >= 0
33
+ return false if zero == false && value.zero?
34
+ return false if zero == true && !value.zero?
35
+ return false if precision && !valid_precision?(value)
36
+
37
+ true
38
+ end
39
+
40
+ def check!(value, depth)
41
+ type_error!('Float must be finite (not Infinity or NaN)', depth) if finite && !value.finite?
42
+ type_error!("Float too small (minimum #{min})", depth) if min && value < min
43
+ type_error!("Float too large (maximum #{max})", depth) if max && value > max
44
+ type_error!('Float cannot be positive', depth) if positive == false && value.positive?
45
+ type_error!('Float must be positive', depth) if positive == true && value <= 0
46
+ type_error!('Float cannot be negative', depth) if negative == false && value.negative?
47
+ type_error!('Float must be negative', depth) if negative == true && value >= 0
48
+ type_error!('Float cannot be zero', depth) if zero == false && value.zero?
49
+ type_error!('Float must be zero', depth) if zero == true && !value.zero?
50
+
51
+ if precision && !valid_precision?(value)
52
+ type_error!("Float exceeds maximum precision of #{precision} decimal places", depth)
53
+ end
54
+
55
+ value
56
+ end
57
+ # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
58
+
59
+ private
60
+
61
+ def valid_precision?(value)
62
+ return true if precision.nil?
63
+
64
+ # Compter les décimales
65
+ decimal_places = value.to_s.split('.').last&.length || 0
66
+ decimal_places <= precision
67
+ end
68
+ end
69
+ end
70
+ end
data/lib/uinit/type/fn.rb CHANGED
@@ -7,7 +7,7 @@ module Uinit
7
7
  def initialize(arity = -1)
8
8
  super()
9
9
 
10
- raise ArgumentError, 'arity must be an Integer' unless arity.is_a?(Integer)
10
+ raise ArgumentError, 'arity must be an Integer' unless arity.is_a?(::Integer)
11
11
 
12
12
  @arity = arity
13
13
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uinit
4
+ module Type
5
+ class Integer < TypeOf
6
+ def initialize(min: nil, max: nil, positive: nil, negative: nil, zero: nil)
7
+ super(::Integer)
8
+
9
+ @min = min
10
+ @max = max
11
+ @positive = positive
12
+ @negative = negative
13
+ @zero = zero
14
+ end
15
+
16
+ attr_reader :min, :max, :positive, :negative, :zero
17
+
18
+ # rubocop:disable Metrics/PerceivedComplexity
19
+ def is?(value)
20
+ return false unless super
21
+
22
+ return false if min && value < min
23
+ return false if max && value > max
24
+ return false if positive == false && value.positive?
25
+ return false if positive == true && value <= 0
26
+ return false if negative == false && value.negative?
27
+ return false if negative == true && value >= 0
28
+ return false if zero == false && value.zero?
29
+ return false if zero == true && !value.zero?
30
+
31
+ true
32
+ end
33
+
34
+ def check!(value, depth)
35
+ type_error!("Integer too small (minimum #{min})", depth) if min && value < min
36
+ type_error!("Integer too large (maximum #{max})", depth) if max && value > max
37
+ type_error!('Integer cannot be positive', depth) if positive == false && value.positive?
38
+ type_error!('Integer must be positive', depth) if positive == true && value <= 0
39
+ type_error!('Integer cannot be negative', depth) if negative == false && value.negative?
40
+ type_error!('Integer must be negative', depth) if negative == true && value >= 0
41
+ type_error!('Integer cannot be zero', depth) if zero == false && value.zero?
42
+ type_error!('Integer must be zero', depth) if zero == true && !value.zero?
43
+
44
+ value
45
+ end
46
+ # rubocop:enable Metrics/PerceivedComplexity
47
+ end
48
+ end
49
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Uinit
4
4
  module Type
5
- class HashOf < Base
5
+ class Schema < Base
6
6
  def self.from?(schema)
7
7
  schema.is_a?(Hash)
8
8
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uinit
4
+ module Type
5
+ class String < TypeOf
6
+ def initialize(empty: true, min_length: nil, max_length: nil, format: nil)
7
+ super(::String)
8
+
9
+ @empty = empty
10
+ @min_length = min_length
11
+ @max_length = max_length
12
+ @format = format
13
+ end
14
+
15
+ attr_reader :empty, :min_length, :max_length, :format
16
+
17
+ # rubocop:disable Metrics/PerceivedComplexity
18
+ def is?(value)
19
+ return false unless super
20
+
21
+ return false if !empty && (value.empty? || value.match?(/^\s+$/))
22
+ return false if min_length && value.length < min_length
23
+ return false if max_length && value.length > max_length
24
+ return false if format && !value.match?(format)
25
+
26
+ true
27
+ end
28
+
29
+ def check!(value, depth)
30
+ if !empty && (value.empty? || value.match?(/^\s+$/))
31
+ type_error!('String cannot be empty or contain only whitespace', depth)
32
+ end
33
+
34
+ if min_length && value.length < min_length
35
+ type_error!("String too short (minimum #{min_length} characters)", depth)
36
+ end
37
+
38
+ if max_length && value.length > max_length
39
+ type_error!("String too long (maximum #{max_length} characters)", depth)
40
+ end
41
+
42
+ type_error!('String doesn\'t match required pattern', depth) if format && !value.match?(format)
43
+
44
+ value
45
+ end
46
+ # rubocop:enable Metrics/PerceivedComplexity
47
+ end
48
+ end
49
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Uinit
4
4
  module Type
5
- VERSION = '0.1.4'
5
+ VERSION = '0.1.6'
6
6
  end
7
7
  end
data/lib/uinit/type.rb CHANGED
@@ -21,7 +21,7 @@ module Uinit
21
21
 
22
22
  def self.from(arg)
23
23
  klass =
24
- [Base, TypeOf, ArrayOf, SetOf, HashOf, Check, Type, Const].find do |type_class|
24
+ [Base, TypeOf, ArrayOf, SetOf, Schema, Check, Type, Const].find do |type_class|
25
25
  type_class.from?(arg)
26
26
  end
27
27
 
data/uinit-type.gemspec CHANGED
@@ -28,10 +28,5 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.add_runtime_dependency 'zeitwerk', '~> 2.6'
30
30
 
31
- spec.add_development_dependency 'bundler'
32
- spec.add_development_dependency 'pry'
33
- spec.add_development_dependency 'rake'
34
- spec.add_development_dependency 'rspec'
35
- spec.add_development_dependency 'rubocop'
36
31
  spec.metadata['rubygems_mfa_required'] = 'true'
37
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uinit-type
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kimoja
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-21 00:00:00.000000000 Z
11
+ date: 2025-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -24,76 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.6'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: pry
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
27
  description: Dynamic type checker
98
28
  email:
99
29
  - joakim.carrilho@cheerz.com
@@ -113,12 +43,15 @@ files:
113
43
  - lib/uinit/type/context.rb
114
44
  - lib/uinit/type/error.rb
115
45
  - lib/uinit/type/extensions.rb
46
+ - lib/uinit/type/float.rb
116
47
  - lib/uinit/type/fn.rb
117
48
  - lib/uinit/type/generic.rb
118
- - lib/uinit/type/hash_of.rb
119
49
  - lib/uinit/type/impl.rb
50
+ - lib/uinit/type/integer.rb
120
51
  - lib/uinit/type/operators.rb
52
+ - lib/uinit/type/schema.rb
121
53
  - lib/uinit/type/set_of.rb
54
+ - lib/uinit/type/string.rb
122
55
  - lib/uinit/type/type.rb
123
56
  - lib/uinit/type/type_of.rb
124
57
  - lib/uinit/type/version.rb
@@ -148,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
81
  - !ruby/object:Gem::Version
149
82
  version: '0'
150
83
  requirements: []
151
- rubygems_version: 3.4.6
84
+ rubygems_version: 3.5.3
152
85
  signing_key:
153
86
  specification_version: 4
154
87
  summary: Dynamic type checker