ferroui_splat/application_performance_monitoring/
default_feature_usage_tracking.rs1use super::{Guid, IFeatureUsageTrackingManager, IFeatureUsageTrackingSession, IFeatureUsageTrackingSessionOf};
5use crate::logging::IEnableLogger;
6use ferroui_system::IDisposable;
7use std::rc::Rc;
8
9pub struct DefaultFeatureUsageTrackingSession {
12 parent_reference: Guid,
13 feature_reference: Guid,
14 feature_name: String,
15}
16
17impl DefaultFeatureUsageTrackingSession {
18 pub fn new(feature_name: &str) -> Self {
22 Self::with_parent(feature_name, Guid::EMPTY)
23 }
24
25 pub(crate) fn with_parent(feature_name: &str, parent_reference: Guid) -> Self {
27 assert!(!feature_name.trim().is_empty(), "The value cannot be an empty string or composed entirely of whitespace. (Parameter 'featureName')");
28 let session = Self {
29 parent_reference,
30 feature_reference: Guid::new_guid(),
31 feature_name: feature_name.to_owned(),
32 };
33 session.log().info_fn(&|| session.session_start_log_message());
34 session
35 }
36
37 fn session_start_log_message(&self) -> String {
38 let mut message = format!("Feature Start. Reference={}", self.feature_reference);
39 if self.parent_reference != Guid::EMPTY {
40 message += &format!(", Parent Reference={}", self.parent_reference);
41 }
42 message
43 }
44}
45
46impl IEnableLogger for DefaultFeatureUsageTrackingSession {}
47
48impl IFeatureUsageTrackingSession for DefaultFeatureUsageTrackingSession {
49 fn feature_name(&self) -> &str {
50 &self.feature_name
51 }
52
53 fn sub_feature(&self, description: &str) -> Rc<dyn IFeatureUsageTrackingSession> {
54 Rc::new(Self::with_parent(description, self.feature_reference))
55 }
56
57 fn on_exception(&self, exception: &dyn std::error::Error) {
58 self.log().info_exception_fn(exception, &|| "Feature Usage Tracking Exception".to_owned());
59 }
60}
61
62impl IFeatureUsageTrackingSessionOf<Guid> for DefaultFeatureUsageTrackingSession {
63 fn feature_reference(&self) -> Guid {
64 self.feature_reference
65 }
66
67 fn parent_reference(&self) -> Guid {
68 self.parent_reference
69 }
70}
71
72impl IDisposable for DefaultFeatureUsageTrackingSession {
73 fn dispose(&self) {
74 self.log().info_fn(&|| format!("Feature Finish: {}", self.feature_reference));
75 }
76}
77
78pub struct FuncFeatureUsageTrackingManager {
80 feature_usage_tracking_session_func: Box<dyn Fn(&str) -> Rc<dyn IFeatureUsageTrackingSession>>,
81}
82
83impl FuncFeatureUsageTrackingManager {
84 pub fn new(
86 feature_usage_tracking_session_func: impl Fn(&str) -> Rc<dyn IFeatureUsageTrackingSession> + 'static,
87 ) -> Self {
88 Self { feature_usage_tracking_session_func: Box::new(feature_usage_tracking_session_func) }
89 }
90}
91
92impl IFeatureUsageTrackingManager for FuncFeatureUsageTrackingManager {
93 fn get_feature_usage_tracking_session(&self, feature_name: &str) -> Rc<dyn IFeatureUsageTrackingSession> {
94 (self.feature_usage_tracking_session_func)(feature_name)
95 }
96}
97
98pub struct DefaultFeatureUsageTrackingManager {
101 inner: FuncFeatureUsageTrackingManager,
102}
103
104impl Default for DefaultFeatureUsageTrackingManager {
105 fn default() -> Self {
106 Self::new()
107 }
108}
109
110impl DefaultFeatureUsageTrackingManager {
111 pub fn new() -> Self {
113 Self {
114 inner: FuncFeatureUsageTrackingManager::new(|feature_name| {
115 Rc::new(DefaultFeatureUsageTrackingSession::new(feature_name)) as Rc<dyn IFeatureUsageTrackingSession>
116 }),
117 }
118 }
119}
120
121impl IFeatureUsageTrackingManager for DefaultFeatureUsageTrackingManager {
122 fn get_feature_usage_tracking_session(&self, feature_name: &str) -> Rc<dyn IFeatureUsageTrackingSession> {
123 self.inner.get_feature_usage_tracking_session(feature_name)
124 }
125}