data_model 0.1.0 → 0.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: c4f03f11c2ab99a1d4e680f8d0ef911b6508bc2802795c7d0ede161f88ea366e
4
- data.tar.gz: d5278afd3d3aa5a14c4972ee8024d94b86722ac5bfe9a5a01e6a21c521a8e29a
3
+ metadata.gz: c62c4d806d3e7bbbac5e4031d91b6f681dcb2697fd09e6a81c90e1b3cdc95ad6
4
+ data.tar.gz: 6bde7c362323265251688a38946ea992451fdd9d1c57838d6dfaa563a49b814d
5
5
  SHA512:
6
- metadata.gz: f5e57acc83fbc9657ccf2923570d1bc8b91ddcb4f097a74b75335130552df0f91463e59a435f7f62c841bf29aafdd3ca5d9ca88099294d183fb7f1e1329b1a53
7
- data.tar.gz: 88b48a214de563da00ff1db868a18a1319c0b3d290317d940738f2eb1c516d51eaee5435ce9d054594fb4a1aef0f87fa0f23ccd1b02fa67c33d7067640a86863
6
+ metadata.gz: 7ed6672730afd6792a13c753ad5bc96694d5dc8982d3411b3d0af3f25e5682096f6a08c939837f473983f264960e1047d076c3304ca98618c020796ab312449f
7
+ data.tar.gz: 2a849997505c5d60c04fc48a51bd5049eb4ee2b90a2d5490929261fb1c03fed818e87834bdc800d748e71d5fd7fd454a19c2664e3c28044c486884149452feed
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- data_model (0.1.0)
4
+ data_model (0.2.0)
5
5
  sorbet
6
6
  zeitwerk
7
7
 
@@ -4,9 +4,12 @@ module DataModel
4
4
  class Builtin::String < Type
5
5
  include Errors
6
6
 
7
+ TFormatter = T.type_alias { T.proc.params(val: String).returns(T::Boolean) }
8
+
7
9
  class Arguments < T::Struct
8
10
  prop :optional, T::Boolean, default: false
9
11
  prop :allow_blank, T::Boolean, default: true
12
+ prop :format, T.nilable(T.any(String, Regexp, TFormatter)), default: nil
10
13
  prop :included, T::Array[String], default: []
11
14
  prop :excluded, T::Array[String], default: []
12
15
  end
@@ -42,22 +45,40 @@ module DataModel
42
45
  end
43
46
  end
44
47
 
48
+ val = T.cast(val, String)
49
+
50
+ # format
51
+ fmt = args.format
52
+ if fmt
53
+ case fmt
54
+ when String
55
+ if !val.match?(fmt)
56
+ err.add(format_error(fmt, val))
57
+ end
58
+ when Regexp
59
+ if !val.match?(fmt)
60
+ err.add(format_error(fmt, val))
61
+ end
62
+ when Proc
63
+ if !fmt.call(val)
64
+ err.add(format_error("<Custom Proc>", val))
65
+ end
66
+ end
67
+ end
68
+
45
69
  # inclusion
46
70
  if args.included.any? && !args.included.include?(val)
47
71
  err.add(inclusion_error(args.included))
48
- return [val, err]
49
72
  end
50
73
 
51
74
  # exclusion
52
75
  if args.excluded.any? && args.excluded.include?(val)
53
76
  err.add(exclusion_error(args.excluded))
54
- return [val, err]
55
77
  end
56
78
 
57
79
  # allow blank
58
- if val.is_a?(String) && !args.allow_blank && val.empty?
80
+ if !args.allow_blank && val.empty?
59
81
  err.add(blank_error)
60
- return [val, err]
61
82
  end
62
83
 
63
84
  # done
@@ -76,6 +76,12 @@ module DataModel
76
76
  [:latest, [latest, val]]
77
77
  end
78
78
 
79
+ # Format applies when value does not match a format
80
+ sig { params(format: Object, val: String).returns(TError) }
81
+ def format_error(format, val)
82
+ [:format, [format, val]]
83
+ end
84
+
79
85
  ## Messages
80
86
 
81
87
  # Generate a message for a type error
@@ -144,6 +150,12 @@ module DataModel
144
150
  "value #{val} is after #{latest}"
145
151
  end
146
152
 
153
+ # Generate a message for a value that does not match the format
154
+ sig { params(format: Object, val: String).returns(String) }
155
+ def format_error_message(format, val)
156
+ "value #{val} does not match format #{format}"
157
+ end
158
+
147
159
  ## API
148
160
  # TODO: split this file
149
161
 
@@ -161,6 +173,7 @@ module DataModel
161
173
  TSetCtx = T.type_alias { T::Array[Symbol] }
162
174
  TWithinCtx = T.type_alias { [Numeric, Numeric] }
163
175
  TWithinTemporalCtx = T.type_alias { [TTemporal, TTemporal] }
176
+ TFormatCtx = T.type_alias { [Object, String] }
164
177
 
165
178
  # Get the error message builders
166
179
  sig { returns(TErrorMessages) }
@@ -223,6 +236,11 @@ module DataModel
223
236
  register_error_message(:blank) do
224
237
  blank_error_message
225
238
  end
239
+
240
+ register_error_message(:format) do |ctx|
241
+ format, val = T.let(ctx, TFormatCtx)
242
+ format_error_message(format, val)
243
+ end
226
244
  end
227
245
 
228
246
  @error_messages
@@ -18,6 +18,39 @@ module DataModel
18
18
  )
19
19
  end
20
20
 
21
+ sig { returns(Example) }
22
+ def email
23
+ Example.new(
24
+ [:string, { format: "@" }],
25
+ variants: {
26
+ valid: "foo@bar.com",
27
+ invalid: "invalid"
28
+ },
29
+ )
30
+ end
31
+
32
+ sig { returns(Example) }
33
+ def email_regexp
34
+ Example.new(
35
+ [:string, { format: /@/ }],
36
+ variants: {
37
+ valid: "foo@bar.com",
38
+ invalid: "invalid"
39
+ },
40
+ )
41
+ end
42
+
43
+ sig { returns(Example) }
44
+ def email_proc
45
+ Example.new(
46
+ [:string, { format: ->(val) { val.match?(/@/) } }],
47
+ variants: {
48
+ valid: "foo@bar.com",
49
+ invalid: "invalid"
50
+ },
51
+ )
52
+ end
53
+
21
54
  sig { returns(Example) }
22
55
  def optional
23
56
  Example.new(
@@ -1,5 +1,5 @@
1
1
  # typed: strict
2
2
 
3
3
  module DataModel
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Briggs
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-09 00:00:00.000000000 Z
11
+ date: 2023-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet