Module: CSVPP::Conversions
- Included in:
- Parser
- Defined in:
- lib/csvpp/conversions.rb
Constant Summary collapse
- ARRAY_TYPE_RGX =
/(?<array_type>\w+),\s*(?<array_delimiter>\W)/
Class Method Summary collapse
- .clean_decimal(str) ⇒ Object
-
.convert(obj, to:, missings: [], **options) ⇒ Object
Parsed value, read from ‘obj`, interpreted as type given by `to`.
- .missing?(obj, missings) ⇒ Boolean
- .parse_array(str, type:, delimiter:, **options) ⇒ Object
-
.parse_boolean(str, true_values: [], false_values: [], **options) ⇒ Object
True or false, or nil if ‘str` doesn’t match any value interpreted as ‘true` or `false`.
- .parse_chop(str, delimiter: ':', **options) ⇒ Object
- .parse_date(str, **options) ⇒ Object
- .parse_decimal(str, **options) ⇒ Object
- .parse_float(str, **options) ⇒ Object
- .parse_int(str, **options) ⇒ Object
-
.parse_medi(str, delimiter: ':', **options) ⇒ Object
See page 3 in documentation/Technisches_Begleitblatt_2017_d.pdf more more info on the medi data type.
- .parse_string(str, **options) ⇒ Object
Class Method Details
.clean_decimal(str) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/csvpp/conversions.rb', line 142 def clean_decimal(str) return str unless str.is_a?(String) val = str.strip .gsub(/['`\s]?/, '') # remove thousand separators .sub(/[\sa-zA-Z]*$/, '') # remove trailing words like "mg" .sub(/^-0*(.+)$/, '-\1') # remove 0 after negative sign: -003 => -3 if val =~ /^0+$/ # remove leading zeros '0' else val.gsub( /^0*/, '') end end |
.convert(obj, to:, missings: [], **options) ⇒ Object
Returns parsed value, read from ‘obj`, interpreted as type given by `to`.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/csvpp/conversions.rb', line 15 def convert(obj, to:, missings: [], **) return nil if missing?(obj, missings) if to.start_with?('array') to, rest = to.split('<') rest = rest.tr('>', '') match = rest.match(ARRAY_TYPE_RGX) = .merge( type: match[:array_type], delimiter: match[:array_delimiter] ) end send("parse_#{to}", obj, **) end |
.missing?(obj, missings) ⇒ Boolean
138 139 140 |
# File 'lib/csvpp/conversions.rb', line 138 def missing?(obj, missings) missings.map(&:to_s).include?(obj.to_s) end |
.parse_array(str, type:, delimiter:, **options) ⇒ Object
31 32 33 |
# File 'lib/csvpp/conversions.rb', line 31 def parse_array(str, type:, delimiter:, **) str.split(delimiter).map { |entry| send("parse_#{type}", entry) } end |
.parse_boolean(str, true_values: [], false_values: [], **options) ⇒ Object
Returns true or false, or nil if ‘str` doesn’t match any value interpreted as ‘true` or `false`.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/csvpp/conversions.rb', line 114 def parse_boolean(str, true_values: [], false_values: [], **) cleaned = str.to_s.strip.downcase trues = if true_values.empty? ['1', 't', 'true'] else true_values.map(&:to_s).map(&:downcase) end return true if trues.include? cleaned falses = if false_values.empty? ['0', 'f', 'false'] else false_values.map(&:to_s).map(&:downcase) end return false if falses.include? cleaned nil end |
.parse_chop(str, delimiter: ':', **options) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/csvpp/conversions.rb', line 35 def parse_chop(str, delimiter: ':', **) code, laterality, date = str.split(delimiter) code = parse_string(code) laterality = parse_string(laterality) if laterality laterality = nil if laterality&.empty? date = parse_date(date) if date { code: code, laterality: laterality, date: date } end |
.parse_date(str, **options) ⇒ Object
106 107 108 |
# File 'lib/csvpp/conversions.rb', line 106 def parse_date(str, **) Date.parse(str.to_s) end |
.parse_decimal(str, **options) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/csvpp/conversions.rb', line 94 def parse_decimal(str, **) return nil if str.to_s.empty? cleaned = clean_decimal(str).to_s if cleaned.empty? nil else BigDecimal(cleaned) end end |
.parse_float(str, **options) ⇒ Object
89 90 91 92 |
# File 'lib/csvpp/conversions.rb', line 89 def parse_float(str, **) return nil if str.to_s.empty? Float(clean_decimal(str)) rescue nil end |
.parse_int(str, **options) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/csvpp/conversions.rb', line 73 def parse_int(str, **) return nil if str.to_s.empty? cleaned = if str.is_a?(String) val = str.strip .gsub(/['`\s]?/, '') # remove thousand separators .sub(/\.\d*/, '') # remove decimal point and everything thereafter .sub(/[\sa-zA-Z]*$/, '') # remove trailing words like "mg" .sub(/^-0*(.+)$/, '-\1') # remove 0 after negative sign: -003 => -3 val =~ /^0+$/ ? '0' : val.gsub( /^0*/, '') # remove leading zeros else str end Integer(cleaned) rescue nil end |
.parse_medi(str, delimiter: ':', **options) ⇒ Object
See page 3 in documentation/Technisches_Begleitblatt_2017_d.pdf more more info on the medi data type.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/csvpp/conversions.rb', line 51 def parse_medi(str, delimiter: ':', **) atc_code, annex, application, dose, unit = str.split(delimiter) atc_code = parse_string(atc_code) annex = parse_string(annex) if annex annex = nil if annex&.empty? application = parse_string(application) dose = parse_decimal(dose) unit = parse_string(unit) { atc_code: atc_code, annex: annex, application: application, dose: dose, unit: unit } end |
.parse_string(str, **options) ⇒ Object
69 70 71 |
# File 'lib/csvpp/conversions.rb', line 69 def parse_string(str, **) str.to_s.strip end |