data_model 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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