ckb_sentry_types/protocol/
session.rs1use std::borrow::Cow;
2use std::fmt;
3use std::net::IpAddr;
4use std::str;
5
6use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8use thiserror::Error;
9use uuid::Uuid;
10
11#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
13#[serde(rename_all = "snake_case")]
14pub enum SessionStatus {
15 Ok,
19 Exited,
21 Crashed,
23 Abnormal,
25}
26
27impl Default for SessionStatus {
28 fn default() -> Self {
29 Self::Ok
30 }
31}
32
33#[derive(Debug, Error)]
35#[error("invalid session status")]
36pub struct ParseSessionStatusError;
37
38impl str::FromStr for SessionStatus {
39 type Err = ParseSessionStatusError;
40
41 fn from_str(string: &str) -> Result<Self, Self::Err> {
42 Ok(match string {
43 "ok" => SessionStatus::Ok,
44 "crashed" => SessionStatus::Crashed,
45 "abnormal" => SessionStatus::Abnormal,
46 "exited" => SessionStatus::Exited,
47 _ => return Err(ParseSessionStatusError),
48 })
49 }
50}
51
52impl fmt::Display for SessionStatus {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 match *self {
55 SessionStatus::Ok => write!(f, "ok"),
56 SessionStatus::Crashed => write!(f, "crashed"),
57 SessionStatus::Abnormal => write!(f, "abnormal"),
58 SessionStatus::Exited => write!(f, "exited"),
59 }
60 }
61}
62
63#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
65pub struct SessionAttributes<'a> {
66 pub release: Cow<'a, str>,
68
69 #[serde(default, skip_serializing_if = "Option::is_none")]
71 pub environment: Option<Cow<'a, str>>,
72
73 #[serde(default, skip_serializing_if = "Option::is_none")]
75 pub ip_address: Option<IpAddr>,
76
77 #[serde(default, skip_serializing_if = "Option::is_none")]
79 pub user_agent: Option<String>,
80}
81
82#[allow(clippy::trivially_copy_pass_by_ref)]
83fn is_false(val: &bool) -> bool {
84 !val
85}
86
87#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
92pub struct SessionUpdate<'a> {
93 #[serde(rename = "sid", default = "Uuid::new_v4")]
95 pub session_id: Uuid,
96
97 #[serde(rename = "did", default)]
99 pub distinct_id: Option<String>,
100
101 #[serde(rename = "seq", default, skip_serializing_if = "Option::is_none")]
103 pub sequence: Option<u64>,
104
105 #[serde(default, skip_serializing_if = "Option::is_none")]
107 pub timestamp: Option<DateTime<Utc>>,
108
109 #[serde(default = "Utc::now")]
111 pub started: DateTime<Utc>,
112
113 #[serde(default, skip_serializing_if = "is_false")]
115 pub init: bool,
116
117 #[serde(default, skip_serializing_if = "Option::is_none")]
119 pub duration: Option<f64>,
120
121 #[serde(default)]
123 pub status: SessionStatus,
124
125 #[serde(default)]
127 pub errors: u64,
128
129 #[serde(rename = "attrs")]
131 pub attributes: SessionAttributes<'a>,
132}