osv 0.3.9 → 0.3.10

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: 935cf4c277ef52eb1b1c4a4c27d2fe54461489b38b4203a1e574ac1a9e3298df
4
- data.tar.gz: aa13944483b0f9fa8963a830d5f2a2932110e86bb32c722565c2b4d5f9dbef3c
3
+ metadata.gz: aed16dbfb14e6caebceb388104731091a5354394cd174804982dbce8f4b95963
4
+ data.tar.gz: 232497c8ec55ab15559f126c4bc90c6bcd0dd4296efadcbf23d07d6a24c7969d
5
5
  SHA512:
6
- metadata.gz: ea38b823a0423ef8883c04f6b677b16ba5d55f9a23faf434fc758788d238972b17b6e2435f0ec92661a32ee31fafb39170c81933d67a201af8cd528678e6261a
7
- data.tar.gz: 77a62c7d62f36bd4143166d65c64eecccece56f1ebb969295cf7af6ff8639af9df71b3923d3ba13590824db68604e90cdc61e22490e81a3d0e24bf1af5f0be47
6
+ metadata.gz: 36e1bab13ede785e2f41f0a56b37a2ff7448deff182b614c71e15ccd16799abe94f1f7db63034cd1c04195666c85a12fa0284dde75753b16e05e8767e9c87b18
7
+ data.tar.gz: '0990fee8e41dd9eb046d6b3733770adb4ef9825165bb0a012b32dac03ddd9d8f2107860d75ef05437aa8d820d42d16c8148642fd3faab326dcab8007731bcf61'
data/README.md CHANGED
@@ -70,9 +70,10 @@ Both methods support the following options:
70
70
  - by default, empty strings are interpreted as empty strings
71
71
  - if you want to interpret empty strings as nil, set this to an empty string
72
72
  - `buffer_size`: Integer specifying the read buffer size
73
- - `result_type`: String specifying the output format ("hash" or "array")
73
+ - `result_type`: String specifying the output format ("hash" or "array" or :hash or :array)
74
74
  - `flexible`: Boolean specifying if the parser should be flexible (default: false)
75
75
  - `flexible_default`: String specifying the default value for missing fields. Implicitly enables flexible mode if set. (default: `nil`)
76
+ - `trim`: String specifying the trim mode ("all" or "headers" or "fields" or :all or :headers or :fields)
76
77
 
77
78
  ### Input Sources
78
79
 
data/Rakefile CHANGED
@@ -20,3 +20,9 @@ Rake::TestTask.new do |t|
20
20
  t.libs << "lib"
21
21
  t.libs << "test"
22
22
  end
23
+
24
+ task :release do
25
+ sh "bundle exec rake test"
26
+ sh "gem build osv.gemspec"
27
+ sh "gem push osv-#{OSV::VERSION}.gem"
28
+ end
@@ -59,6 +59,7 @@ pub struct RecordReaderBuilder<'a, T: RecordParser + Send + 'static> {
59
59
  buffer: usize,
60
60
  flexible: bool,
61
61
  flexible_default: Option<String>,
62
+ trim: csv::Trim,
62
63
  _phantom: PhantomData<T>,
63
64
  }
64
65
 
@@ -74,6 +75,7 @@ impl<'a, T: RecordParser + Send + 'static> RecordReaderBuilder<'a, T> {
74
75
  buffer: BUFFER_CHANNEL_SIZE,
75
76
  flexible: false,
76
77
  flexible_default: None,
78
+ trim: csv::Trim::None,
77
79
  _phantom: PhantomData,
78
80
  }
79
81
  }
@@ -113,6 +115,11 @@ impl<'a, T: RecordParser + Send + 'static> RecordReaderBuilder<'a, T> {
113
115
  self
114
116
  }
115
117
 
118
+ pub fn trim(mut self, trim: csv::Trim) -> Self {
119
+ self.trim = trim;
120
+ self
121
+ }
122
+
116
123
  fn handle_string_io(&self) -> Result<Box<dyn Read + Send + 'static>, ReaderError> {
117
124
  let string: RString = self.to_read.funcall("string", ())?;
118
125
  let content = string.to_string()?;
@@ -200,6 +207,7 @@ impl<'a, T: RecordParser + Send + 'static> RecordReaderBuilder<'a, T> {
200
207
  .delimiter(self.delimiter)
201
208
  .quote(self.quote_char)
202
209
  .flexible(flexible)
210
+ .trim(self.trim)
203
211
  .from_reader(readable);
204
212
 
205
213
  let headers = RecordReader::<T>::get_headers(self.ruby, &mut reader, self.has_headers)?;
@@ -248,6 +256,7 @@ impl<'a, T: RecordParser + Send + 'static> RecordReaderBuilder<'a, T> {
248
256
  .delimiter(self.delimiter)
249
257
  .quote(self.quote_char)
250
258
  .flexible(flexible)
259
+ .trim(self.trim)
251
260
  .from_reader(readable);
252
261
 
253
262
  let headers = RecordReader::<T>::get_headers(self.ruby, &mut reader, self.has_headers)?;
@@ -1,5 +1,6 @@
1
1
  use crate::csv::{CsvRecord, RecordReaderBuilder};
2
2
  use crate::utils::*;
3
+ use csv::Trim;
3
4
  use magnus::value::ReprValue;
4
5
  use magnus::{block::Yield, Error, KwArgs, RHash, Ruby, Symbol, Value};
5
6
  use std::collections::HashMap;
@@ -21,6 +22,7 @@ pub fn parse_csv(
21
22
  result_type,
22
23
  flexible,
23
24
  flexible_default,
25
+ trim,
24
26
  } = parse_csv_args(&ruby, args)?;
25
27
 
26
28
  if !ruby.block_given() {
@@ -35,6 +37,12 @@ pub fn parse_csv(
35
37
  result_type,
36
38
  flexible,
37
39
  flexible_default,
40
+ trim: match trim {
41
+ Trim::All => Some("all".to_string()),
42
+ Trim::Headers => Some("headers".to_string()),
43
+ Trim::Fields => Some("fields".to_string()),
44
+ _ => None,
45
+ },
38
46
  });
39
47
  }
40
48
 
@@ -46,6 +54,7 @@ pub fn parse_csv(
46
54
  .has_headers(has_headers)
47
55
  .flexible(flexible)
48
56
  .flexible_default(flexible_default)
57
+ .trim(trim)
49
58
  .delimiter(delimiter)
50
59
  .quote_char(quote_char)
51
60
  .null_string(null_string)
@@ -58,6 +67,7 @@ pub fn parse_csv(
58
67
  .has_headers(has_headers)
59
68
  .flexible(flexible)
60
69
  .flexible_default(flexible_default)
70
+ .trim(trim)
61
71
  .delimiter(delimiter)
62
72
  .quote_char(quote_char)
63
73
  .null_string(null_string)
@@ -87,6 +97,7 @@ struct EnumeratorArgs {
87
97
  result_type: String,
88
98
  flexible: bool,
89
99
  flexible_default: Option<String>,
100
+ trim: Option<String>,
90
101
  }
91
102
 
92
103
  fn create_enumerator(
@@ -107,6 +118,7 @@ fn create_enumerator(
107
118
  kwargs.aset(Symbol::new("result_type"), Symbol::new(args.result_type))?;
108
119
  kwargs.aset(Symbol::new("flexible"), args.flexible)?;
109
120
  kwargs.aset(Symbol::new("flexible_default"), args.flexible_default)?;
121
+ kwargs.aset(Symbol::new("trim"), args.trim.map(Symbol::new))?;
110
122
  let enumerator = args
111
123
  .rb_self
112
124
  .enumeratorize("for_each", (args.to_read, KwArgs(kwargs)));
data/ext/osv/src/utils.rs CHANGED
@@ -6,6 +6,27 @@ use magnus::{
6
6
 
7
7
  use crate::csv::BUFFER_CHANNEL_SIZE;
8
8
 
9
+ fn parse_string_or_symbol(ruby: &Ruby, value: Value) -> Result<Option<String>, Error> {
10
+ if value.is_nil() {
11
+ Ok(None)
12
+ } else if value.is_kind_of(ruby.class_string()) {
13
+ RString::from_value(value)
14
+ .ok_or_else(|| Error::new(magnus::exception::type_error(), "Invalid string value"))?
15
+ .to_string()
16
+ .map(|s| Some(s))
17
+ } else if value.is_kind_of(ruby.class_symbol()) {
18
+ Symbol::from_value(value)
19
+ .ok_or_else(|| Error::new(magnus::exception::type_error(), "Invalid symbol value"))?
20
+ .funcall("to_s", ())
21
+ .map(|s| Some(s))
22
+ } else {
23
+ Err(Error::new(
24
+ magnus::exception::type_error(),
25
+ "Value must be a String or Symbol",
26
+ ))
27
+ }
28
+ }
29
+
9
30
  #[derive(Debug)]
10
31
  pub struct CsvArgs {
11
32
  pub to_read: Value,
@@ -17,6 +38,7 @@ pub struct CsvArgs {
17
38
  pub result_type: String,
18
39
  pub flexible: bool,
19
40
  pub flexible_default: Option<String>,
41
+ pub trim: csv::Trim,
20
42
  }
21
43
 
22
44
  /// Parse common arguments for CSV parsing
@@ -36,6 +58,7 @@ pub fn parse_csv_args(ruby: &Ruby, args: &[Value]) -> Result<CsvArgs, Error> {
36
58
  Option<Value>,
37
59
  Option<bool>,
38
60
  Option<Option<String>>,
61
+ Option<Value>,
39
62
  ),
40
63
  (),
41
64
  >(
@@ -50,6 +73,7 @@ pub fn parse_csv_args(ruby: &Ruby, args: &[Value]) -> Result<CsvArgs, Error> {
50
73
  "result_type",
51
74
  "flexible",
52
75
  "flexible_default",
76
+ "trim",
53
77
  ],
54
78
  )?;
55
79
 
@@ -85,36 +109,26 @@ pub fn parse_csv_args(ruby: &Ruby, args: &[Value]) -> Result<CsvArgs, Error> {
85
109
 
86
110
  let buffer_size = kwargs.optional.4.unwrap_or(BUFFER_CHANNEL_SIZE);
87
111
 
88
- let result_type = match kwargs.optional.5 {
89
- Some(value) => {
90
- let parsed = if value.is_kind_of(ruby.class_string()) {
91
- RString::from_value(value)
92
- .ok_or_else(|| {
93
- Error::new(magnus::exception::type_error(), "Invalid string value")
94
- })?
95
- .to_string()?
96
- } else if value.is_kind_of(ruby.class_symbol()) {
97
- Symbol::from_value(value)
98
- .ok_or_else(|| {
99
- Error::new(magnus::exception::type_error(), "Invalid symbol value")
100
- })?
101
- .funcall("to_s", ())?
102
- } else {
112
+ let result_type = match kwargs
113
+ .optional
114
+ .5
115
+ .map(|value| parse_string_or_symbol(ruby, value))
116
+ {
117
+ Some(Ok(Some(parsed))) => match parsed.as_str() {
118
+ "hash" | "array" => parsed,
119
+ _ => {
103
120
  return Err(Error::new(
104
- magnus::exception::type_error(),
105
- "result_type must be a String or Symbol",
106
- ));
107
- };
108
-
109
- match parsed.as_str() {
110
- "hash" | "array" => parsed,
111
- _ => {
112
- return Err(Error::new(
113
- magnus::exception::runtime_error(),
114
- "result_type must be either 'hash' or 'array'",
115
- ))
116
- }
121
+ magnus::exception::runtime_error(),
122
+ "result_type must be either 'hash' or 'array'",
123
+ ))
117
124
  }
125
+ },
126
+ Some(Ok(None)) => String::from("hash"),
127
+ Some(Err(_)) => {
128
+ return Err(Error::new(
129
+ magnus::exception::type_error(),
130
+ "result_type must be a String or Symbol",
131
+ ))
118
132
  }
119
133
  None => String::from("hash"),
120
134
  };
@@ -123,6 +137,35 @@ pub fn parse_csv_args(ruby: &Ruby, args: &[Value]) -> Result<CsvArgs, Error> {
123
137
 
124
138
  let flexible_default = kwargs.optional.7.unwrap_or_default();
125
139
 
140
+ let trim = match kwargs
141
+ .optional
142
+ .8
143
+ .map(|value| parse_string_or_symbol(ruby, value))
144
+ {
145
+ Some(Ok(Some(parsed))) => match parsed.as_str() {
146
+ "all" => csv::Trim::All,
147
+ "headers" => csv::Trim::Headers,
148
+ "fields" => csv::Trim::Fields,
149
+ invalid => {
150
+ return Err(Error::new(
151
+ magnus::exception::runtime_error(),
152
+ format!(
153
+ "trim must be either 'all', 'headers', or 'fields' but got '{}'",
154
+ invalid
155
+ ),
156
+ ))
157
+ }
158
+ },
159
+ Some(Ok(None)) => csv::Trim::None,
160
+ Some(Err(_)) => {
161
+ return Err(Error::new(
162
+ magnus::exception::type_error(),
163
+ "trim must be a String or Symbol",
164
+ ))
165
+ }
166
+ None => csv::Trim::None,
167
+ };
168
+
126
169
  Ok(CsvArgs {
127
170
  to_read,
128
171
  has_headers,
@@ -133,5 +176,6 @@ pub fn parse_csv_args(ruby: &Ruby, args: &[Value]) -> Result<CsvArgs, Error> {
133
176
  result_type,
134
177
  flexible,
135
178
  flexible_default,
179
+ trim,
136
180
  })
137
181
  }
data/lib/osv/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module OSV
2
- VERSION = "0.3.9"
2
+ VERSION = "0.3.10"
3
3
  end
data/lib/osv.rbi CHANGED
@@ -14,12 +14,15 @@ module OSV
14
14
  # an empty string.
15
15
  # - `buffer_size`: Integer specifying the read buffer size
16
16
  # - `result_type`: String specifying the output format
17
- # ("hash" or "array")
17
+ # ("hash" or "array" or :hash or :array)
18
18
  # - `flexible`: Boolean specifying if the parser should be flexible
19
19
  # (default: false)
20
20
  # - `flexible_default`: String specifying the default value for missing fields.
21
21
  # Implicitly enables flexible mode if set.
22
22
  # (default: `nil`)
23
+ # - `trim`: String specifying the trim mode
24
+ # ("all" or "headers" or "fields" or :all or :headers or :fields)
25
+ # (default: `nil`)
23
26
  sig do
24
27
  params(
25
28
  input: T.any(String, StringIO, IO),
@@ -28,9 +31,10 @@ module OSV
28
31
  quote_char: T.nilable(String),
29
32
  nil_string: T.nilable(String),
30
33
  buffer_size: T.nilable(Integer),
31
- result_type: T.nilable(String),
34
+ result_type: T.nilable(T.any(String, Symbol)),
32
35
  flexible: T.nilable(T::Boolean),
33
36
  flexible_default: T.nilable(String),
37
+ trim: T.nilable(T.any(String, Symbol)),
34
38
  blk: T.nilable(T.proc.params(row: T.any(T::Hash[String, T.nilable(String)], T::Array[T.nilable(String)])).void)
35
39
  ).returns(T.any(Enumerator, T.untyped))
36
40
  end
@@ -44,6 +48,7 @@ module OSV
44
48
  result_type: nil,
45
49
  flexible: nil,
46
50
  flexible_default: nil,
51
+ trim: nil,
47
52
  &blk
48
53
  )
49
54
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: osv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Jaremko