xml2json-rb 0.1.1 → 0.3.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: 3b8bf36283e6565f3c5fe13d52a74b42f69435113f2bc8df671b7feefe0e6d58
4
- data.tar.gz: bcc4149800d29bb5ed30e938fa44c0f87bf9e0b5afb8226e8ac3a78961ccad92
3
+ metadata.gz: 7300901db2b5b148d589efdc043ba16afe065c4848300ae4fe13606e372c9e8f
4
+ data.tar.gz: bcfa9f9a7017c4d5c62f538b1abe07bd4c996d8a650e412798d43e7c18871e15
5
5
  SHA512:
6
- metadata.gz: cc3cf01a0b18a7a902fa550a0603d23aebc1faa2a3c23dd92097fd0fc59905ec37add860ed930ef0e980df85fb3bf65b253c0d3635f19728d8c2aeb21dc46a3c
7
- data.tar.gz: abcb6321dba81f9e451a7aed4525f09b458b9b5323bcfe2fe39ec5a43ed9a298ddf0f1b6e5254b4f1b71d4922baaaf5e1d50984be9a4db0c6f9bc6ec4fea11cf
6
+ metadata.gz: 2719f4a3cc080a3b26c1c2e4e06fb351af1f6a71d882f2a192171a55b63caf66c4d2b143744239ea6842ef6cecfa00b4d0b45065660264d012dd281f716efe9b
7
+ data.tar.gz: 973a6c931eba9a847bcb48be1834e6c63a5c6f64538d199380b7405e4ca64d3ad316a4041490db7bf59623e24f299335ee68697f9ea304ab9f245b490eff1029
data/Cargo.lock CHANGED
@@ -344,7 +344,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
344
344
 
345
345
  [[package]]
346
346
  name = "xml2json"
347
- version = "0.1.0"
347
+ version = "0.3.0"
348
348
  dependencies = [
349
349
  "magnus",
350
350
  "xml2json-rs",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "xml2json"
3
- version = "0.1.0"
3
+ version = "0.3.0"
4
4
  edition = "2021"
5
5
  authors = ["uvlad7 <uvlad7@gmail.com>"]
6
6
  license = "MIT"
@@ -1,47 +1,207 @@
1
- use magnus::{define_module, function, prelude::*, Error};
2
- use xml2json_rs::{XmlBuilder, JsonBuilder};
1
+ use magnus::{define_module, function, prelude::*, Error, Value};
2
+ use magnus::scan_args::{scan_args};
3
+ use xml2json_rs::{XmlBuilder, JsonBuilder, JsonConfig, XmlConfig, Declaration, Version, Encoding, Indentation};
3
4
 
4
5
  // fn hello(subject: String) -> String {
5
6
  // format!("Hello from Rust, {}!", subject)
6
7
  // }
7
8
 
8
- // struct RbXmlConfig {
9
- // val: XmlConfig,
10
- // }
9
+ #[macro_export]
10
+ macro_rules! set_arg {
11
+ ($config:expr, $opts_hash:expr, $arg:ident, $arg_type:ident) => (
12
+ let arg_value = $opts_hash.lookup::<_, Option<$arg_type>>(magnus::Symbol::new(stringify!($arg)))?;
13
+ if arg_value.is_some() {
14
+ $config.$arg(arg_value.unwrap());
15
+ }
16
+ );
17
+ }
11
18
 
12
- // impl RbXmlConfig {
13
- // fn root_name(&mut self, key: Option<String>) -> &mut RbXmlConfig {
14
- // self.val.root_name(key);
15
- // self
16
- // }
17
- //
18
- // fn build(self, json_s: String) -> Result<String, Error> {
19
- // build_xml_impl(json_s, Some(self))
20
- // }
21
- // }
19
+ fn map_xml2json_err(error: xml2json_rs::X2JError) -> Error {
20
+ Error::new(magnus::exception::runtime_error(), error.details())
21
+ }
22
22
 
23
- // fn build_xml(json_s: String) -> Result<String, Error> {
24
- // build_xml_impl(json_s, None)
25
- // }
23
+ fn build_xml(args: &[Value]) -> Result<String, Error> {
24
+ build_xml_impl(args, false)
25
+ }
26
26
 
27
- // fn build_xml_impl(json_s: String, config: Option<RbXmlConfig>) -> Result<String, Error> {
28
- // let mut xml_builder = config.map_or_else(|| XmlBuilder::default(), |conf| conf.val.finalize());
29
- // xml_builder.build_from_json_string(&json_s).or_else(|error| {
30
- // Err(Error::new(magnus::exception::arg_error(), error.to_string()))
31
- // })
32
- // }
27
+ fn build_pretty_xml(args: &[Value]) -> Result<String, Error> {
28
+ build_xml_impl(args, true)
29
+ }
30
+
31
+ fn build_xml_impl(args: &[Value], build_pretty: bool) -> Result<String, Error> {
32
+ let args = scan_args::<_, _, (), (), _, ()>(args)?;
33
+ let (json_s, ): (String, ) = args.required;
34
+ let (opts, ): (Option<magnus::RHash>, ) = args.optional;
35
+ let _: () = args.keywords;
36
+
37
+ let mut xml_builder: XmlBuilder;
38
+ if opts.is_some() { // yep, even if it's an empty hash
39
+ // println!("{}", opts.unwrap().to_string());
40
+ let opts_hash = opts.unwrap();
41
+ let mut config = XmlConfig::new();
42
+ set_arg!(config, opts_hash, root_name, String);
43
+ set_arg!(config, opts_hash, attrkey, String);
44
+ set_arg!(config, opts_hash, charkey, String);
45
+
46
+ let decl_version = opts_hash.lookup::<_, Option<Value>>(magnus::Symbol::new("version"))?;
47
+ let decl_encoding = opts_hash.lookup::<_, Option<Value>>(magnus::Symbol::new("encoding"))?;
48
+ let decl_standalone = opts_hash.lookup::<_, Option<bool>>(magnus::Symbol::new("standalone"))?;
49
+ if decl_version.is_some()
50
+ || decl_encoding.is_some()
51
+ || decl_standalone.is_some()
52
+ { // something is specified
53
+ // I didn't find a way to get defaults without copying them
54
+ let decl_version_val;
55
+ if decl_version.is_some() {
56
+ let decl_version_str = unsafe { decl_version.unwrap().to_s() }?.into_owned();
57
+ decl_version_val = Version::try_from(decl_version_str.as_str())
58
+ .map_err(map_xml2json_err)?;
59
+ } else { decl_version_val = Version::XML10; }
60
+ let decl_encoding_val;
61
+ if decl_encoding.is_some() {
62
+ let decl_encoding_str = unsafe { decl_encoding.unwrap().to_s() }?.into_owned();
63
+ decl_encoding_val = Some(Encoding::try_from(decl_encoding_str.as_str())
64
+ .map_err(map_xml2json_err)?);
65
+ } else { decl_encoding_val = None; }
66
+
67
+ let decl = Declaration::new(
68
+ decl_version_val,
69
+ decl_encoding_val,
70
+ decl_standalone,
71
+ );
72
+ config.decl(decl);
73
+ }
74
+
75
+ let indent = opts_hash.lookup::<_, Option<bool>>(magnus::Symbol::new("indent"))?;
76
+ if indent.unwrap_or(true) {
77
+ let indent_char = opts_hash.lookup::<_, Option<char>>(magnus::Symbol::new("indent_char"))?;
78
+ let indent_size = opts_hash.lookup::<_, Option<usize>>(magnus::Symbol::new("indent_size"))?;
79
+ if indent_char.is_some()
80
+ || indent_size.is_some()
81
+ {
82
+ let indent_char_val: u8;
83
+ if indent_char.is_some() {
84
+ indent_char_val = u8::try_from(indent_char.unwrap()).map_err(|error| Error::new(magnus::exception::type_error(), error.to_string()))?;
85
+ } else { indent_char_val = b' '; }
86
+ config.rendering(Indentation::new(
87
+ indent_char_val,
88
+ indent_size.unwrap_or(2),
89
+ ));
90
+ } else if indent.unwrap_or(build_pretty) {
91
+ // because Indentation::default is not the same as not calling config.rendering at all;
92
+ config.rendering(Indentation::default());
93
+ }
94
+ }
95
+ xml_builder = config.finalize();
96
+ } else if build_pretty {
97
+ xml_builder = XmlConfig::new().rendering(Indentation::default()).finalize();
98
+ } else { xml_builder = XmlBuilder::default(); }
33
99
 
34
- fn build_xml(json_s: String) -> Result<String, Error> {
35
- let mut xml_builder = XmlBuilder::default();
36
100
  xml_builder.build_from_json_string(&json_s).or_else(|error| {
37
- Err(Error::new(magnus::exception::runtime_error(), error.details()))
101
+ Err(map_xml2json_err(error))
38
102
  })
39
103
  }
40
104
 
41
- fn build_json(xml: String) -> Result<String, Error> {
42
- let json_builder = JsonBuilder::default();
43
- json_builder.build_string_from_xml(&xml).or_else(|error| {
44
- Err(Error::new(magnus::exception::runtime_error(), error.details()))
105
+ fn build_json(args: &[Value]) -> Result<String, Error> {
106
+ build_json_impl(args, false)
107
+ }
108
+
109
+ fn build_pretty_json(args: &[Value]) -> Result<String, Error> {
110
+ build_json_impl(args, true)
111
+ }
112
+
113
+ fn build_json_impl(args: &[Value], mut build_pretty: bool) -> Result<String, Error> {
114
+ // https://docs.rs/magnus/latest/magnus/scan_args/fn.scan_args.html
115
+ let args = scan_args::<_, _, (), (), _, ()>(args)?;
116
+ let (xml, ): (String, ) = args.required;
117
+ let (opts, ): (Option<magnus::RHash>, ) = args.optional;
118
+ // let _: () = args.optional;
119
+ let _: () = args.keywords;
120
+
121
+ // Impossible, too long
122
+ // let kw = get_kwargs::<_, (), (
123
+ // Option<String>, // charkey
124
+ // Option<String>, // attrkey
125
+ // Option<String>, // empty_tag
126
+ // Option<bool>, // explicit_root
127
+ // Option<bool>, // trim
128
+ // Option<bool>, // ignore_attrs
129
+ // Option<bool>, // merge_attrs
130
+ // Option<bool>, // normalize_text
131
+ // Option<bool>, // lowercase_tags
132
+ // Option<bool>, // explicit_array
133
+ // Option<bool>, // explicit_charkey
134
+ // ), ()>(args.keywords, &[], &[
135
+ // "charkey",
136
+ // "attrkey",
137
+ // "empty_tag",
138
+ // "explicit_root",
139
+ // "trim",
140
+ // "ignore_attrs",
141
+ // "merge_attrs",
142
+ // "normalize_text",
143
+ // "lowercase_tags",
144
+ // "explicit_array",
145
+ // "explicit_charkey",
146
+ // ])?;
147
+ // let (
148
+ // charkey,
149
+ // attrkey,
150
+ // empty_tag,
151
+ // explicit_root,
152
+ // trim,
153
+ // ignore_attrs,
154
+ // merge_attrs,
155
+ // normalize_text,
156
+ // lowercase_tags,
157
+ // explicit_array,
158
+ // explicit_charkey,
159
+ // ) = kw.optional;
160
+ // if charkey.is_some()
161
+ // || attrkey.is_some()
162
+ // || empty_tag.is_some()
163
+ // || explicit_root.is_some()
164
+ // || trim.is_some()
165
+ // || ignore_attrs.is_some()
166
+ // || merge_attrs.is_some()
167
+ // || normalize_text.is_some()
168
+ // || lowercase_tags.is_some()
169
+ // || explicit_array.is_some()
170
+ // || explicit_charkey.is_some()
171
+ // {
172
+ // println!("any")
173
+ // } else { println!("none") }
174
+
175
+ let json_builder: JsonBuilder;
176
+ if opts.is_some() { // yep, even if it's an empty hash
177
+ // println!("{}", opts.unwrap().to_string());
178
+ let opts_hash = opts.unwrap();
179
+ let mut config = JsonConfig::new();
180
+ set_arg!(config, opts_hash, charkey, String);
181
+ set_arg!(config, opts_hash, attrkey, String);
182
+ set_arg!(config, opts_hash, empty_tag, String);
183
+ set_arg!(config, opts_hash, explicit_root, bool);
184
+ set_arg!(config, opts_hash, trim, bool);
185
+ set_arg!(config, opts_hash, ignore_attrs, bool);
186
+ set_arg!(config, opts_hash, merge_attrs, bool);
187
+ set_arg!(config, opts_hash, normalize_text, bool);
188
+ set_arg!(config, opts_hash, lowercase_tags, bool);
189
+ set_arg!(config, opts_hash, explicit_array, bool);
190
+ set_arg!(config, opts_hash, explicit_charkey, bool);
191
+ json_builder = config.finalize();
192
+
193
+ let indent = opts_hash.lookup::<_, Option<bool>>(magnus::Symbol::new("indent"))?;
194
+ if indent.is_some() {
195
+ build_pretty = indent.unwrap();
196
+ }
197
+ } else { json_builder = JsonBuilder::default(); }
198
+
199
+ if build_pretty {
200
+ json_builder.build_pretty_string_from_xml(&xml)
201
+ } else {
202
+ json_builder.build_string_from_xml(&xml)
203
+ }.or_else(|error| {
204
+ Err(map_xml2json_err(error))
45
205
  })
46
206
  }
47
207
 
@@ -51,9 +211,15 @@ fn init() -> Result<(), Error> {
51
211
  // module.define_singleton_method("hello", function!(hello, 1))?;
52
212
  // It's not possible to wrap XmlBuilder
53
213
  let xml = module.define_module("Xml")?;
54
- xml.define_singleton_method("build", function!(build_xml, 1))?;
55
- // xml.define_class("Config", magnus::class::object())?;
214
+ let xml_version = xml.define_module("Version")?;
215
+ xml_version.const_set("XML10", Version::XML10.to_string())?;
216
+ xml_version.const_set("XML11", Version::XML11.to_string())?;
217
+ let xml_encoding = xml.define_module("Encoding")?;
218
+ xml_encoding.const_set("UTF8", Encoding::UTF8.to_string())?;
219
+ xml.define_singleton_method("build", function!(build_xml, -1))?;
220
+ xml.define_singleton_method("build_pretty", function!(build_pretty_xml, -1))?;
56
221
  let json = module.define_module("Json")?;
57
- json.define_singleton_method("build", function!(build_json, 1))?;
222
+ json.define_singleton_method("build", function!(build_json, -1))?;
223
+ json.define_singleton_method("build_pretty", function!(build_pretty_json, -1))?;
58
224
  Ok(())
59
225
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Xml2Json
4
- VERSION = "0.1.1"
4
+ VERSION = "0.3.0"
5
5
  end
Binary file
data/lib/xml2json.rb CHANGED
@@ -7,15 +7,30 @@ require_relative "xml2json/xml2json"
7
7
  module Xml2Json
8
8
  # @!parse [ruby]
9
9
  # module Xml
10
+ # module Version
11
+ # XML10 = "1.0"
12
+ # XML11 = "1.1"
13
+ # end
14
+ # module Encoding
15
+ # UTF8 = "UTF-8"
16
+ # end
17
+ #
10
18
  # # @param json_s [String, #to_str] JSON string
19
+ # # @param opts [Hash<Symbol, Object>] config params
20
+ # # @see https://docs.rs/xml2json-rs/1.0.1/xml2json_rs/struct.XmlConfig.html rust doc
11
21
  # # @return [String] XML string
12
22
  # # @raise [RuntimeError] if the input string is invalid
13
- # def self.build(json_s); end
23
+ # def self.build(json_s, opts: nil); end
24
+ # def self.build_pretty(json_s, opts: nil); end
14
25
  # end
26
+ #
15
27
  # module Json
16
28
  # # @param xml [String, #to_str] XML string
29
+ # # @param opts [Hash<Symbol, Object>] config params
30
+ # # @see https://docs.rs/xml2json-rs/1.0.1/xml2json_rs/struct.JsonConfig.html rust doc
17
31
  # # @return [String] JSON string
18
32
  # # @raise [RuntimeError] if the input string is invalid
19
- # def self.build(xml); end
33
+ # def self.build(xml, opts: nil); end
34
+ # def self.build_pretty(xml, opts: nil); end
20
35
  # end
21
36
  end
@@ -1,5 +1,6 @@
1
1
  module Xml2Json
2
2
  module Json
3
- def self.build: (xml: String) -> String
3
+ def self.build: (xml: String, opts: Hash[Symbol, Object]?) -> String
4
+ def self.build_pretty: (xml: String, opts: Hash[Symbol, Object]?) -> String
4
5
  end
5
6
  end
@@ -0,0 +1,7 @@
1
+ module Xml2Json
2
+ module Xml
3
+ module Encoding
4
+ UTF8: String
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module Xml2Json
2
+ module Xml
3
+ module Version
4
+ XML10: String
5
+ XML11: String
6
+ end
7
+ end
8
+ end
@@ -1,5 +1,6 @@
1
1
  module Xml2Json
2
2
  module Xml
3
- def self.build: (json_s: String) -> String
3
+ def self.build: (json_s: String, opts: Hash[Symbol, Object]?) -> String
4
+ def self.build_pretty: (json_s: String, opts: Hash[Symbol, Object]?) -> String
4
5
  end
5
6
  end
metadata CHANGED
@@ -1,113 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xml2json-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - uvlad7
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-09 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: yard-rustdoc
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: pry
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: pry-byebug
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: yard
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rack
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rackup
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: puma
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
11
+ date: 2023-10-01 00:00:00.000000000 Z
12
+ dependencies: []
111
13
  description: This gem helps to convert xml strings to json and vise versa
112
14
  email:
113
15
  - uvlad7@gmail.com
@@ -126,6 +28,8 @@ files:
126
28
  - lib/xml2json/xml2json.so
127
29
  - sig/xml2_json/json.rbs
128
30
  - sig/xml2_json/xml.rbs
31
+ - sig/xml2_json/xml/encoding.rbs
32
+ - sig/xml2_json/xml/version.rbs
129
33
  - sig/xml2json.rbs
130
34
  homepage: https://github.com/uvlad7/xml2json-rb
131
35
  licenses:
@@ -134,8 +38,9 @@ metadata:
134
38
  homepage_uri: https://github.com/uvlad7/xml2json-rb
135
39
  source_code_uri: https://github.com/uvlad7/xml2json-rb
136
40
  changelog_uri: https://github.com/uvlad7/xml2json-rb/blob/main/CHANGELOG.md
137
- documentation_uri: https://rubydoc.info/gems/xml2json-rb/0.1.1
138
- post_install_message:
41
+ documentation_uri: https://rubydoc.info/gems/xml2json-rb/0.3.0
42
+ rubygems_mfa_required: 'true'
43
+ post_install_message:
139
44
  rdoc_options: []
140
45
  require_paths:
141
46
  - lib
@@ -151,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
56
  version: 3.3.11
152
57
  requirements: []
153
58
  rubygems_version: 3.4.10
154
- signing_key:
59
+ signing_key:
155
60
  specification_version: 4
156
61
  summary: Ruby wrapper for xml2json-rs
157
62
  test_files: []