use super::{Guid, IFeatureUsageTrackingManager, IFeatureUsageTrackingSession, IFeatureUsageTrackingSessionOf};
use crate::logging::IEnableLogger;
use ferroui_system::IDisposable;
use std::rc::Rc;
pub struct DefaultFeatureUsageTrackingSession {
parent_reference: Guid,
feature_reference: Guid,
feature_name: String,
}
impl DefaultFeatureUsageTrackingSession {
pub fn new(feature_name: &str) -> Self {
Self::with_parent(feature_name, Guid::EMPTY)
}
pub(crate) fn with_parent(feature_name: &str, parent_reference: Guid) -> Self {
assert!(!feature_name.trim().is_empty(), "The value cannot be an empty string or composed entirely of whitespace. (Parameter 'featureName')");
let session = Self {
parent_reference,
feature_reference: Guid::new_guid(),
feature_name: feature_name.to_owned(),
};
session.log().info_fn(&|| session.session_start_log_message());
session
}
fn session_start_log_message(&self) -> String {
let mut message = format!("Feature Start. Reference={}", self.feature_reference);
if self.parent_reference != Guid::EMPTY {
message += &format!(", Parent Reference={}", self.parent_reference);
}
message
}
}
impl IEnableLogger for DefaultFeatureUsageTrackingSession {}
impl IFeatureUsageTrackingSession for DefaultFeatureUsageTrackingSession {
fn feature_name(&self) -> &str {
&self.feature_name
}
fn sub_feature(&self, description: &str) -> Rc<dyn IFeatureUsageTrackingSession> {
Rc::new(Self::with_parent(description, self.feature_reference))
}
fn on_exception(&self, exception: &dyn std::error::Error) {
self.log().info_exception_fn(exception, &|| "Feature Usage Tracking Exception".to_owned());
}
}
impl IFeatureUsageTrackingSessionOf<Guid> for DefaultFeatureUsageTrackingSession {
fn feature_reference(&self) -> Guid {
self.feature_reference
}
fn parent_reference(&self) -> Guid {
self.parent_reference
}
}
impl IDisposable for DefaultFeatureUsageTrackingSession {
fn dispose(&self) {
self.log().info_fn(&|| format!("Feature Finish: {}", self.feature_reference));
}
}
pub struct FuncFeatureUsageTrackingManager {
feature_usage_tracking_session_func: Box<dyn Fn(&str) -> Rc<dyn IFeatureUsageTrackingSession>>,
}
impl FuncFeatureUsageTrackingManager {
pub fn new(
feature_usage_tracking_session_func: impl Fn(&str) -> Rc<dyn IFeatureUsageTrackingSession> + 'static,
) -> Self {
Self { feature_usage_tracking_session_func: Box::new(feature_usage_tracking_session_func) }
}
}
impl IFeatureUsageTrackingManager for FuncFeatureUsageTrackingManager {
fn get_feature_usage_tracking_session(&self, feature_name: &str) -> Rc<dyn IFeatureUsageTrackingSession> {
(self.feature_usage_tracking_session_func)(feature_name)
}
}
pub struct DefaultFeatureUsageTrackingManager {
inner: FuncFeatureUsageTrackingManager,
}
impl Default for DefaultFeatureUsageTrackingManager {
fn default() -> Self {
Self::new()
}
}
impl DefaultFeatureUsageTrackingManager {
pub fn new() -> Self {
Self {
inner: FuncFeatureUsageTrackingManager::new(|feature_name| {
Rc::new(DefaultFeatureUsageTrackingSession::new(feature_name)) as Rc<dyn IFeatureUsageTrackingSession>
}),
}
}
}
impl IFeatureUsageTrackingManager for DefaultFeatureUsageTrackingManager {
fn get_feature_usage_tracking_session(&self, feature_name: &str) -> Rc<dyn IFeatureUsageTrackingSession> {
self.inner.get_feature_usage_tracking_session(feature_name)
}
}