Module: UsageCredits::PeriodParser
- Defined in:
- lib/usage_credits/helpers/period_parser.rb
Overview
Handles parsing and normalization of time periods throughout the gem. Converts strings like "1.month" or symbols like :monthly into ActiveSupport::Duration objects.
Constant Summary collapse
- VALID_PERIODS =
Canonical periods and their aliases
{ second: [:second, :seconds], # 1.second minute: [:minute, :minutes], # 1.minute hour: [:hour, :hours, :hourly], # 1.hour day: [:day, :daily], # 1.day week: [:week, :weekly], # 1.week month: [:month, :monthly], # 1.month quarter: [:quarter, :quarterly], # 3.months year: [:year, :yearly, :annually] # 1.year }.freeze
- MIN_PERIOD =
Deprecated: Use UsageCredits.configuration.min_fulfillment_period instead
1.day
Class Method Summary collapse
-
.canonical_unit_for(unit) ⇒ Symbol
Map any alias to its canonical unit method name.
-
.min_fulfillment_period ⇒ Object
Get the configured minimum fulfillment period.
-
.normalize_period(period) ⇒ Object
Turns things like
:monthlyinto1.monthto always store consistent time periods. -
.parse_period(period_str) ⇒ ActiveSupport::Duration
Parse a period string into an ActiveSupport::Duration.
-
.valid_period_format?(period_str) ⇒ Boolean
Validates that a period string matches the expected format and units.
Class Method Details
.canonical_unit_for(unit) ⇒ Symbol
Map any alias to its canonical unit method name
96 97 98 99 100 101 102 103 104 |
# File 'lib/usage_credits/helpers/period_parser.rb', line 96 def canonical_unit_for(unit) # Find which canonical unit this alias belongs to VALID_PERIODS.each do |canonical, aliases| return canonical if aliases.include?(unit) end # Fallback to the unit itself if not found (shouldn't happen if validation passed) unit end |
.min_fulfillment_period ⇒ Object
Get the configured minimum fulfillment period
25 26 27 28 29 30 31 32 |
# File 'lib/usage_credits/helpers/period_parser.rb', line 25 def min_fulfillment_period # Use configured value if available, otherwise fall back to default if defined?(UsageCredits) && UsageCredits.respond_to?(:configuration) UsageCredits.configuration.min_fulfillment_period else MIN_PERIOD end end |
.normalize_period(period) ⇒ Object
Turns things like :monthly into 1.month to always store consistent time periods
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/usage_credits/helpers/period_parser.rb', line 35 def normalize_period(period) return nil unless period # Handle ActiveSupport::Duration objects directly if period.is_a?(ActiveSupport::Duration) min_period = min_fulfillment_period raise ArgumentError, "Period must be at least #{min_period.inspect}" if period < min_period period else # Convert symbols to canonical durations duration = case period when *VALID_PERIODS[:second] then 1.second when *VALID_PERIODS[:minute] then 1.minute when *VALID_PERIODS[:hour] then 1.hour when *VALID_PERIODS[:day] then 1.day when *VALID_PERIODS[:week] then 1.week when *VALID_PERIODS[:month] then 1.month when *VALID_PERIODS[:quarter] then 3.months when *VALID_PERIODS[:year] then 1.year else raise ArgumentError, "Unsupported period: #{period}. Supported periods: #{VALID_PERIODS.values.flatten.inspect}" end min_period = min_fulfillment_period raise ArgumentError, "Period must be at least #{min_period.inspect}" if duration < min_period duration end end |
.parse_period(period_str) ⇒ ActiveSupport::Duration
Parse a period string into an ActiveSupport::Duration
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/usage_credits/helpers/period_parser.rb', line 68 def parse_period(period_str) return period_str if period_str.is_a?(ActiveSupport::Duration) if period_str.to_s =~ /\A(\d+)[.\s](\w+)\z/ amount = $1.to_i unit = $2.singularize.to_sym # Validate the unit is supported valid_units = VALID_PERIODS.values.flatten unless valid_units.include?(unit) raise ArgumentError, "Unsupported period unit: #{unit}. Supported units: #{valid_units.inspect}" end # Map alias to canonical unit (e.g., :hourly -> :hour, :seconds -> :second) canonical_unit = canonical_unit_for(unit) duration = amount.send(canonical_unit) min_period = min_fulfillment_period raise ArgumentError, "Period must be at least #{min_period.inspect}" if duration < min_period duration else raise ArgumentError, "Invalid period format: #{period_str}. Expected format: '1.month', '2 months', etc." end end |
.valid_period_format?(period_str) ⇒ Boolean
Validates that a period string matches the expected format and units
107 108 109 110 111 112 |
# File 'lib/usage_credits/helpers/period_parser.rb', line 107 def valid_period_format?(period_str) parse_period(period_str) true rescue ArgumentError false end |