use std::time::Instant;
use crate::options::ClientOptions;
use crate::protocol::{SessionEnd, SessionStart, SessionStatus, User};
use crate::util;
#[derive(Debug, Clone)]
pub struct Session {
session_id: String,
release: String,
environment: Option<String>,
user_id: Option<String>,
status: SessionStatus,
started: Instant,
}
impl Session {
pub fn start(options: &ClientOptions, user: Option<&User>) -> Option<Session> {
let release = options.release.clone()?;
Some(Session {
session_id: util::new_trace_id(),
release,
environment: Some(options.resolved_environment()),
user_id: user.and_then(|u| u.id.clone()),
status: SessionStatus::Ok,
started: Instant::now(),
})
}
pub fn id(&self) -> &str {
&self.session_id
}
pub fn status(&self) -> SessionStatus {
self.status
}
pub fn mark_errored(&mut self) {
if self.status == SessionStatus::Ok {
self.status = SessionStatus::Errored;
}
}
pub fn mark_crashed(&mut self) {
self.status = SessionStatus::Crashed;
}
pub fn to_start(&self) -> SessionStart {
SessionStart {
session_id: self.session_id.clone(),
release: self.release.clone(),
environment: self.environment.clone(),
user_id: self.user_id.clone(),
sdk_name: Some(util::SDK_NAME.to_string()),
sdk_version: Some(util::SDK_VERSION.to_string()),
platform: Some(util::PLATFORM.to_string()),
}
}
pub fn to_end(&self, status: Option<SessionStatus>) -> SessionEnd {
let final_status = status.unwrap_or(match self.status {
SessionStatus::Ok => SessionStatus::Exited,
other => other,
});
SessionEnd {
session_id: self.session_id.clone(),
release: self.release.clone(),
environment: self.environment.clone(),
user_id: self.user_id.clone(),
sdk_name: Some(util::SDK_NAME.to_string()),
sdk_version: Some(util::SDK_VERSION.to_string()),
platform: Some(util::PLATFORM.to_string()),
duration_ms: self.started.elapsed().as_millis() as u64,
status: final_status.as_str().to_string(),
}
}
}