Module: Ace::B36ts::Atoms::FormatSpecs
- Defined in:
- lib/ace/b36ts/atoms/format_specs.rb
Overview
Format specifications for granular timestamp encoding.
Defines 7 format types with varying precision and length:
-
2sec (6 chars, ~1.85s precision) - default
-
month (2 chars, month precision)
-
week (3 chars, week precision)
-
day (3 chars, day precision)
-
40min (4 chars, 40-minute block precision)
-
50ms (7 chars, ~50ms precision)
-
ms (8 chars, ~1.4ms precision)
Day/week disambiguation (3-char formats):
-
Day format: 3rd character in 0-30 range
-
Week format: 3rd character in 31-35 range
Defined Under Namespace
Classes: FormatSpec
Constant Summary collapse
- FORMATS =
All supported format specifications
{ "2sec": FormatSpec.new( name: :"2sec", length: 6, precision_desc: "~1.85s", pattern: /\A[0-9a-z]{6}\z/i ), month: FormatSpec.new( name: :month, length: 2, precision_desc: "month", pattern: /\A[0-9a-z]{2}\z/i ), week: FormatSpec.new( name: :week, length: 3, precision_desc: "week", pattern: /\A[0-9a-z]{3}\z/i ), day: FormatSpec.new( name: :day, length: 3, precision_desc: "day", pattern: /\A[0-9a-z]{3}\z/i ), "40min": FormatSpec.new( name: :"40min", length: 4, precision_desc: "40min", pattern: /\A[0-9a-z]{4}\z/i ), "50ms": FormatSpec.new( name: :"50ms", length: 7, precision_desc: "~50ms", pattern: /\A[0-9a-z]{7}\z/i ), ms: FormatSpec.new( name: :ms, length: 8, precision_desc: "~1.4ms", pattern: /\A[0-9a-z]{8}\z/i ) }.freeze
- DAY_FORMAT_MAX =
Day/week disambiguation for 3-char formats Day format: 3rd char (day value) is 0-30 Week format: 3rd char (week value) is 31-35
30- WEEK_FORMAT_MIN =
31- WEEK_FORMAT_MAX =
35- SPLIT_LEVELS =
%i[month week day block].freeze
Class Method Summary collapse
-
.all_formats ⇒ Array<Symbol>
Get all format names.
-
.all_lengths ⇒ Array<Integer>
Get all supported lengths.
-
.detect_from_id(encoded_id, alphabet: CompactIdEncoder::DEFAULT_ALPHABET) ⇒ Symbol?
Detect format from ID string For 3-char IDs, uses the 3rd character value to distinguish day vs week.
-
.get(name) ⇒ FormatSpec?
Get format specification by name.
-
.valid_format?(name) ⇒ Boolean
Check if format name is valid.
-
.valid_split_levels?(levels) ⇒ Boolean
Validate split level ordering and hierarchy.
Class Method Details
.all_formats ⇒ Array<Symbol>
Get all format names
103 104 105 |
# File 'lib/ace/b36ts/atoms/format_specs.rb', line 103 def all_formats FORMATS.keys end |
.all_lengths ⇒ Array<Integer>
Get all supported lengths
110 111 112 |
# File 'lib/ace/b36ts/atoms/format_specs.rb', line 110 def all_lengths FORMATS.values.map(&:length).uniq.sort end |
.detect_from_id(encoded_id, alphabet: CompactIdEncoder::DEFAULT_ALPHABET) ⇒ Symbol?
Detect format from ID string For 3-char IDs, uses the 3rd character value to distinguish day vs week
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/ace/b36ts/atoms/format_specs.rb', line 138 def detect_from_id(encoded_id, alphabet: CompactIdEncoder::DEFAULT_ALPHABET) return nil if encoded_id.nil? || encoded_id.empty? # Validate all characters are in the alphabet # Use Set for faster character validation (O(1) vs O(n)) alphabet_set = (alphabet == CompactIdEncoder::DEFAULT_ALPHABET) ? CompactIdEncoder::DEFAULT_ALPHABET_SET : alphabet.chars.to_set return nil unless encoded_id.downcase.chars.all? { |c| alphabet_set.include?(c) } length = encoded_id.length case length when 2 :month when 3 # Disambiguate day vs week by 3rd character value third_char_value = alphabet.index(encoded_id[2].downcase) return nil if third_char_value.nil? if third_char_value <= DAY_FORMAT_MAX :day elsif third_char_value <= WEEK_FORMAT_MAX :week end # Note: With base36 (values 0-35), day covers 0-30 and week covers 31-35, # so all valid values are handled. This branch implicitly returns nil # only if alphabet validation fails (which is caught earlier). when 4 :"40min" when 6 :"2sec" when 7 :"50ms" when 8 :ms end end |
.get(name) ⇒ FormatSpec?
Get format specification by name
88 89 90 |
# File 'lib/ace/b36ts/atoms/format_specs.rb', line 88 def get(name) FORMATS[name] end |
.valid_format?(name) ⇒ Boolean
Check if format name is valid
96 97 98 |
# File 'lib/ace/b36ts/atoms/format_specs.rb', line 96 def valid_format?(name) FORMATS.key?(name) end |
.valid_split_levels?(levels) ⇒ Boolean
Validate split level ordering and hierarchy
118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/ace/b36ts/atoms/format_specs.rb', line 118 def valid_split_levels?(levels) return false unless levels.is_a?(Array) return false if levels.empty? return false unless levels.all? { |level| SPLIT_LEVELS.include?(level) } return false unless levels.uniq.length == levels.length return false unless levels.first == :month indices = levels.map { |level| SPLIT_LEVELS.index(level) } return false unless indices == indices.sort return false if levels.include?(:block) && !levels.include?(:day) true end |