jsoncop 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -22
- data/lib/jsoncop/analyzer.rb +29 -17
- data/lib/jsoncop/generator.rb +50 -22
- data/lib/jsoncop/model/attribute.rb +21 -0
- data/lib/jsoncop/model/model.rb +1 -0
- data/lib/jsoncop/model/transformer.rb +11 -0
- data/lib/jsoncop/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d68292e78bb6f41e6f716a177702537eb7af012
|
4
|
+
data.tar.gz: 7d9f747880b9f1016543e68427a65efe25530066
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 455670249f7eb076763eb09268602d7658ab4446bd6e70a4c164aa8e4b29c00c9b65a8d4910883bd0cc4f7c39b14a0b76b6b32845cb59374a76e52cfc5167024
|
7
|
+
data.tar.gz: 05b4142380220cdd1cc5e645225ab6482901508b2b1b0bf4258dbc996f0fd1b6fa1e7d184f0e776a3fe87ddb48aa7b75786bc0adcb13ea02fd407bd0c7bb42a6
|
data/README.md
CHANGED
@@ -19,44 +19,26 @@ let person = Person.parse(json: json)
|
|
19
19
|
|
20
20
|
## Usage
|
21
21
|
|
22
|
-
Define a model with and
|
22
|
+
Define a model with and **add `//@jsoncop` just before model definition line**:
|
23
23
|
|
24
24
|
```swift
|
25
|
-
|
26
|
-
|
25
|
+
//@jsoncop
|
27
26
|
struct Person {
|
28
27
|
let id: Int
|
29
28
|
let name: String
|
30
|
-
let createdAt: Date
|
31
|
-
|
32
|
-
static func JSONKeyPathByPropertyKey() -> [String: String] {
|
33
|
-
return [
|
34
|
-
"id": "id",
|
35
|
-
"name": "name",
|
36
|
-
"createdAt": "createdAt"
|
37
|
-
]
|
38
|
-
}
|
39
|
-
|
40
|
-
static func createdAtJSONTransformer(value: Any) -> Date? {
|
41
|
-
guard let value = value as? Double else { return nil }
|
42
|
-
return Date(timeIntervalSinceNow: value)
|
43
|
-
}
|
44
29
|
}
|
45
30
|
```
|
46
|
-
|
47
|
-
> DO NOT forget to add "// jsoncop: enabled" before struct.
|
48
|
-
|
49
31
|
Run `cop install` in project root folder.
|
50
32
|
|
51
33
|
```shell
|
52
34
|
$ cop install
|
53
35
|
```
|
54
36
|
|
55
|
-
This will generate several parsing methods in current file:
|
37
|
+
This will generate several parsing methods in current file without affecting other part of your codes:
|
56
38
|
|
57
39
|
![](./images/jsoncop-demo.png)
|
58
40
|
|
59
|
-
All the code between
|
41
|
+
All the code between `// MARK: - JSONCop-Start` and `// MARK: - JSONCop-End` and will be replaced when re-run `cop install` in current project folder. Other codes will remain unchanged. Please don't write any codes in this area.
|
60
42
|
|
61
43
|
## Installation
|
62
44
|
|
data/lib/jsoncop/analyzer.rb
CHANGED
@@ -3,16 +3,18 @@ module JSONCop
|
|
3
3
|
|
4
4
|
require 'jsoncop/model/model'
|
5
5
|
require 'jsoncop/model/attribute'
|
6
|
+
require 'jsoncop/model/transformer'
|
6
7
|
|
7
|
-
JSON_COP_ENABLED =
|
8
|
+
JSON_COP_ENABLED = /@jsoncop/
|
8
9
|
|
10
|
+
NEED_PARSING_CONTENT = /(\/\/\s*@jsoncop\s+(?:struct|class)(?:.|\s)*?\n})/
|
9
11
|
MODEL_NAME_REGEX = /(struct|class)\s+(.+)\s*{/
|
10
12
|
ATTRIBUTE_REGEX = /^\s+(let|var)\s(.+):(.+)/
|
11
|
-
JSON_TRANSFORMER_REGEX = /^\s+static\s+func\s+(.+)JSONTransformer.+->.+/
|
13
|
+
JSON_TRANSFORMER_REGEX = /^\s+static\s+func\s+(.+)JSONTransformer\(.+?\:(.+)\).+->.+/
|
12
14
|
JSON_BY_PROPERTY_HASH_REGEX = /static\s+func\s+JSONKeyPathByPropertyKey\(\)\s*->\s*\[String\s*:\s*String\]\s*{\s*return\s*(\[[\s"a-z0-9A-Z_\-:\[\],]*)}/
|
13
15
|
|
14
16
|
attr_reader :file_path
|
15
|
-
attr_accessor :
|
17
|
+
attr_accessor :current_model
|
16
18
|
|
17
19
|
def initialize(file_path)
|
18
20
|
@file_path = file_path
|
@@ -21,23 +23,33 @@ module JSONCop
|
|
21
23
|
def analyze!
|
22
24
|
content = File.read file_path
|
23
25
|
return unless content =~ JSON_COP_ENABLED
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
models = []
|
27
|
+
content.scan(NEED_PARSING_CONTENT).flatten.each do |content|
|
28
|
+
content.each_line do |line|
|
29
|
+
if line =~ MODEL_NAME_REGEX
|
30
|
+
model_name = line.scan(MODEL_NAME_REGEX).flatten.last
|
31
|
+
@current_model = Model::Model.new model_name
|
32
|
+
models << @current_model
|
33
|
+
elsif line =~ ATTRIBUTE_REGEX
|
34
|
+
result = line.scan(ATTRIBUTE_REGEX).flatten
|
35
|
+
@current_model.attributes << Model::Attribute.new(result[1], result[2])
|
36
|
+
elsif line =~ JSON_TRANSFORMER_REGEX
|
37
|
+
result = line.scan(JSON_TRANSFORMER_REGEX).flatten
|
38
|
+
@current_model.transformers << Model::Transformer.new(result[0], result[1])
|
39
|
+
end
|
34
40
|
end
|
41
|
+
|
42
|
+
json_attr_list = content.scan(JSON_BY_PROPERTY_HASH_REGEX).flatten.first
|
43
|
+
if json_attr_list
|
44
|
+
json_attr_list.gsub!(/[(\[\]"\s)]*/, '')
|
45
|
+
@current_model.attr_json_hash = Hash[json_attr_list.split(",").map {
|
46
|
+
|attr_json_pair| attr_json_pair.split(":").reverse
|
47
|
+
}]
|
48
|
+
end
|
49
|
+
|
35
50
|
end
|
36
51
|
|
37
|
-
|
38
|
-
json_attr_list.gsub!(/[(\[\]"\s)]*/, '')
|
39
|
-
@model.attr_json_hash = Hash[json_attr_list.split(",").map { |attr_json_pair| attr_json_pair.split(":").reverse }]
|
40
|
-
@model
|
52
|
+
models
|
41
53
|
end
|
42
54
|
|
43
55
|
end
|
data/lib/jsoncop/generator.rb
CHANGED
@@ -7,47 +7,75 @@ module JSONCop
|
|
7
7
|
attr_reader :file_path
|
8
8
|
attr_reader :model
|
9
9
|
|
10
|
-
def initialize(file_path,
|
10
|
+
def initialize(file_path, models)
|
11
11
|
@file_path = file_path
|
12
|
-
@
|
12
|
+
@models = models
|
13
13
|
end
|
14
14
|
|
15
15
|
def generate!
|
16
|
-
jsoncop_generate_start =
|
17
|
-
jsoncop_generate_end =
|
16
|
+
jsoncop_generate_start = /\/\/ MARK: \- JSONCop\-Start/
|
17
|
+
jsoncop_generate_end = /\/\/ MARK: \- JSONCop\-End/
|
18
18
|
content = File.read file_path
|
19
19
|
if content.match(jsoncop_generate_start) && content.match(jsoncop_generate_end)
|
20
|
-
content.gsub!(/\/\/
|
20
|
+
content.gsub!(/\/\/ MARK: \- JSONCop\-Start[^$]*MARK: \- JSONCop\-End/, json_cop_template)
|
21
|
+
else
|
22
|
+
content += json_cop_template
|
21
23
|
end
|
22
|
-
File.write file_path, content
|
24
|
+
File.write file_path, content
|
23
25
|
end
|
24
26
|
|
25
27
|
def json_cop_template
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
extension #{
|
30
|
-
static func parse(json:
|
31
|
-
guard
|
32
|
-
|
28
|
+
result = "// MARK: - JSONCop-Start\n\n"
|
29
|
+
@models.each do |model|
|
30
|
+
result += <<-JSONCOP
|
31
|
+
extension #{model.name} {
|
32
|
+
static func parse(json: Any) -> #{model.name}? {
|
33
|
+
guard let json = json as? [String: Any] else { return nil }
|
34
|
+
guard #{json_parsing_template model} else { return nil }
|
35
|
+
return #{model.name}(#{model.key_value_pair})
|
33
36
|
}
|
34
|
-
static func
|
37
|
+
static func parses(jsons: Any) -> [#{model.name}] {
|
38
|
+
guard let jsons = jsons as? [[String: Any]] else { return [] }
|
35
39
|
return jsons.flatMap(parse)
|
36
40
|
}
|
37
41
|
}
|
38
42
|
|
39
|
-
|
40
|
-
|
43
|
+
JSONCOP
|
44
|
+
# result += <<-CODING
|
45
|
+
# extension #{model.name}: NSCoding {
|
46
|
+
# func encode(with aCoder: NSCoder) {
|
47
|
+
#
|
48
|
+
# }
|
49
|
+
#
|
50
|
+
# init?(coder decoder: NSCoder) {
|
51
|
+
# guard #{decode_template model} else { return nil }
|
52
|
+
#
|
53
|
+
# self.init(#{model.key_value_pair})
|
54
|
+
# }
|
55
|
+
# }
|
56
|
+
#
|
57
|
+
# CODING
|
58
|
+
end
|
59
|
+
result += "// MARK: - JSONCop-End"
|
60
|
+
result
|
41
61
|
end
|
42
62
|
|
43
|
-
def json_parsing_template
|
44
|
-
|
45
|
-
|
46
|
-
|
63
|
+
def json_parsing_template(model)
|
64
|
+
model.attributes.map do |attr|
|
65
|
+
transformer = model.transformers.select { |t| t.name == attr.name }.first
|
66
|
+
if transformer
|
67
|
+
"let #{attr.name} = (json[\"#{model.attr_json_hash[attr.name] || attr.name}\"] as? #{transformer.type}).flatMap(#{attr.name}JSONTransformer)"
|
47
68
|
else
|
48
|
-
"let #{attr.name} = json[\"#{
|
69
|
+
"let #{attr.name} = json[\"#{model.attr_json_hash[attr.name] || attr.name}\"] as? #{attr.type}"
|
49
70
|
end
|
50
|
-
end.join(",\n\t\t")
|
71
|
+
end.join(",\n\t\t\t")
|
51
72
|
end
|
73
|
+
|
74
|
+
def decode_template(model)
|
75
|
+
model.attributes.map do |attr|
|
76
|
+
"let #{attr.name} = decoder.decode#{attr.decode_type}(forKey: \"#{attr.name}\") as? #{attr.type}"
|
77
|
+
end.join(",\n\t\t\t")
|
78
|
+
end
|
79
|
+
|
52
80
|
end
|
53
81
|
end
|
@@ -6,6 +6,27 @@ module JSONCop
|
|
6
6
|
@name = name.gsub(/\s+/, "")
|
7
7
|
@type = type.gsub(/\s+/, "")
|
8
8
|
end
|
9
|
+
|
10
|
+
def real_type
|
11
|
+
return type[0..-2] if type.end_with? "?"
|
12
|
+
return type
|
13
|
+
end
|
14
|
+
|
15
|
+
def optional_type
|
16
|
+
return type if type.end_with? "?"
|
17
|
+
return type + "?"
|
18
|
+
end
|
19
|
+
|
20
|
+
def decode_type
|
21
|
+
built_in_types = %w[Int32 Int64 Bool Float Double]
|
22
|
+
return real_type if built_in_types.include? real_type
|
23
|
+
|
24
|
+
case real_type
|
25
|
+
when "Int" then "Integer"
|
26
|
+
when "Date" then "Object"
|
27
|
+
else "Object"
|
28
|
+
end
|
29
|
+
end
|
9
30
|
end
|
10
31
|
end
|
11
32
|
end
|
data/lib/jsoncop/model/model.rb
CHANGED
data/lib/jsoncop/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsoncop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Draveness
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: claide
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- lib/jsoncop/helper.rb
|
127
127
|
- lib/jsoncop/model/attribute.rb
|
128
128
|
- lib/jsoncop/model/model.rb
|
129
|
+
- lib/jsoncop/model/transformer.rb
|
129
130
|
- lib/jsoncop/version.rb
|
130
131
|
homepage: https://github.com/Draveness/JSONCop
|
131
132
|
licenses:
|
@@ -147,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
148
|
version: '0'
|
148
149
|
requirements: []
|
149
150
|
rubyforge_project:
|
150
|
-
rubygems_version: 2.6.
|
151
|
+
rubygems_version: 2.6.6
|
151
152
|
signing_key:
|
152
153
|
specification_version: 4
|
153
154
|
summary: A JSON to model method generator.
|