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

LOGGER_READER =
Object.new.freeze
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.



99
100
101
102
# File 'lib/charming/application.rb', line 99

def initialize
  @logger = self.class.logger
  @session = {}
end

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



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

def logger
  @logger
end

#sessionObject (readonly)

Returns the value of attribute session.



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

def session
  @session
end

#task_executorObject

Returns the value of attribute task_executor.



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

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.



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

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

  @default_theme = name.to_sym
end

.logger(value = LOGGER_READER) ⇒ Object

Returns or sets the app logger. Defaults to a null-device logger so app and framework code can safely call logging methods without writing into the terminal UI.



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

def logger(value = LOGGER_READER)
  return configured_logger if value == LOGGER_READER

  @logger = value
end

.namespaceObject

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



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

def namespace
  ActiveSupport::Inflector.deconstantize(name.to_s)
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).



36
37
38
39
40
# File 'lib/charming/application.rb', line 36

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.



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

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)


44
45
46
47
48
49
50
51
52
53
# File 'lib/charming/application.rb', line 44

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
    UI::Theme.load_builtin(built_in)
  else
    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.



70
71
72
73
74
75
# File 'lib/charming/application.rb', line 70

def theme_for(name = nil)
  theme_name = name || default_theme
  return 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.



56
57
58
# File 'lib/charming/application.rb', line 56

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.



105
106
107
# File 'lib/charming/application.rb', line 105

def routes
  self.class.routes
end

#themeObject



109
110
111
# File 'lib/charming/application.rb', line 109

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

#use_theme(name) ⇒ Object



113
114
115
116
# File 'lib/charming/application.rb', line 113

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