SamovarSourceSamovarTable

class Table

Represents a table of parsing rows for a command.

A table manages the collection of options, arguments, and nested commands that define how to parse a command line.

Definitions

def self.nested(klass, parent = nil)

Create a nested table that inherits from the parent class's table.

Signature

parameter klass Class

The command class to create a table for.

parameter parent Table | Nil

The parent table to inherit from.

returns Table

The new table.

Implementation

def self.nested(klass, parent = nil)
	if klass.superclass.respond_to?(:table)
		parent = klass.superclass.table
	end
	
	self.new(parent, name: klass.name)
end

def initialize(parent = nil, name: nil)

Initialize a new table.

Signature

parameter parent Table | Nil

The parent table to inherit from.

parameter name String | Nil

The name of the command this table belongs to.

Implementation

def initialize(parent = nil, name: nil)
	@parent = parent
	@name = name
	@rows = {}
end

def freeze

Freeze this table.

Signature

returns Table

The frozen table.

Implementation

def freeze
	return self if frozen?
	
	@rows.freeze
	
	super
end

def [](key)

Get a row by key.

Signature

parameter key Symbol

The key to look up.

returns Object | Nil

The row with the given key.

Implementation

def [] key
	@rows[key]
end

def each(&block)

Iterate over each row.

Signature

yields {|row| ...}

Each row in the table.

Implementation

def each(&block)
	@rows.each_value(&block)
end

def <<(row)

Add a row to the table.

Implementation

def << row
	if existing_row = @rows[row.key] and existing_row.respond_to?(:merge!)
		existing_row.merge!(row)
	else
		# In the above case where there is an existing row, but it doensn't support being merged, we overwrite it. This preserves order.
		@rows[row.key] = row.dup
	end
end

def empty?

Check if this table is empty.

Signature

returns Boolean

True if this table and its parent are empty.

Implementation

def empty?
	@rows.empty? && @parent&.empty?
end

def merge_into(table)

Merge this table's rows into another table.

Signature

parameter table Table

The table to merge into.

returns Table

The merged table.

Implementation

def merge_into(table)
	@parent&.merge_into(table)
	
	@rows.each_value do |row|
		table << row
	end
	
	return table
end

def merged

Get a merged table that includes parent rows.

Signature

returns Table

The merged table.

Implementation

def merged
	if @parent.nil? or @parent.empty?
		return self
	else
		merge_into(self.class.new)
	end
end

def usage

Generate a usage string from all rows.

Signature

returns String

The usage string.

Implementation

def usage
	@rows.each_value.collect(&:to_s).reject(&:empty?).join(" ")
end

def parse(input, parent)

Parse the input according to the rows in this table.

Signature

parameter input Array(String)

The command-line arguments.

parameter parent Command

The parent command to store results in.

Implementation

def parse(input, parent)
	@rows.each do |key, row|
		next unless row.respond_to?(:parse)
		
		current = parent.send(key)
		
		result = row.parse(input, parent, current)
		if result != nil
			parent.public_send("#{row.key}=", result)
		end
	end
end