camel_snake_struct 0.2.1 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +6 -0
- data/CHANGELOG.md +6 -0
- data/README.md +55 -0
- data/bin/rake +1 -1
- data/bin/rspec +1 -1
- data/bin/rubocop +1 -1
- data/camel_snake_struct.gemspec +1 -1
- data/lib/camel_snake_struct.rb +29 -3
- metadata +3 -3
- /data/{gems.rb → Gemfile} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f4978b18cb18f1bd33284ad21a540552ef8a558fcdcff4fb0296c0f2d1c444f
|
4
|
+
data.tar.gz: a830f31ca20fcff51e85832afa26e5cfa6c02d0a52d080427223c6e3bdd16342
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 309e7c1c9df867de7930257defd3588433f12248bc43e448f38c8132d66b20d34ebeb41ea58b9198414ed81769467853e98ddec1ed90319c3ea16d31db1cc2a3
|
7
|
+
data.tar.gz: aa718371a22f920b35ad630f344d4bae3ed07081bd8a85771bf37c3b059f541985ea646d375c2df7a2e7bc0c1f9781602cbdaf99421c09dff3c92c9994c3fa62
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# 0.3.1
|
2
|
+
* handle situation where the key of the hash will not make a valid method, EG { "2020-01-02 19:00:00 UTC" => [""] }
|
3
|
+
|
4
|
+
# 0.3.0
|
5
|
+
* Learning Structs store meta data about the shape of the hash from the examples provided. This can be used with tapioca custom DSL compilers to generate sorbet types
|
6
|
+
|
1
7
|
# 0.2.1
|
2
8
|
* activesupport < 8.0
|
3
9
|
|
data/README.md
CHANGED
@@ -67,6 +67,61 @@ puts result3.date.timezone # nil
|
|
67
67
|
puts result3.date.unix_time # nil
|
68
68
|
```
|
69
69
|
|
70
|
+
Learning Structs store meta data about the shape of the hash from the examples provided.
|
71
|
+
This can be used with tapioca custom DSL compilers to generate sorbet types
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
MyLoadedStruct = Class.new(CamelSnakeStruct)
|
75
|
+
MyLoadedStruct.example('data' => [{ 'name' => 'Jeff' }], 'errors' => [], 'date' => { 'timezone' => 'UTC', 'unixTime' => 0})
|
76
|
+
|
77
|
+
puts MyLoadedStruct.types_meta_data
|
78
|
+
# {"data"=>#<struct CamelSnakeStruct::Type__Meta__Data class_types=#<Set: {MyLoadedStruct::Datum}>, array=true>, "errors"=>#<struct CamelSnakeStruct::Type__Meta__Data class_types=#<Set: {}>, array=true>, "date"=>#<struct CamelSnakeStruct::Type__Meta__Data class_types=#<Set: {MyLoadedStruct::Date}>, array=false>}
|
79
|
+
```
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# typed: true
|
83
|
+
|
84
|
+
module Tapioca
|
85
|
+
module Compilers
|
86
|
+
class CamelSnakeStructCompiler < Tapioca::Dsl::Compiler
|
87
|
+
extend T::Sig
|
88
|
+
|
89
|
+
ConstantType = type_member {{ fixed: T.class_of(CamelSnakeStruct) }}
|
90
|
+
|
91
|
+
sig { override.returns(T::Enumerable[Module]) }
|
92
|
+
def self.gather_constants
|
93
|
+
all_classes.select do |c|
|
94
|
+
c < ::CamelSnakeStruct && !c.types_meta_data.empty?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
sig { override.void }
|
99
|
+
def decorate
|
100
|
+
root.create_path(constant) do |klass|
|
101
|
+
constant.types_meta_data.each do |name, meta_data|
|
102
|
+
classes = meta_data.classes.to_a.map{|a| [TrueClass,FalseClass].include?(a) ? "T::Boolean" : a.to_s }.uniq
|
103
|
+
return_type = if classes.size == 1
|
104
|
+
classes.first.to_s
|
105
|
+
else
|
106
|
+
"T.any(#{classes.join(', ')})"
|
107
|
+
end
|
108
|
+
if meta_data.array
|
109
|
+
klass.create_method(name.to_s, parameters: [], return_type: "T::Array[#{return_type}]")
|
110
|
+
elsif return_type == 'NilClass' || return_type == 'String'
|
111
|
+
klass.create_method(name.to_s, parameters: [], return_type: 'T.nilable(String)')
|
112
|
+
else
|
113
|
+
klass.create_method(name.to_s, parameters: [], return_type: return_type)
|
114
|
+
end
|
115
|
+
klass.create_method("#{name}?", parameters: [], return_type: 'T::Boolean')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
```
|
123
|
+
|
124
|
+
|
70
125
|
### Limitations
|
71
126
|
|
72
127
|
* Expects to receive a hash
|
data/bin/rake
CHANGED
data/bin/rspec
CHANGED
data/bin/rubocop
CHANGED
data/camel_snake_struct.gemspec
CHANGED
data/lib/camel_snake_struct.rb
CHANGED
@@ -3,10 +3,18 @@ require 'active_support/core_ext/string'
|
|
3
3
|
|
4
4
|
class CamelSnakeStruct
|
5
5
|
def self.example(data)
|
6
|
+
raise ArgumentError, "Examples are for Learning Structs" if self == CamelSnakeStruct
|
7
|
+
|
6
8
|
new_example = new(data)
|
7
9
|
walk_example(new_example)
|
8
10
|
end
|
9
11
|
|
12
|
+
Type__Meta__Data = Struct.new(:class_types, :array) do
|
13
|
+
def classes
|
14
|
+
class_types.to_a
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
10
18
|
def self.walk_example(new_example)
|
11
19
|
new_example.send(:_method_to_key).keys.each do |m_name|
|
12
20
|
result = new_example.public_send(m_name)
|
@@ -15,15 +23,33 @@ class CamelSnakeStruct
|
|
15
23
|
elsif result.is_a?(Array) && result.first.is_a?(CamelSnakeStruct)
|
16
24
|
walk_example(result.first)
|
17
25
|
end
|
26
|
+
|
27
|
+
store_meta_data(new_example.class, m_name, result)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.store_meta_data(example_class, m_name, result)
|
32
|
+
types_meta_data = (example_class.types_meta_data[m_name] ||= Type__Meta__Data.new(Set.new, false))
|
33
|
+
if result.is_a?(Array)
|
34
|
+
types_meta_data.array = true
|
35
|
+
result.map(&:class).each { |c| types_meta_data.class_types << c }
|
36
|
+
else
|
37
|
+
types_meta_data.class_types << result.class
|
18
38
|
end
|
19
39
|
end
|
20
40
|
|
41
|
+
def self.types_meta_data
|
42
|
+
@types_meta_data ||= {}
|
43
|
+
end
|
44
|
+
|
21
45
|
def initialize(hash)
|
22
46
|
@_raw_hash = hash&.to_h || {}
|
23
47
|
@_method_to_key = @_raw_hash.keys.each_with_object({}) do |key, mapping|
|
24
|
-
|
25
|
-
|
26
|
-
|
48
|
+
if key =~ /^[A-Za-z]/
|
49
|
+
normalize_key = key.gsub('@', '').gsub(/\.|\s/, '_')
|
50
|
+
mapping[normalize_key] = key
|
51
|
+
mapping[normalize_key.underscore] = key
|
52
|
+
end
|
27
53
|
end
|
28
54
|
end
|
29
55
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: camel_snake_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grant Petersen-Speelman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -41,6 +41,7 @@ files:
|
|
41
41
|
- ".rspec"
|
42
42
|
- ".rubocop.yml"
|
43
43
|
- CHANGELOG.md
|
44
|
+
- Gemfile
|
44
45
|
- README.md
|
45
46
|
- Rakefile
|
46
47
|
- bin/console
|
@@ -49,7 +50,6 @@ files:
|
|
49
50
|
- bin/rubocop
|
50
51
|
- bin/setup
|
51
52
|
- camel_snake_struct.gemspec
|
52
|
-
- gems.rb
|
53
53
|
- lib/camel_snake_struct.rb
|
54
54
|
homepage: https://github.com/NEXL-LTS/camel_snake_struct-ruby
|
55
55
|
licenses: []
|
/data/{gems.rb → Gemfile}
RENAMED
File without changes
|