1+ use std:: { collections:: HashMap , process:: Command , sync:: Mutex , time:: { SystemTime , UNIX_EPOCH } } ;
2+
3+ use cargo_metadata:: { CargoOpt , MetadataCommand } ;
4+ use lazy_static:: lazy_static;
5+ use uuid:: Uuid ;
6+
7+ use crate :: { commons:: exception:: connect_exception:: ConnectException , infrastructure:: { db_service:: DBService , db_service_lite:: DBServiceLite } } ;
8+
9+ lazy_static ! {
10+ static ref INSTANCE : Mutex <Option <Configuration >> = Mutex :: new( None ) ;
11+ }
12+
13+ #[ derive( Clone ) ]
14+ pub struct Configuration {
15+ rustc_version : String ,
16+ cargo_version : String ,
17+ app_name : String ,
18+ app_version : String ,
19+ session_id : String ,
20+ timestamp : u128 ,
21+ services : HashMap < String , DBService >
22+ }
23+
24+ impl Configuration {
25+
26+ pub fn initialize ( ) -> Configuration {
27+ let mut instance = INSTANCE . lock ( ) . expect ( "Could not lock mutex" ) ;
28+ if instance. is_some ( ) {
29+ //TODO: Log.
30+ panic ! ( "Configuration is already initialized." ) ;
31+ }
32+
33+ let rustc_version = Configuration :: command_rustc_version ( ) ;
34+ let cargo_version = Configuration :: command_cargo_version ( ) ;
35+
36+ let metadata = MetadataCommand :: new ( )
37+ . features ( CargoOpt :: AllFeatures )
38+ . exec ( )
39+ . unwrap ( ) ;
40+
41+ let root: & cargo_metadata:: Package = metadata. packages . iter ( )
42+ . find ( |i| i. name == "rust_db_manager_core" ) . unwrap ( ) ;
43+
44+ let app_name = root. name . clone ( ) ;
45+ let app_version = root. version . clone ( ) . to_string ( ) ;
46+
47+ let session_id = Uuid :: new_v4 ( ) . to_string ( ) ;
48+ let timestamp = SystemTime :: now ( )
49+ . duration_since ( UNIX_EPOCH )
50+ . expect ( "Cannot read actual date." )
51+ . as_millis ( ) ;
52+ let services = HashMap :: new ( ) ;
53+
54+ let config = Configuration {
55+ rustc_version, cargo_version, app_name, app_version, session_id, timestamp, services
56+ } ;
57+
58+ * instance = Some ( config) ;
59+
60+ return instance. as_ref ( ) . unwrap ( ) . clone ( ) ;
61+ }
62+
63+ fn command_cargo_version ( ) -> String {
64+ Configuration :: command_lang_version ( "cargo" )
65+ }
66+
67+ fn command_rustc_version ( ) -> String {
68+ Configuration :: command_lang_version ( "rustc" )
69+ }
70+
71+ fn command_lang_version ( resource : & str ) -> String {
72+ let output = Command :: new ( resource)
73+ . arg ( "--version" )
74+ . output ( )
75+ . expect ( "Failed to execute command" ) ;
76+ if output. status . success ( ) {
77+ return String :: from_utf8_lossy ( & output. stdout ) . to_string ( ) ;
78+ } else {
79+ //TODO: Log.
80+ panic ! ( "Failed to get {} version" , resource) ;
81+ }
82+ }
83+
84+ fn instance ( ) -> Configuration {
85+ let instance = INSTANCE . lock ( ) . expect ( "Could not lock mutex" ) ;
86+ if instance. is_none ( ) {
87+ //TODO: Log.
88+ panic ! ( "Configuration is not initialized." ) ;
89+ }
90+
91+ return instance. as_ref ( ) . unwrap ( ) . clone ( ) ;
92+ }
93+
94+ pub fn rustc_version ( ) -> String {
95+ Configuration :: instance ( ) . rustc_version
96+ }
97+
98+ pub fn cargo_version ( ) -> String {
99+ Configuration :: instance ( ) . cargo_version
100+ }
101+
102+ pub fn name ( ) -> String {
103+ Configuration :: instance ( ) . app_name
104+ }
105+
106+ pub fn version ( ) -> String {
107+ Configuration :: instance ( ) . app_version
108+ }
109+
110+ pub fn session_id ( ) -> String {
111+ Configuration :: instance ( ) . session_id
112+ }
113+
114+ pub fn timestamp ( ) -> u128 {
115+ Configuration :: instance ( ) . timestamp
116+ }
117+
118+ pub fn find_services ( ) -> Vec < DBServiceLite > {
119+ let mut instance = INSTANCE . lock ( ) . expect ( "Could not lock mutex" ) ;
120+
121+ let config = match instance. as_mut ( ) {
122+ Some ( config) => config,
123+ None => panic ! ( "Configuration is not initialized." ) ,
124+ } ;
125+
126+ config. services . iter ( ) . map ( |s| DBServiceLite :: new ( s. 1 . name ( ) , s. 1 . category ( ) ) ) . collect ( )
127+ }
128+
129+ pub fn find_service ( key : & str ) -> Option < DBService > {
130+ let mut instance = INSTANCE . lock ( ) . expect ( "Could not lock mutex" ) ;
131+
132+ let config = match instance. as_mut ( ) {
133+ Some ( config) => config,
134+ None => panic ! ( "Configuration is not initialized." ) ,
135+ } ;
136+
137+ config. services . get ( key) . cloned ( )
138+ }
139+
140+ pub fn push_service ( service : & DBService ) -> Result < & DBService , ConnectException > {
141+ let mut instance = INSTANCE . lock ( ) . expect ( "Could not lock mutex" ) ;
142+
143+ let config = match instance. as_mut ( ) {
144+ Some ( config) => config,
145+ None => panic ! ( "Configuration is not initialized." ) ,
146+ } ;
147+
148+ if config. services . contains_key ( & service. name ( ) ) {
149+ let exception = ConnectException :: new ( String :: from ( "Service already exists." ) ) ;
150+ return Err ( exception) ;
151+ }
152+
153+ config. services . insert ( service. name ( ) , service. clone ( ) ) ;
154+
155+ return Ok ( service) ;
156+ }
157+
158+ pub fn put_service ( service : DBService ) -> DBService {
159+ let mut instance = INSTANCE . lock ( ) . expect ( "Could not lock mutex" ) ;
160+
161+ let config = match instance. as_mut ( ) {
162+ Some ( config) => config,
163+ None => panic ! ( "Configuration is not initialized." ) ,
164+ } ;
165+
166+ config. services . insert ( service. name ( ) , service. clone ( ) ) ;
167+
168+ return service;
169+ }
170+
171+ pub fn remove_service ( service : DBService ) -> Option < DBService > {
172+ let mut instance = INSTANCE . lock ( ) . expect ( "Could not lock mutex" ) ;
173+
174+ let config = match instance. as_mut ( ) {
175+ Some ( config) => config,
176+ None => panic ! ( "Configuration is not initialized." ) ,
177+ } ;
178+
179+ return config. services . remove ( & service. name ( ) ) ;
180+ }
181+
182+ }
0 commit comments