Class: Ukiryu::Models::Routing

Inherits:
Object
  • Object
show all
Defined in:
lib/ukiryu/models/routing.rb

Overview

Represents a command routing table for hierarchical tools.

Routing maps command names to their executable targets, enabling tools like git where ‘git remote` routes to `git-remote` executable.

Examples:

Basic routing

routing = Routing.new({ 'remote' => 'git-remote', 'branch' => 'git-branch' })
routing.resolve('remote') # => 'git-remote'

Multi-level routing

routing = Routing.new({ 'remote' => 'git-remote' })
routing.child('remote').merge!({ 'add' => 'action' })
routing.resolve_path(['remote', 'add']) # => ['git-remote', 'action']

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(table = {}, parent: nil) ⇒ Routing

Create a new Routing table

Examples:

Routing.new({ 'remote' => 'git-remote' })
Routing.new({ 'add' => 'action' }, parent_routing)

Parameters:

  • table (Hash) (defaults to: {})

    routing table mapping command names to executables

  • parent (Routing, nil) (defaults to: nil)

    parent routing for multi-level hierarchies



39
40
41
42
43
# File 'lib/ukiryu/models/routing.rb', line 39

def initialize(table = {}, parent: nil)
  @table = symbolize_keys(table)
  @parent = parent
  @children = {}
end

Instance Attribute Details

#parentRouting? (readonly)

Parent routing table for multi-level hierarchies

Returns:



28
29
30
# File 'lib/ukiryu/models/routing.rb', line 28

def parent
  @parent
end

#tableHash<String, String> (readonly)

The routing table mapping command names to executables

Returns:

  • (Hash<String, String>)


23
24
25
# File 'lib/ukiryu/models/routing.rb', line 23

def table
  @table
end

Instance Method Details

#child(command_name) ⇒ Routing

Get a child routing table for a command

Creates or returns the child routing for multi-level hierarchies.

Examples:

routing.child('remote').merge!({ 'add' => 'action' })

Parameters:

  • command_name (String, Symbol)

    the parent command name

Returns:

  • (Routing)

    the child routing table



107
108
109
110
# File 'lib/ukiryu/models/routing.rb', line 107

def child(command_name)
  key = command_name.to_sym
  @children[key] ||= Routing.new(parent: self)
end

#circular?Boolean

Check for circular references in routing hierarchy

Returns:

  • (Boolean)

    true if circular reference detected



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/ukiryu/models/routing.rb', line 164

def circular?
  return false unless @parent

  current = @parent
  seen = { self => true }

  while current
    return true if seen.key?(current)

    seen[current] = true
    current = current.parent
  end

  false
end

#empty?Boolean

Check if the routing table is empty

Returns:

  • (Boolean)

    true if no routing entries



140
141
142
# File 'lib/ukiryu/models/routing.rb', line 140

def empty?
  @table.empty?
end

#include?(command_name) ⇒ Boolean

Check if a command exists in the routing table

Examples:

routing.include?('remote') # => true
routing.include?('unknown') # => false

Parameters:

  • command_name (String, Symbol)

    the command name to check

Returns:

  • (Boolean)

    true if the command exists



92
93
94
95
# File 'lib/ukiryu/models/routing.rb', line 92

def include?(command_name)
  key = command_name.to_sym
  @table.key?(key) || @parent&.include?(key) || false
end

#inspectString

String representation

Returns:

  • (String)

    debug-friendly string representation



184
185
186
187
# File 'lib/ukiryu/models/routing.rb', line 184

def inspect
  parent_info = @parent ? "(parent: #{parent.object_id})" : ''
  "#<#{self.class.name}:#{object_id}#{parent_info} #{@table.keys.inspect}>"
end

#keysArray<String>

Get all command names in this routing table

Examples:

routing.keys # => ['remote', 'branch', 'stash']

Returns:

  • (Array<String>)

    array of command names



132
133
134
# File 'lib/ukiryu/models/routing.rb', line 132

def keys
  @table.keys.map(&:to_s).sort
end

#merge!(other) ⇒ self

Merge a hash into this routing table

Examples:

routing.merge!({ 'branch' => 'git-branch' })

Parameters:

  • other (Hash)

    the routing entries to merge

Returns:

  • (self)

    returns self for chaining



120
121
122
123
# File 'lib/ukiryu/models/routing.rb', line 120

def merge!(other)
  @table.merge!(symbolize_keys(other))
  self
end

#resolve(command_name) ⇒ String?

Resolve a command name to its executable target

Examples:

routing.resolve('remote') # => 'git-remote'
routing.resolve('unknown') # => nil

Parameters:

  • command_name (String, Symbol)

    the command name to resolve

Returns:

  • (String, nil)

    the executable target or nil if not found



54
55
56
57
# File 'lib/ukiryu/models/routing.rb', line 54

def resolve(command_name)
  key = command_name.to_sym
  @table[key] || @parent&.resolve(key)
end

#resolve_path(path) ⇒ Array<String>

Resolve a path of command names to their executable targets

Examples:

routing.resolve_path(['remote', 'add']) # => ['git-remote', 'action']

Parameters:

  • path (Array<String, Symbol>)

    the command path to resolve

Returns:

  • (Array<String>)

    array of executable targets



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/ukiryu/models/routing.rb', line 67

def resolve_path(path)
  return [] if path.empty?

  # Resolve first level in this routing table
  first_target = resolve(path.first)
  return [] unless first_target

  # If there are more levels, resolve them in child routing
  if path.size > 1
    child = child(path.first)
    [first_target, *child.resolve_path(path[1..])]
  else
    [first_target]
  end
end

#sizeInteger

Get the number of routing entries

Returns:

  • (Integer)

    number of entries



148
149
150
# File 'lib/ukiryu/models/routing.rb', line 148

def size
  @table.size
end

#to_hHash

Convert routing table to hash

Returns:

  • (Hash)

    the routing table as a hash



156
157
158
# File 'lib/ukiryu/models/routing.rb', line 156

def to_h
  @table.transform_keys(&:to_s)
end

#to_sString

String representation for debugging

Returns:

  • (String)

    routing table as formatted string



193
194
195
196
197
# File 'lib/ukiryu/models/routing.rb', line 193

def to_s
  return '(empty)' if @table.empty?

  @table.map { |k, v| "#{k} => #{v}" }.join(', ')
end