Class: Iriq::Shape

Inherits:
Object
  • Object
show all
Defined in:
lib/iriq/shape.rb

Overview

Structured route shape: an ordered list of typed segment entries plus rendering methods that produce the various string forms (placeholder, canonical-dates, raw-types, etc.).

Replaces the string-as-data convention where PathShape’s String output was the only carrier of shape information. Structured Shape makes:

- downstream consumers cheap (they iterate entries instead of
  re-deriving from segments + classifier)
- shape identity explicit (structural #== / #hash, not string match)
- multiple renderings free (canonical dates, hints on/off, raw types
  vs hinted) without re-walking segments

The cluster identity layer still uses string keys for storage; a follow-up step migrates Cluster equality to be Shape-driven.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(entries:) ⇒ Shape

Returns a new instance of Shape.



31
32
33
# File 'lib/iriq/shape.rb', line 31

def initialize(entries:)
  @entries = entries
end

Instance Attribute Details

#entriesObject (readonly)

Returns the value of attribute entries.



17
18
19
# File 'lib/iriq/shape.rb', line 17

def entries
  @entries
end

Class Method Details

.from_dump(h) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/iriq/shape.rb', line 71

def self.from_dump(h)
  entries = (h["entries"] || []).map do |e|
    e.each_with_object({}) do |(k, v), acc|
      key = k.to_sym
      # Only :type is symbolized — :value and :hint stay as strings,
      # matching what SegmentHints.derive produces.
      acc[key] = key == :type ? v.to_sym : v
    end
  end
  new(entries: entries)
end

.from_entries(entries) ⇒ Object

Build a Shape from already-derived SegmentHints entries — same input PathShape.from_entries used to take. Useful when the caller already walked segments once and wants to avoid a second pass.



27
28
29
# File 'lib/iriq/shape.rb', line 27

def self.from_entries(entries)
  new(entries: entries || [])
end

.from_segments(segments, classifier: SegmentClassifier::DEFAULT) ⇒ Object

Build a Shape from raw path segments using the given classifier.



20
21
22
# File 'lib/iriq/shape.rb', line 20

def self.from_segments(segments, classifier: SegmentClassifier::DEFAULT)
  new(entries: SegmentHints.derive(segments || [], classifier))
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Structural equality: two Shapes are equal when they render the same placeholder form. /users/1 and /users/999 are the same shape even though raw values differ, but /users/1 and /posts/1 are not.



58
59
60
# File 'lib/iriq/shape.rb', line 58

def ==(other)
  other.is_a?(Shape) && other.render == render
end

#empty?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/iriq/shape.rb', line 35

def empty?
  @entries.empty?
end

#hashObject



63
64
65
# File 'lib/iriq/shape.rb', line 63

def hash
  render.hash
end

#render(hints: true, canonical_dates: false, canonical_currencies: false) ⇒ Object

Render to the placeholder form — “/users/user_id” etc. This is the default string representation.



41
42
43
44
45
46
47
48
# File 'lib/iriq/shape.rb', line 41

def render(hints: true, canonical_dates: false, canonical_currencies: false)
  return "/" if empty?

  "/" + @entries.map { |e|
    render_entry(e, hints: hints, canonical_dates: canonical_dates,
                    canonical_currencies: canonical_currencies)
  }.join("/")
end

#to_dumpObject



67
68
69
# File 'lib/iriq/shape.rb', line 67

def to_dump
  { "entries" => @entries.map { |e| e.transform_keys(&:to_s) } }
end

#to_sObject Also known as: inspect



50
51
52
# File 'lib/iriq/shape.rb', line 50

def to_s
  render
end