composite_unit_measurements 0.2.0 → 0.4.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: e4450805d84ddd3b1cc972d152d187f44cbb1624d87dfece055c6db82ae70d20
4
- data.tar.gz: 621ccd8a46402e7592dd93c8bf0683e414714e3f3fb67f1f4837cceabe96e5ab
3
+ metadata.gz: c25131e598e9fb02e3b569eeb45df0f39b254d5d85ab7e60ee729365b70c59cc
4
+ data.tar.gz: c659dea44b220217466355182589a808a098d1d654efbc664f55e6556198422f
5
5
  SHA512:
6
- metadata.gz: 56937734d56198b02eb4c51c9b446558ec31a69bc123489ec371d8f36e7758efda6cf8d50ea85e947e57cf72f003e795a7897d850ff5a228f7505dc53b2aea36
7
- data.tar.gz: d1e8a2129c276a186c8dd8bd7bf4cf5b29e2ff46c9dcff98b6928fba858b5d64441645c905ba273fd82bf547f43d14d1b0b25d2342d2219869d8d0a9b2a4d606
6
+ metadata.gz: ca73e1e52c1c40b08f95ce7196bdb5c290dbe4d955c8c9c80affc6210b5657cb05a013e5352467412a8139cb1ef927914b96cd59843565fb30462ba4ce77419f
7
+ data.tar.gz: 7528d84b11c1eeb86eea5b5683e581513695b816662669711fa8a567a9fba1c7b4f505d19dd250c6b1175c5e9bdea896f5f483e0096c35b38a591aa7477124fa
data/CHANGELOG.md CHANGED
@@ -1,4 +1,23 @@
1
- ## 0.2.0 - 2023-11-17
1
+ ## [0.4.0](https://github.com/shivam091/composite_unit_measurements/compare/v0.2.0...v0.3.0) - 2023-11-30
2
+
3
+ ### What's new
4
+
5
+ - Added ability to parse `litre-millilitre` volume measurements.
6
+ - Updated readme with parsing examples.
7
+
8
+ -----------
9
+
10
+ ## [0.3.0](https://github.com/shivam091/composite_unit_measurements/compare/v0.2.0...v0.3.0) - 2023-11-27
11
+
12
+ ### What's new
13
+
14
+ - Added ability to parse `kilometre-metre` and `metre-centimetre` length measurements.
15
+ - Added ability to parse `hour-minute` time measurement.
16
+ - Added ability to parse `kilogramme-gramme` weight measurement.
17
+
18
+ -----------
19
+
20
+ ## [0.2.0](https://github.com/shivam091/composite_unit_measurements/compare/v0.1.0...v0.2.0) - 2023-11-17
2
21
 
3
22
  ### What's new
4
23
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- composite_unit_measurements (0.2.0)
4
+ composite_unit_measurements (0.4.0)
5
5
  activesupport (~> 7.0)
6
6
  unit_measurements (~> 5)
7
7
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Composite Unit Measurements
2
2
 
3
- A set of specialized parsers for dealing with composite measurement strings.
3
+ A collection of specialized parsers designed for handling composite measurement strings.
4
4
 
5
5
  [![Ruby](https://github.com/shivam091/composite_unit_measurements/actions/workflows/main.yml/badge.svg)](https://github.com/shivam091/composite_unit_measurements/actions/workflows/main.yml)
6
6
  [![Gem Version](https://badge.fury.io/rb/composite_unit_measurements.svg)](https://badge.fury.io/rb/composite_unit_measurements)
@@ -13,17 +13,18 @@ A set of specialized parsers for dealing with composite measurement strings.
13
13
 
14
14
  ## Introduction
15
15
 
16
- The `CompositeUnitMeasurements` gem is a versatile solution tailored for parsing
17
- composite measurement strings. By harnessing the capabilities of the `unit_measurements`
18
- gem, it empowers you to seamlessly handle composite measurements in various units.
16
+ The `composite_unit_measurements` gem offers versatile parsers for efficiently parsing
17
+ composite measurement strings. Leveraging the power of the `unit_measurements` gem,
18
+ it enables smooth handling of composite measurements in various units.
19
19
 
20
20
  ## Minimum Requirements
21
21
 
22
- * Ruby 3.2.2+ (https://www.ruby-lang.org/en/downloads/branches/)
22
+ * Ruby 3.2.2+ ([Download Ruby](https://www.ruby-lang.org/en/downloads/branches/))
23
23
 
24
24
  ## Installation
25
25
 
26
- If using bundler, first add this line to your application's Gemfile:
26
+ To use `composite_unit_measurements` in your Rails application, add the
27
+ following line to your Gemfile:
27
28
 
28
29
  ```ruby
29
30
  gem "composite_unit_measurements"
@@ -39,63 +40,81 @@ Or otherwise simply install it yourself as:
39
40
 
40
41
  ## Usage
41
42
 
42
- Each packaged parser includes the `#parse` method to parse composite measurements.
43
- You can use an appropriate parser to parse measurements. The final result of `#parse`
43
+ Each packaged parser includes the `.parse` method to parse composite measurements.
44
+ You can use an appropriate parser to these measurements and the final result of
44
45
  is returned in the leftmost unit of your measurement.
45
46
 
47
+ The result of each parser method returns an instance of measurement on which we can
48
+ perform any functionality offered by `unit_measurements`.
49
+
46
50
  This gem internally uses [`unit_measurements`](https://github.com/shivam091/unit_measurements)
47
- to perform conversions and arithmetic operations. You can use any
48
- [alias of the units](https://github.com/shivam091/unit_measurements/blob/main/units.md)
49
- to build a supported composite measurements.
51
+ to perform conversions and arithmetic operations. You can build supported composite measurements
52
+ using any [unit alias](https://github.com/shivam091/unit_measurements/blob/main/units.md).
53
+
54
+ ### Examples
55
+
56
+ **Parsing length measurements:**
57
+
58
+ ```ruby
59
+ CompositeUnitMeasurements::Length.parse("5 km 500 m") #=> 5.5 km
60
+ ```
61
+
62
+ **Parsing weight measurements:**
63
+
64
+ ```ruby
65
+ CompositeUnitMeasurements::Weight.parse("4 kg 500 g") # 4.5 kg
66
+ ```
67
+
68
+ **Parsing time measurements:**
50
69
 
51
70
  ```ruby
52
- CompositeUnitMeasurements::Length.parse("5 feet 6 inches")
53
- #=> 5.5 ft
54
- CompositeUnitMeasurements::Weight.parse("8 pound 12 ounce")
55
- #=> 8.75 lb
56
- CompositeUnitMeasurements::Time.parse("12:60:60,60")
57
- #=> 13.0166666833333333666667 h
71
+ CompositeUnitMeasurements::Time.parse("3 h 45 min") #=> 3.75 hr
58
72
  ```
59
73
 
60
- Each parser has capability to parse `real`, `rational`, `scientific`, and `complex` numbers.
74
+ **Parsing volume measurements:**
61
75
 
62
76
  ```ruby
63
- CompositeUnitMeasurements::Length.parse("1+2i ft 12 in")
64
- #=> 2.0+2.0i ft
65
- CompositeUnitMeasurements::Length.parse("1.5 ft 12e2 in")
66
- #=> 101.5 ft
67
- CompositeUnitMeasurements::Length.parse("1 1/2 ft 1+2i in")
68
- #=> 1.5833333333333333+0.16666666666666669i ft
69
- CompositeUnitMeasurements::Length.parse("2 ft 1+2i in")
70
- #=> 2.0833333333333335+0.16666666666666669i ft
71
- CompositeUnitMeasurements::Length.parse("1e-2 ft 1+2i in")
72
- #=> 0.09333333333333334+0.16666666666666669i ft
77
+ CompositeUnitMeasurements::Volume.parse("2 l 250 ml") #=> 2.25 l
78
+ ```
79
+
80
+ ### Support for numeric types
81
+
82
+ Each parser can handle various numeric types, including scientific notation, rational numbers, and complex numbers.
83
+
84
+ ```ruby
85
+ CompositeUnitMeasurements::Length.parse("1+2i ft 12 in") #=> 2.0+2.0i ft
86
+ CompositeUnitMeasurements::Length.parse("1.5 ft 12e2 in") #=> 101.5 ft
87
+ CompositeUnitMeasurements::Length.parse("1 1/2 ft 1+2i in") #=> 1.5833333333333333+0.16666666666666669i ft
88
+ CompositeUnitMeasurements::Length.parse("2 ft 1+2i in") #=> 2.0833333333333335+0.16666666666666669i ft
89
+ CompositeUnitMeasurements::Length.parse("1e-2 ft 1+2i in") #=> 0.09333333333333334+0.16666666666666669i ft
73
90
  ```
74
91
 
75
92
  ## Packaged parsers & supported composite measurements
76
93
 
77
- There are tons of composite measurements that are bundled with `composite_unit_measurements`.
94
+ The `composite_unit_measurements` gem supports parsing various composite measurements, including:
78
95
 
79
- **1. Unitify::CompositeMeasurements::Length**
96
+ **1. CompositeUnitMeasurements::Length**
97
+ - metre-centimetre (6 m 50 cm)
98
+ - kilometre-metre (5 km 500 m)
80
99
  - foot-inch (5 ft 6 in)
81
100
 
82
- **2. Unitify::CompositeMeasurements::Weight**
101
+ **2. CompositeUnitMeasurements::Weight**
102
+ - kilogramme-gramme (4 kg 500 g)
83
103
  - pound-ounce (8 lb 12 oz)
84
104
  - stone-pound (2 st 6 lb)
85
105
 
86
- **3. Unitify::CompositeMeasurements::Time**
87
- - hour-minute-second-microsecond (12:60:60,60)
106
+ **3. CompositeUnitMeasurements::Time**
107
+ - hour-minute (3 h 45 min)
108
+ - hour-minute-second-microsecond (12:60,3600:360000000)
88
109
 
89
- ### Specifing parsers
110
+ **4. CompositeUnitMeasurements::Volume**
111
+ - litre-millilitre (2 l 250 ml)
90
112
 
91
- By default, `composite_unit_measurements` ships with all the packaged parsers and
92
- this happens automatically when you require the gem in the following manner.
93
-
94
- ```ruby
95
- require "composite_unit_measurements"
96
- ```
113
+ ### Specifing parsers
97
114
 
98
- You can also use parsers in your application as per your need as:
115
+ By default, `composite_unit_measurements` includes all packaged parsers automatically
116
+ when required in your application. However, you can opt to use specific parsers as
117
+ needed:
99
118
 
100
119
  ```ruby
101
120
  require "composite_unit_measurements/base"
@@ -106,12 +125,14 @@ require "composite_unit_measurements/weight"
106
125
 
107
126
  ## Contributing
108
127
 
109
- 1. Fork it
110
- 2. Create your feature branch (`git checkout -b my-new-feature`)
128
+ Contributions to this project are welcomed! To contribute:
129
+
130
+ 1. Fork this repository
131
+ 2. Create a new branch (`git checkout -b my-new-feature`)
111
132
  3. Commit your changes (`git commit -am "Add some feature"`)
112
- 4. Push to the branch (`git push origin my-new-feature`)
113
- 5. Create new Pull Request
133
+ 4. Push the changes to your branch (`git push origin my-new-feature`)
134
+ 5. Create new **Pull Request**
114
135
 
115
136
  ## License
116
137
 
117
- Copyright 2023 [Harshal V. LADHE]((https://shivam091.github.io)), Released under the [MIT License](http://opensource.org/licenses/MIT).
138
+ Copyright 2023 [Harshal V. LADHE](https://shivam091.github.io), Released under the [MIT License](http://opensource.org/licenses/MIT).
@@ -54,4 +54,7 @@ module CompositeUnitMeasurements
54
54
 
55
55
  # Matches any number, including scientific, complex, rational, and real numbers.
56
56
  ANY_NUMBER = /(?<number>#{SCIENTIFIC_NUMBER}|#{COMPLEX_NUMBER}|#{RATIONAL_NUMBER}|#{REAL_NUMBER})/.freeze
57
+
58
+ private_constant :REAL_NUMBER, :RATIONAL_NUMBER, :SCIENTIFIC_NUMBER, :COMPLEX_NUMBER,
59
+ :ANY_NUMBER
57
60
  end
@@ -14,9 +14,17 @@ module CompositeUnitMeasurements
14
14
  class << self
15
15
  # Parses a given +string+ into a +UnitMeasurements::Length+ object.
16
16
  #
17
+ # @example Parse 'metre-centimetre' measurement:
18
+ # CompositeUnitMeasurements::Length.parse("6 m 50 cm") #=> 6.5 m
19
+ # @example Parse 'kilometre-metre' measurement:
20
+ # CompositeUnitMeasurements::Length.parse("5 km 500 m") #=> 5.5 km
21
+ # @example Parse 'foot-inch' measurement:
22
+ # CompositeUnitMeasurements::Length.parse("5 ft 6 in") #=> 5.5 ft
23
+ #
17
24
  # @param [String] string The string to parse for length measurement.
18
25
  # @return [UnitMeasurements::Length]
19
26
  # Returns a UnitMeasurements::Length object if parsing is successful.
27
+ #
20
28
  # @raise [UnitMeasurements::ParseError]
21
29
  # If the string does not match any known format.
22
30
  #
@@ -24,15 +32,18 @@ module CompositeUnitMeasurements
24
32
  # @since 0.2.0
25
33
  def parse(string)
26
34
  case string
27
- when FOOT_INCH then parse_foot_inch(string)
28
- else raise UnitMeasurements::ParseError, string
35
+ when FOOT_INCH then parse_foot_inch(string)
36
+ when KILOMETRE_METRE then parse_kilometre_metre(string)
37
+ when METRE_CENTIMETRE then parse_metre_centimetre(string)
38
+ else raise UnitMeasurements::ParseError, string
29
39
  end
30
40
  end
31
41
 
32
42
  private
33
43
 
34
44
  # @private
35
- # Parses a +string+ representing a length in the format of +foot-inch+.
45
+ # Parses a +string+ representing a length in the format of +foot-inch+
46
+ # into a +UnitMeasurements::Length+ object.
36
47
  #
37
48
  # @param [String] string
38
49
  # The string representing length measurement in the format of *foot-inch*.
@@ -46,12 +57,50 @@ module CompositeUnitMeasurements
46
57
  foot, inch = string.match(FOOT_INCH)&.captures
47
58
 
48
59
  if foot && inch
49
- UnitMeasurements::Length.new(foot, :ft) + UnitMeasurements::Length.new(inch, :in)
60
+ UnitMeasurements::Length.new(foot, "ft") + UnitMeasurements::Length.new(inch, "in")
50
61
  end
51
62
  end
52
- end
53
63
 
54
- private
64
+ # @private
65
+ # Parses a +string+ representing a length in the format of +metre-centimetre+
66
+ # into a +UnitMeasurements::Length+ object.
67
+ #
68
+ # @param [String] string
69
+ # The string representing length measurement in the format of *metre-centimetre*.
70
+ # @return [UnitMeasurements::Length]
71
+ # Returns a UnitMeasurements::Length object if parsing is successful.
72
+ #
73
+ # @see METRE_CENTIMETRE
74
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
75
+ # @since 0.3.0
76
+ def parse_metre_centimetre(string)
77
+ metre, centimetre = string.match(METRE_CENTIMETRE)&.captures
78
+
79
+ if metre && centimetre
80
+ UnitMeasurements::Length.new(metre, "m") + UnitMeasurements::Length.new(centimetre, "cm")
81
+ end
82
+ end
83
+
84
+ # @private
85
+ # Parses a +string+ representing a length in the format of +kilometre-metre+
86
+ # into a +UnitMeasurements::Length+ object.
87
+ #
88
+ # @param [String] string
89
+ # The string representing length measurement in the format of *kilometre-metre*.
90
+ # @return [UnitMeasurements::Length]
91
+ # Returns a UnitMeasurements::Length object if parsing is successful.
92
+ #
93
+ # @see KILOMETRE_METRE
94
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
95
+ # @since 0.3.0
96
+ def parse_kilometre_metre(string)
97
+ kilometre, metre = string.match(KILOMETRE_METRE)&.captures
98
+
99
+ if kilometre && metre
100
+ UnitMeasurements::Length.new(kilometre, "km") + UnitMeasurements::Length.new(metre, "m")
101
+ end
102
+ end
103
+ end
55
104
 
56
105
  # Regex pattern for aliases of +foot+ unit.
57
106
  #
@@ -65,10 +114,43 @@ module CompositeUnitMeasurements
65
114
  # @since 0.2.0
66
115
  INCH_ALIASES = /(?:"|in|inch(?:es)?)/.freeze
67
116
 
117
+ # Regex pattern for aliases of +metre+ unit.
118
+ #
119
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
120
+ # @since 0.3.0
121
+ METRE_ALIASES = /(?:m|meter(?:s)?|metre(?:s)?)/.freeze
122
+
123
+ # Regex pattern for aliases of +centimetre+ unit.
124
+ #
125
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
126
+ # @since 0.3.0
127
+ CENTIMETRE_ALIASES = /(?:cm|centimeter(?:s)?|centimetre(?:s)?)/.freeze
128
+
129
+ # Regex pattern for aliases of +kilometre+ unit.
130
+ #
131
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
132
+ # @since 0.3.0
133
+ KILOMETRE_ALIASES = /(?:km|kilometer(?:s)?|kilometre(?:s)?)/.freeze
134
+
68
135
  # Regex pattern for parsing a length measurement in the format of +foot-inch+.
69
136
  #
70
137
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
71
138
  # @since 0.2.0
72
139
  FOOT_INCH = /\A#{ANY_NUMBER}\s*#{FOOT_ALIASES}\s*#{ANY_NUMBER}\s*#{INCH_ALIASES}\z/.freeze
140
+
141
+ # Regex pattern for parsing a length measurement in the format of +metre-centimetre+.
142
+ #
143
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
144
+ # @since 0.3.0
145
+ METRE_CENTIMETRE = /\A#{ANY_NUMBER}\s*#{METRE_ALIASES}\s*#{ANY_NUMBER}\s*#{CENTIMETRE_ALIASES}\z/.freeze
146
+
147
+ # Regex pattern for parsing a length measurement in the format of +kilometre-metre+.
148
+ #
149
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
150
+ # @since 0.3.0
151
+ KILOMETRE_METRE = /\A#{ANY_NUMBER}\s*#{KILOMETRE_ALIASES}\s*#{ANY_NUMBER}\s*#{METRE_ALIASES}\z/.freeze
152
+
153
+ private_constant :FOOT_ALIASES, :INCH_ALIASES, :METRE_ALIASES, :CENTIMETRE_ALIASES,
154
+ :KILOMETRE_ALIASES, :FOOT_INCH, :KILOMETRE_METRE, :METRE_CENTIMETRE
73
155
  end
74
156
  end
@@ -14,6 +14,12 @@ module CompositeUnitMeasurements
14
14
  class << self
15
15
  # Parses a given +string+ into a +UnitMeasurements::Time+ object.
16
16
  #
17
+ # @example Parse 'hour-minute' measurement:
18
+ # CompositeUnitMeasurements::Time.parse("3 h 45 min") #=> 3.75 h
19
+ # @example Parse 'duration':
20
+ # CompositeUnitMeasurements::Time.parse("12:60:3600,360000000") #=> 14.1 h
21
+ # CompositeUnitMeasurements::Time.parse("12:60:3600") #=> 14.0 h
22
+ #
17
23
  # @param [String] string The string to parse for time measurement.
18
24
  # @return [UnitMeasurements::Time]
19
25
  # Returns a UnitMeasurements::Time object if parsing is successful.
@@ -24,16 +30,38 @@ module CompositeUnitMeasurements
24
30
  # @since 0.2.0
25
31
  def parse(string)
26
32
  case string
27
- when DURATION then parse_duration(string)
28
- else raise UnitMeasurements::ParseError, string
33
+ when HOUR_MINUTE then parse_hour_minute(string)
34
+ when DURATION then parse_duration(string)
35
+ else raise UnitMeasurements::ParseError, string
29
36
  end
30
37
  end
31
38
 
32
39
  private
33
40
 
41
+ # @private
42
+ # Parses a +string+ representing a time in the format of +hour-minute+
43
+ # into a +UnitMeasurements::Time+ object.
44
+ #
45
+ # @param [String] string
46
+ # The string representing time measurement in the format of *hour-minute*.
47
+ # @return [UnitMeasurements::Time]
48
+ # Returns a UnitMeasurements::Time object if parsing is successful.
49
+ #
50
+ # @see HOUR_MINUTE
51
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
52
+ # @since 0.3.0
53
+ def parse_hour_minute(string)
54
+ hour, minute = string.match(HOUR_MINUTE)&.captures
55
+
56
+ if hour && minute
57
+ UnitMeasurements::Time.new(hour, "h") + UnitMeasurements::Time.new(minute, "min")
58
+ end
59
+ end
60
+
34
61
  # @private
35
62
  # Parses a +string+ representing time duration in the format of
36
- # +hour:minute:second,microsecond+ or +hour:minute:second+.
63
+ # +hour:minute:second,microsecond+ or +hour:minute:second+ into a
64
+ # +UnitMeasurements::Time+ object.
37
65
  #
38
66
  # @param [String] string The string representing time duration.
39
67
  # @return [UnitMeasurements::Time]
@@ -55,7 +83,23 @@ module CompositeUnitMeasurements
55
83
  end
56
84
  end
57
85
 
58
- private
86
+ # Regex pattern for aliases of +hour+ unit.
87
+ #
88
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
89
+ # @since 0.3.0
90
+ HOUR_ALIASES = /(?:h|hr|hour(?:s)?)/.freeze
91
+
92
+ # Regex pattern for aliases of +minute+ unit.
93
+ #
94
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
95
+ # @since 0.3.0
96
+ MINUTE_ALIASES = /(?:min|minute(?:s)?)/.freeze
97
+
98
+ # Regex pattern for parsing a time measurement in the format of +hour-minute+.
99
+ #
100
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
101
+ # @since 0.3.0
102
+ HOUR_MINUTE = /\A#{ANY_NUMBER}\s*#{HOUR_ALIASES}\s*#{ANY_NUMBER}\s*#{MINUTE_ALIASES}\z/.freeze
59
103
 
60
104
  # Regex pattern for parsing duration in the format of +hour:minute:second+ or
61
105
  # +hour:minute:second,microsecond+.
@@ -63,5 +107,7 @@ module CompositeUnitMeasurements
63
107
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
64
108
  # @since 0.2.0
65
109
  DURATION = /\A(?<hour>#{REAL_NUMBER}):(?<min>#{REAL_NUMBER}):(?:(?<sec>#{REAL_NUMBER}))?(?:,(?<msec>#{REAL_NUMBER}))?\z/.freeze
110
+
111
+ private_constant :HOUR_ALIASES, :MINUTE_ALIASES, :HOUR_MINUTE, :DURATION
66
112
  end
67
113
  end
@@ -2,7 +2,28 @@
2
2
  # -*- frozen_string_literal: true -*-
3
3
  # -*- warn_indent: true -*-
4
4
 
5
+ # This module provides parsers and utilities for handling composite unit measurements.
6
+ # It allows parsing and manipulation of various composite measurements for units of
7
+ # +length+, +weight+, +time+ etc.
8
+ #
9
+ # @note
10
+ # This module serves as a namespace for classes and utilities related to composite
11
+ # unit measurements. To parse such measurements, refer to individual classes like
12
+ # {Length}, {Weight}, {Time}, etc. within this module.
13
+ #
14
+ # @example
15
+ # CompositeUnitMeasurements::Length.parse("5 feet 12 inches")
16
+ # => 6.0 ft
17
+ #
18
+ # CompositeUnitMeasurements::Weight.parse("8 lb 12 oz")
19
+ # => 8.75 lb
20
+ #
21
+ # CompositeUnitMeasurements::Time.parse("3 h 45 min")
22
+ # => 3.75 h
23
+ #
24
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
25
+ # @since 0.1.0
5
26
  module CompositeUnitMeasurements
6
27
  # Current stable version
7
- VERSION = "0.2.0"
28
+ VERSION = "0.4.0"
8
29
  end
@@ -0,0 +1,79 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # -*- frozen_string_literal: true -*-
3
+ # -*- warn_indent: true -*-
4
+
5
+ require "unit_measurements/unit_groups/volume"
6
+
7
+ module CompositeUnitMeasurements
8
+ # A parser handling +volume+ measurements, particularly for composite units
9
+ # like +litre-millilitre+, +gallon-quart+, +quart-pint+, etc.
10
+ #
11
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
12
+ # @since 0.4.0
13
+ class Volume
14
+ class << self
15
+ # Parses a given +string+ into a +UnitMeasurements::Volume+ object.
16
+ #
17
+ # @example Parse 'litre-millilitre' measurement:
18
+ # CompositeUnitMeasurements::Volume.parse("2 l 250 ml") #=> 2.25 l
19
+ #
20
+ # @param [String] string The string to parse for volume measurement.
21
+ # @return [UnitMeasurements::Volume]
22
+ # Returns a UnitMeasurements::Volume object if parsing is successful.
23
+ #
24
+ # @raise [UnitMeasurements::ParseError]
25
+ # If the string does not match any known format.
26
+ #
27
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
28
+ # @since 0.4.0
29
+ def parse(string)
30
+ case string
31
+ when LITRE_MILLILITRE then parse_litre_millilitre(string)
32
+ else raise UnitMeasurements::ParseError, string
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ # @private
39
+ # Parses a +string+ representing a volume in the format of +litre-millilitre+
40
+ # into a +UnitMeasurements::Volume+ object.
41
+ #
42
+ # @param [String] string
43
+ # The string representing volume measurement in the format of *litre-millilitre*.
44
+ # @return [UnitMeasurements::Volume]
45
+ # Returns a UnitMeasurements::Volume object if parsing is successful.
46
+ #
47
+ # @see LITRE_MILLILITRE
48
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
49
+ # @since 0.4.0
50
+ def parse_litre_millilitre(string)
51
+ litre, millilitre = string.match(LITRE_MILLILITRE)&.captures
52
+
53
+ if litre && millilitre
54
+ UnitMeasurements::Volume.new(litre, "l") + UnitMeasurements::Volume.new(millilitre, "ml")
55
+ end
56
+ end
57
+ end
58
+
59
+ # Regex pattern for aliases of +litre+ unit.
60
+ #
61
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
62
+ # @since 0.4.0
63
+ LITRE_ALIASES = /(?:l|L|liter(?:s)?|litre(?:s)?)/.freeze
64
+
65
+ # Regex pattern for aliases of +millilitre+ unit.
66
+ #
67
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
68
+ # @since 0.4.0
69
+ MILLILITRE_ALIASES = /(?:ml|mL|milliliter(?:s)?|millilitre(?:s)?)/.freeze
70
+
71
+ # Regex pattern for parsing a volume measurement in the format of +litre-millilitre+.
72
+ #
73
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
74
+ # @since 0.4.0
75
+ LITRE_MILLILITRE = /\A#{ANY_NUMBER}\s*#{LITRE_ALIASES}\s*#{ANY_NUMBER}\s*#{MILLILITRE_ALIASES}\z/.freeze
76
+
77
+ private_constant :LITRE_MILLILITRE, :LITRE_ALIASES, :MILLILITRE_ALIASES
78
+ end
79
+ end
@@ -6,7 +6,7 @@ require "unit_measurements/unit_groups/weight"
6
6
 
7
7
  module CompositeUnitMeasurements
8
8
  # A parser handling +weight+ measurements, particularly for composite units
9
- # like +pound-ounce+, +stone-pound+, +kilogramme-gramme+, etc.
9
+ # like +kilogramme-gramme+, +pound-ounce+, +stone-pound+ etc.
10
10
  #
11
11
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
12
12
  # @since 0.2.0
@@ -14,6 +14,13 @@ module CompositeUnitMeasurements
14
14
  class << self
15
15
  # Parses a given +string+ into a +UnitMeasurements::Weight+ object.
16
16
  #
17
+ # @example Parse 'kilogramme-gramme' measurement:
18
+ # CompositeUnitMeasurements::Weight.parse("4 kg 500 g") #=> 4.5 kg
19
+ # @example Parse 'pound-ounce' measurement:
20
+ # CompositeUnitMeasurements::Weight.parse("8 lb 12 oz") #=> 8.75 lb
21
+ # @example Parse 'stone-pound' measurement:
22
+ # CompositeUnitMeasurements::Weight.parse("2 st 6 lb") #=> 2.428571428571429 st
23
+ #
17
24
  # @param [String] string The string to parse for weight measurement.
18
25
  # @return [UnitMeasurements::Weight]
19
26
  # Returns a UnitMeasurements::Weight object if parsing is successful.
@@ -24,16 +31,18 @@ module CompositeUnitMeasurements
24
31
  # @since 0.2.0
25
32
  def parse(string)
26
33
  case string
27
- when POUND_OUNCE then parse_pound_ounce(string)
28
- when STONE_POUND then parse_stone_pound(string)
29
- else raise UnitMeasurements::ParseError, string
34
+ when POUND_OUNCE then parse_pound_ounce(string)
35
+ when STONE_POUND then parse_stone_pound(string)
36
+ when KILOGRAMME_GRAMME then parse_kilogramme_gramme(string)
37
+ else raise UnitMeasurements::ParseError, string
30
38
  end
31
39
  end
32
40
 
33
41
  private
34
42
 
35
43
  # @private
36
- # Parses a +string+ representing a weight in the format of +pound-ounce+.
44
+ # Parses a +string+ representing a weight in the format of +pound-ounce+
45
+ # into a +UnitMeasurements::Weight+ object.
37
46
  #
38
47
  # @param [String] string
39
48
  # The string representing weight measurement in the format of *pound-ounce*.
@@ -47,12 +56,13 @@ module CompositeUnitMeasurements
47
56
  pound, ounce = string.match(POUND_OUNCE)&.captures
48
57
 
49
58
  if pound && ounce
50
- UnitMeasurements::Weight.new(pound, :lb) + UnitMeasurements::Weight.new(ounce, :oz)
59
+ UnitMeasurements::Weight.new(pound, "lb") + UnitMeasurements::Weight.new(ounce, "oz")
51
60
  end
52
61
  end
53
62
 
54
63
  # @private
55
- # Parses a +string+ representing a weight in the format of +stone-pound+.
64
+ # Parses a +string+ representing a weight in the format of +stone-pound+
65
+ # into a +UnitMeasurements::Weight+ object.
56
66
  #
57
67
  # @param [String] string
58
68
  # The string representing weight measurement in the format of *stone-pound*.
@@ -66,41 +76,80 @@ module CompositeUnitMeasurements
66
76
  stone, pound = string.match(STONE_POUND)&.captures
67
77
 
68
78
  if stone && pound
69
- UnitMeasurements::Weight.new(stone, :st) + UnitMeasurements::Weight.new(pound, :lb)
79
+ UnitMeasurements::Weight.new(stone, "st") + UnitMeasurements::Weight.new(pound, "lb")
70
80
  end
71
81
  end
72
- end
73
82
 
74
- private
83
+ # @private
84
+ # Parses a +string+ representing a weight in the format of +kilogramme-gramme+
85
+ # into a +UnitMeasurements::Weight+ object.
86
+ #
87
+ # @param [String] string
88
+ # The string representing weight measurement in the format of *kilogramme-gramme*.
89
+ # @return [UnitMeasurements::Weight]
90
+ # Returns a UnitMeasurements::Weight object if parsing is successful.
91
+ #
92
+ # @see KILOGRAMME_GRAMME
93
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
94
+ # @since 0.3.0
95
+ def parse_kilogramme_gramme(string)
96
+ kilogramme, gramme = string.match(KILOGRAMME_GRAMME)&.captures
97
+
98
+ if kilogramme && gramme
99
+ UnitMeasurements::Weight.new(kilogramme, "kg") + UnitMeasurements::Weight.new(gramme, "g")
100
+ end
101
+ end
102
+ end
75
103
 
76
104
  # Regex pattern for aliases of +pound+ unit.
77
105
  #
78
106
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
79
107
  # @since 0.2.0
80
- POUND_UNITS = /(?:#|lb|lbs|lbm|pound-mass|pound(?:s)?)/.freeze
108
+ POUND_ALIASES = /(?:#|lb|lbs|lbm|pound-mass|pound(?:s)?)/.freeze
81
109
 
82
110
  # Regex pattern for aliases of +ounce+ unit.
83
111
  #
84
112
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
85
113
  # @since 0.2.0
86
- OUNCE_UNITS = /(?:oz|ounce(?:s)?)/.freeze
114
+ OUNCE_ALIASES = /(?:oz|ounce(?:s)?)/.freeze
87
115
 
88
116
  # Regex pattern for aliases of +stone+ unit.
89
117
  #
90
118
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
91
119
  # @since 0.2.0
92
- STONE_UNITS = /(?:st|stone(?:s)?)/.freeze
120
+ STONE_ALIASES = /(?:st|stone(?:s)?)/.freeze
121
+
122
+ # Regex pattern for aliases of +gramme+ unit.
123
+ #
124
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
125
+ # @since 0.3.0
126
+ GRAMME_ALIASES = /(?:g|gram(?:s)?|gramme(?:s)?)/.freeze
127
+
128
+ # Regex pattern for aliases of +kilogramme+ unit.
129
+ #
130
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
131
+ # @since 0.3.0
132
+ KILOGRAMME_ALIASES = /(?:kg|kilogram(?:s)?|kilogramme(?:s)?)/.freeze
93
133
 
94
134
  # Regex pattern for parsing a weight measurement in the format of +pound-ounce+.
95
135
  #
96
136
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
97
137
  # @since 0.2.0
98
- POUND_OUNCE = /\A#{ANY_NUMBER}\s*#{POUND_UNITS}\s*#{ANY_NUMBER}\s*#{OUNCE_UNITS}\z/.freeze
138
+ POUND_OUNCE = /\A#{ANY_NUMBER}\s*#{POUND_ALIASES}\s*#{ANY_NUMBER}\s*#{OUNCE_ALIASES}\z/.freeze
99
139
 
100
140
  # Regex pattern for parsing a weight measurement in the format of +stone-pound+.
101
141
  #
102
142
  # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
103
143
  # @since 0.2.0
104
- STONE_POUND = /\A#{ANY_NUMBER}\s*#{STONE_UNITS}\s*#{ANY_NUMBER}\s*#{POUND_UNITS}\z/.freeze
144
+ STONE_POUND = /\A#{ANY_NUMBER}\s*#{STONE_ALIASES}\s*#{ANY_NUMBER}\s*#{POUND_ALIASES}\z/.freeze
145
+
146
+ # Regex pattern for parsing a weight measurement in the format of +kilogramme-gramme+.
147
+ #
148
+ # @author {Harshal V. Ladhe}[https://shivam091.github.io/]
149
+ # @since 0.3.0
150
+ KILOGRAMME_GRAMME = /\A#{ANY_NUMBER}\s*#{KILOGRAMME_ALIASES}\s*#{ANY_NUMBER}\s*#{GRAMME_ALIASES}\z/.freeze
151
+
152
+ private_constant :KILOGRAMME_GRAMME, :POUND_ALIASES, :OUNCE_ALIASES, :STONE_ALIASES ,
153
+ :GRAMME_ALIASES, :KILOGRAMME_ALIASES, :POUND_OUNCE, :STONE_POUND
105
154
  end
106
155
  end
@@ -7,3 +7,4 @@ require "composite_unit_measurements/base"
7
7
  require "composite_unit_measurements/length"
8
8
  require "composite_unit_measurements/time"
9
9
  require "composite_unit_measurements/weight"
10
+ require "composite_unit_measurements/volume"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composite_unit_measurements
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harshal LADHE
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-17 00:00:00.000000000 Z
11
+ date: 2023-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -124,6 +124,7 @@ files:
124
124
  - lib/composite_unit_measurements/length.rb
125
125
  - lib/composite_unit_measurements/time.rb
126
126
  - lib/composite_unit_measurements/version.rb
127
+ - lib/composite_unit_measurements/volume.rb
127
128
  - lib/composite_unit_measurements/weight.rb
128
129
  homepage: https://github.com/shivam091/composite_unit_measurements
129
130
  licenses: