Skip to main content

cargo_move/
application.rs

1//! CargoMove Abscissa Application
2
3use crate::{commands::CargoMoveCmd, config::CargoMoveConfig};
4use abscissa_core::{
5    application, config, logging, Application, EntryPoint, FrameworkError, StandardPaths,
6};
7use lazy_static::lazy_static;
8
9lazy_static! {
10    /// Application state
11    pub static ref APPLICATION: application::Lock<CargoMoveApp> = application::Lock::default();
12}
13
14/// Obtain a read-only (multi-reader) lock on the application state.
15///
16/// Panics if the application state has not been initialized.
17pub fn app_reader() -> application::lock::Reader<CargoMoveApp> {
18    APPLICATION.read()
19}
20
21/// Obtain an exclusive mutable lock on the application state.
22pub fn app_writer() -> application::lock::Writer<CargoMoveApp> {
23    APPLICATION.write()
24}
25
26/// Obtain a read-only (multi-reader) lock on the application configuration.
27///
28/// Panics if the application configuration has not been loaded.
29pub fn app_config() -> config::Reader<CargoMoveApp> {
30    config::Reader::new(&APPLICATION)
31}
32
33/// CargoMove Application
34#[derive(Debug)]
35pub struct CargoMoveApp {
36    /// Application configuration.
37    config: Option<CargoMoveConfig>,
38
39    /// Application state.
40    state: application::State<Self>,
41}
42
43/// Initialize a new application instance.
44///
45/// By default no configuration is loaded, and the framework state is
46/// initialized to a default, empty state (no components, threads, etc).
47impl Default for CargoMoveApp {
48    fn default() -> Self {
49        Self {
50            config: None,
51            state: application::State::default(),
52        }
53    }
54}
55
56impl Application for CargoMoveApp {
57    /// Entrypoint command for this application.
58    type Cmd = EntryPoint<CargoMoveCmd>;
59
60    /// Application configuration.
61    type Cfg = CargoMoveConfig;
62
63    /// Paths to resources within the application.
64    type Paths = StandardPaths;
65
66    /// Accessor for application configuration.
67    fn config(&self) -> &CargoMoveConfig {
68        self.config.as_ref().expect("config not loaded")
69    }
70
71    /// Borrow the application state immutably.
72    fn state(&self) -> &application::State<Self> {
73        &self.state
74    }
75
76    /// Borrow the application state mutably.
77    fn state_mut(&mut self) -> &mut application::State<Self> {
78        &mut self.state
79    }
80
81    /// Register all components used by this application.
82    ///
83    /// If you would like to add additional components to your application
84    /// beyond the default ones provided by the framework, this is the place
85    /// to do so.
86    fn register_components(&mut self, command: &Self::Cmd) -> Result<(), FrameworkError> {
87        let components = self.framework_components(command)?;
88        self.state.components.register(components)
89    }
90
91    /// Post-configuration lifecycle callback.
92    ///
93    /// Called regardless of whether config is loaded to indicate this is the
94    /// time in app lifecycle when configuration would be loaded if
95    /// possible.
96    fn after_config(&mut self, config: Self::Cfg) -> Result<(), FrameworkError> {
97        // Configure components
98        self.state.components.after_config(&config)?;
99        self.config = Some(config);
100        Ok(())
101    }
102
103    /// Get logging configuration from command-line options
104    fn logging_config(&self, command: &EntryPoint<CargoMoveCmd>) -> logging::Config {
105        if command.verbose {
106            logging::Config::verbose()
107        } else {
108            logging::Config::default()
109        }
110    }
111}