composite_unit_measurements 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: