Class: Charming::Application

Inherits:
Object
  • Object
show all
Defined in:
lib/charming/application.rb

Overview

Application is a lightweight, Rails-inspired application base for building terminal-based apps. It provides routing (via a DSL), session storage, and task execution for managing async operations.

Constant Summary collapse

THEME_READER =
Object.new.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeApplication

Initializes an empty session hash for per-request state storage.



83
84
85
# File 'lib/charming/application.rb', line 83

def initialize
  @session = {}
end

Instance Attribute Details

#sessionObject (readonly)

Returns the value of attribute session.



80
81
82
# File 'lib/charming/application.rb', line 80

def session
  @session
end

#task_executorObject

Returns the value of attribute task_executor.



79
80
81
# File 'lib/charming/application.rb', line 79

def task_executor
  @task_executor
end

Class Method Details

.default_theme(name = THEME_READER) ⇒ Object

Returns the default theme name, or sets it when name is given. When unset, falls back to the first registered theme. Used by ‘theme_for` when no name is provided.



53
54
55
56
57
# File 'lib/charming/application.rb', line 53

def default_theme(name = THEME_READER)
  return @default_theme || themes.keys.first if name == THEME_READER

  @default_theme = name.to_sym
end

.namespaceObject

Derives the module namespace from the class name — e.g., Admin::HomeController yields “Admin”. Mirrors Rails’ engine-style namespacing.



21
22
23
# File 'lib/charming/application.rb', line 21

def namespace
  name&.split("::")&.then { |parts| parts[0...-1].join("::") }
end

.root(path = THEME_READER) ⇒ Object

Returns the app’s filesystem root, used to resolve relative theme and template paths. Pass path to set it; without arguments it returns the current value (or nil if unset).



27
28
29
30
31
# File 'lib/charming/application.rb', line 27

def root(path = THEME_READER)
  return @root if path == THEME_READER

  @root = File.expand_path(path)
end

.routes(&block) ⇒ Object

Registers or returns the app’s Router. Accepts an optional block to define routes via DSL (screen, root). Lazily initializes a new Router per namespace.



13
14
15
16
17
# File 'lib/charming/application.rb', line 13

def routes(&block)
  @routes ||= Router.new(namespace: namespace)
  @routes.draw(&block) if block
  @routes
end

.theme(name, from: nil, built_in: nil) ⇒ Object

Registers a named theme. Provide either from: (path to a JSON file relative to the app root) or built_in: (name of a bundled theme such as “phosphor”). Raises when neither or both are given.

Raises:

  • (ArgumentError)


35
36
37
38
39
40
41
42
43
44
# File 'lib/charming/application.rb', line 35

def theme(name, from: nil, built_in: nil)
  raise ArgumentError, "theme expects from: or built_in:" unless from || built_in
  raise ArgumentError, "theme expects either from: or built_in:, not both" if from && built_in

  themes[name.to_sym] = if built_in
    Presentation::UI::Theme.load_builtin(built_in)
  else
    Presentation::UI::Theme.load_file(resolve_theme_path(from))
  end
end

.theme_for(name = nil) ⇒ Object

Resolves a theme by name (or the default theme when name is nil). Returns the default built-in theme if no name is given and no default is registered.



61
62
63
64
65
66
# File 'lib/charming/application.rb', line 61

def theme_for(name = nil)
  theme_name = name || default_theme
  return Presentation::UI::Theme.default unless theme_name

  themes.fetch(theme_name.to_sym)
end

.themesObject

Hash of all registered themes keyed by symbol, including those inherited from superclasses.



47
48
49
# File 'lib/charming/application.rb', line 47

def themes
  @themes ||= superclass.respond_to?(:themes) ? superclass.themes.dup : {}
end

Instance Method Details

#routesObject

Delegates to the class-level Router, providing instance access to route definitions.



88
89
90
# File 'lib/charming/application.rb', line 88

def routes
  self.class.routes
end

#themeObject



92
93
94
# File 'lib/charming/application.rb', line 92

def theme
  self.class.theme_for(session[:theme])
end

#use_theme(name) ⇒ Object



96
97
98
99
# File 'lib/charming/application.rb', line 96

def use_theme(name)
  self.class.theme_for(name)
  session[:theme] = name.to_sym
end