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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fe2dadd4db52fbf4f373d7219133ee6a400c3c61
4
- data.tar.gz: e7ce11ffaa6a534e095b73d5301e6f04a622181d
3
+ metadata.gz: 6d68292e78bb6f41e6f716a177702537eb7af012
4
+ data.tar.gz: 7d9f747880b9f1016543e68427a65efe25530066
5
5
  SHA512:
6
- metadata.gz: ae267be67d57306b869c5e5bc267691941d3a4ea25dfff9188d322646da8e6d1187cb8d8268a841442c5fe5d965e55cc407e23470219e15c8bac12528eebc290
7
- data.tar.gz: d1bbf93c5b176cf40c734113727e09068c0b2e2ee0d16b582a59858add6554023af9941350c096c140d2579ba63914092b575a7a493455d66aef0be66969caf9
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 implement `static func JSONKeyPathByPropertyKey` method:
22
+ Define a model with and **add `//@jsoncop` just before model definition line**:
23
23
 
24
24
  ```swift
25
- // jsoncop: enabled
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 `generate-start` and `generate-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.
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
 
@@ -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 = /jsoncop: 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 :model
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
- content.each_line do |line|
25
- if line =~ MODEL_NAME_REGEX
26
- model_name = line.scan(MODEL_NAME_REGEX).flatten.last
27
- @model = Model::Model.new model_name
28
- elsif line =~ ATTRIBUTE_REGEX
29
- result = line.scan(ATTRIBUTE_REGEX).flatten
30
- @model.attributes << Model::Attribute.new(result[1], result[2])
31
- elsif line =~ JSON_TRANSFORMER_REGEX
32
- result = line.scan(JSON_TRANSFORMER_REGEX).flatten
33
- @model.transformers << result.first
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
- json_attr_list = content.scan(JSON_BY_PROPERTY_HASH_REGEX).flatten.first
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
@@ -7,47 +7,75 @@ module JSONCop
7
7
  attr_reader :file_path
8
8
  attr_reader :model
9
9
 
10
- def initialize(file_path, model)
10
+ def initialize(file_path, models)
11
11
  @file_path = file_path
12
- @model = model
12
+ @models = models
13
13
  end
14
14
 
15
15
  def generate!
16
- jsoncop_generate_start = /jsoncop: generate\-start/
17
- jsoncop_generate_end = /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!(/\/\/ jsoncop: generate-start[^$]*jsoncop: generate\-end/, "")
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 + json_cop_template
24
+ File.write file_path, content
23
25
  end
24
26
 
25
27
  def json_cop_template
26
- <<-JSONCOP
27
- // jsoncop: generate-start
28
-
29
- extension #{@model.name} {
30
- static func parse(json: [String: Any]) -> #{@model.name}? {
31
- guard #{json_parsing_template} else { return nil }
32
- return #{@model.name}(#{model.key_value_pair})
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 parse(jsons: [[String: Any]]) -> [#{@model.name}] {
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
- // jsoncop: generate-end
40
- JSONCOP
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
- @model.attributes.map do |attr|
45
- if @model.transformers.include? attr.name
46
- "let #{attr.name} = (json[\"#{@model.attr_json_hash[attr.name]}\"]).flatMap(#{attr.name}JSONTransformer)"
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[\"#{@model.attr_json_hash[attr.name]}\"] as? #{attr.type}"
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
@@ -2,6 +2,7 @@ module JSONCop
2
2
  module Model
3
3
  class Model
4
4
  attr_reader :name
5
+ attr_accessor :is_struct
5
6
  attr_accessor :attributes
6
7
  attr_accessor :transformers
7
8
  attr_accessor :attr_json_hash
@@ -0,0 +1,11 @@
1
+ module JSONCop
2
+ module Model
3
+ class Transformer
4
+ attr_reader :name, :type
5
+ def initialize(name, type)
6
+ @name = name.gsub(/\s+/, "")
7
+ @type = type.gsub(/\s+/, "").gsub(/:/, ": ")
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module JSONCop
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
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.1.2
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-19 00:00:00.000000000 Z
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.4
151
+ rubygems_version: 2.6.6
151
152
  signing_key:
152
153
  specification_version: 4
153
154
  summary: A JSON to model method generator.