camille 0.5.8 → 0.5.10

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: 60434d249fd905789f0c9fd812d097163cda296655c56fde57569269d8188e39
4
- data.tar.gz: 422d993e72473270985d6ade710ae39e3ada83ef85942e83291176dc8bff9dcc
3
+ metadata.gz: 247a0f8bf5424ac104e9c4b71a073c4b7a6e38399434dc57a9a3b13f40b72d0b
4
+ data.tar.gz: db54f6d86bab52b6f50bc09cc3aa42c4b2b9c00c10a484394de270bc4a1c8351
5
5
  SHA512:
6
- metadata.gz: 6561b6b4c62f85c22d28b27c9693a1dfe8a3cccaaf95251d3995b50b0457363ea82ef971fa03d10959bcf505ee0188b2189b6de5d3cd984930830bc2a9bdcd3e
7
- data.tar.gz: 4266ecec3ab26f2e1af40b83fe60d337ed81b8fa6f953200c14f6e1dfb2ffe9519ea2d0519882b4790cc34cc1c7f84b18fb8481d0ec3cba88636c73236998761
6
+ metadata.gz: aa084c1032e46b35a3330a5500bdf2a31dd19d57585ca7fd12bbd8c93083d1f2b5f9df1c53c68dd10ab53167d27fe8f4680cf4a7f8f8567f4e9dd3b279d13022
7
+ data.tar.gz: be8d2cc143b82614cd99ef6d0b38c2fcc756152a9856db840e04595f1d566d97e8c01f51caadcb7ba88ff9d00924f3ff1e048a821b9a08f50a164c3047b8aba5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.10
4
+
5
+ ### Added
6
+
7
+ * Added intersection and boolean literal support to `Camille::Syntax`
8
+
9
+ ## 0.5.9
10
+
11
+ ### Added
12
+
13
+ * Added intersection type
14
+ * Added #print to Camille::TypeError
15
+
16
+ ### Changed
17
+
18
+ * Typecheck will no longer remove fields from a hash if those fields are not presented in type schema
19
+
20
+ ### Fixed
21
+
22
+ * Fixed the wrong literal generated by an array of unions
23
+
3
24
  ## 0.5.8
4
25
 
5
26
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- camille (0.5.8)
4
+ camille (0.5.10)
5
5
  rails (>= 6.1, < 8)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -153,6 +153,8 @@ params(
153
153
  }[]
154
154
  # a union type is two types connected by '|'
155
155
  union: Number | String,
156
+ # an intersection type is two types connected by '&'
157
+ intersection: { id: Number } & { name: String },
156
158
  # a tuple type is several types put inside '[]'
157
159
  tuple: [Number, String, Boolean],
158
160
  # a field followed by '?' is optional, the same as in TypeScript
@@ -7,6 +7,10 @@ module Camille
7
7
  Camille::Types::Union.new(self, other)
8
8
  end
9
9
 
10
+ def & other
11
+ Camille::Types::Intersection.new(self, other)
12
+ end
13
+
10
14
  def []
11
15
  Camille::Types::Array.new(self)
12
16
  end
@@ -24,6 +28,10 @@ module Camille
24
28
  Camille::Type.instance(self) | other
25
29
  end
26
30
 
31
+ def self.& other
32
+ Camille::Type.instance(self) & other
33
+ end
34
+
27
35
  def self.[]
28
36
  Camille::Type.instance(self)[]
29
37
  end
@@ -14,6 +14,10 @@ module Camille
14
14
  def | other
15
15
  Camille::Types::Union.new(Camille::Types::Object.new(self), other)
16
16
  end
17
+
18
+ def & other
19
+ Camille::Types::Intersection.new(Camille::Types::Object.new(self), other)
20
+ end
17
21
  end
18
22
 
19
23
  refine ::Array do
@@ -71,5 +75,33 @@ module Camille
71
75
  Camille::Types::Union.new(Camille::Types::StringLiteral.new(self), other)
72
76
  end
73
77
  end
78
+
79
+ refine TrueClass do
80
+ def [] key = NULL_VALUE
81
+ if key == NULL_VALUE
82
+ Camille::Types::BooleanLiteral.new(true)[]
83
+ else
84
+ super
85
+ end
86
+ end
87
+
88
+ def | other
89
+ Camille::Types::Union.new(Camille::Types::BooleanLiteral.new(true), other)
90
+ end
91
+ end
92
+
93
+ refine FalseClass do
94
+ def [] key = NULL_VALUE
95
+ if key == NULL_VALUE
96
+ Camille::Types::BooleanLiteral.new(false)[]
97
+ else
98
+ super
99
+ end
100
+ end
101
+
102
+ def | other
103
+ Camille::Types::Union.new(Camille::Types::BooleanLiteral.new(false), other)
104
+ end
105
+ end
74
106
  end
75
107
  end
@@ -17,5 +17,9 @@ module Camille
17
17
  def basic?
18
18
  !!@message
19
19
  end
20
+
21
+ def print io = STDOUT
22
+ Camille::TypeErrorPrinter.new(self).print io
23
+ end
20
24
  end
21
25
  end
@@ -0,0 +1,39 @@
1
+ module Camille
2
+ module Types
3
+ class Intersection < Camille::BasicType
4
+ class ArgumentError < ::ArgumentError; end
5
+
6
+ attr_reader :left, :right
7
+
8
+ def initialize left, right
9
+ @left = Camille::Type.instance left
10
+ @right = Camille::Type.instance right
11
+ end
12
+
13
+ def transform_and_check value
14
+ left_error, left_transformed = @left.transform_and_check value
15
+ if left_error
16
+ error = Camille::TypeError.new(
17
+ 'intersection.left' => left_error
18
+ )
19
+ [error, nil]
20
+ else
21
+ right_error, right_transformed = @right.transform_and_check left_transformed
22
+ if right_error
23
+ error = Camille::TypeError.new(
24
+ 'intersection.right' => right_error
25
+ )
26
+ [error, nil]
27
+ else
28
+ [nil, right_transformed]
29
+ end
30
+ end
31
+ end
32
+
33
+ def literal
34
+ "(#{@left.literal} & #{@right.literal})"
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -11,12 +11,17 @@ module Camille
11
11
 
12
12
  def transform_and_check value
13
13
  if value.is_a? Hash
14
- transform_and_check_results = @fields.map do |key, type|
15
- error, transformed = type.transform_and_check(value[key])
16
- if @optional_keys.include?(key) && !error && transformed.nil?
17
- nil
14
+ keys = (@fields.keys + value.keys).uniq
15
+ transform_and_check_results = keys.map do |key|
16
+ if type = @fields[key]
17
+ error, transformed = type.transform_and_check(value[key])
18
+ if @optional_keys.include?(key) && !error && transformed.nil?
19
+ nil
20
+ else
21
+ [key, [error, transformed]]
22
+ end
18
23
  else
19
- [key, type.transform_and_check(value[key])]
24
+ [key, [nil, value[key]]]
20
25
  end
21
26
  end.compact
22
27
 
@@ -63,7 +68,7 @@ module Camille
63
68
  def check_case_conversion_safe sym
64
69
  str = sym.to_s
65
70
  if str != str.camelize.underscore
66
- raise ArgumentError.new("Only keys satisfying `key.to_s == key.to_s.caamelize.underscore` can be used.")
71
+ raise ArgumentError.new("Only keys satisfying `key.to_s == key.to_s.camelize.underscore` can be used.")
67
72
  end
68
73
  end
69
74
  end
@@ -27,7 +27,7 @@ module Camille
27
27
  end
28
28
 
29
29
  def literal
30
- "#{@left.literal} | #{@right.literal}"
30
+ "(#{@left.literal} | #{@right.literal})"
31
31
  end
32
32
  end
33
33
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Camille
4
- VERSION = "0.5.8"
4
+ VERSION = "0.5.10"
5
5
  end
data/lib/camille.rb CHANGED
@@ -13,6 +13,7 @@ require_relative "camille/types/object"
13
13
  require_relative "camille/types/null"
14
14
  require_relative "camille/types/undefined"
15
15
  require_relative "camille/types/union"
16
+ require_relative "camille/types/intersection"
16
17
  require_relative "camille/types/tuple"
17
18
  require_relative "camille/types/any"
18
19
  require_relative "camille/types/number_literal"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: camille
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.8
4
+ version: 0.5.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - 辻彩
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-26 00:00:00.000000000 Z
11
+ date: 2023-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -78,6 +78,7 @@ files:
78
78
  - lib/camille/types/array.rb
79
79
  - lib/camille/types/boolean.rb
80
80
  - lib/camille/types/boolean_literal.rb
81
+ - lib/camille/types/intersection.rb
81
82
  - lib/camille/types/null.rb
82
83
  - lib/camille/types/number.rb
83
84
  - lib/camille/types/number_literal.rb