jsoncop 0.1.2 → 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 +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
|

|
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.
|