clean_insights_sdk/
visit.rs1use chrono::{DateTime, Timelike, Utc};
2use chrono::serde::ts_seconds;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
6pub struct Visit {
7
8 #[serde(rename = "action_name", serialize_with = "serialize_scene_path", deserialize_with = "deserialize_action_name")]
10 pub scene_path: Vec<String>,
11
12 pub campaign_id: String,
14
15 pub times: u32,
17
18 #[serde(rename = "period_start", with = "ts_seconds")]
20 pub first: DateTime<Utc>,
21
22 #[serde(rename = "period_end", with = "ts_seconds")]
24 pub last: DateTime<Utc>,
25}
26
27fn serialize_scene_path<S>(scene_path: &Vec<String>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
28 serializer.serialize_str(scene_path.join("/").as_str())
29}
30
31fn deserialize_action_name<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error> where D: Deserializer<'de> {
32 let action_name = String::deserialize(deserializer)?;
33
34 Ok(action_name.split('/').map(|item| item.to_owned()).collect())
35}
36
37impl Visit {
38
39 pub fn new(scene_path: Vec<String>, campaign_id: String) -> Visit {
51 let now = Utc::now().with_nanosecond(0).unwrap();
52
53 Visit { scene_path, campaign_id, times: 1, first: now.clone(), last: now }
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use chrono::TimeZone;
61
62 #[test]
63 fn new_visit() {
64 let visit = Visit {
65 scene_path: vec!["foo".to_string(), "bar".to_string()],
66 campaign_id: "test".to_string(),
67 times: 100,
68 first: Utc.timestamp_opt(0, 0).unwrap(),
69 last: Utc.timestamp_opt(0, 0).unwrap() };
70
71 let json = serde_json::to_string(&visit).unwrap();
72
73 assert_eq!(json,
74 "{\"action_name\":\"foo/bar\",\"campaign_id\":\"test\",\"times\":100,\"period_start\":0,\"period_end\":0}");
75
76 let visit2: Visit = serde_json::from_str(json.as_str()).unwrap();
77
78 assert_eq!(visit2, visit);
79 }
80
81 #[test]
82 fn new_visit_with_defaults() {
83 let visit = Visit::new(
84 vec!["foo".to_string(), "bar".to_string()],
85 "test".to_string());
86
87 let json = serde_json::to_string(&visit).unwrap();
88 let now = Utc::now().timestamp();
89
90 assert_eq!(json,
91 format!("{{\"action_name\":\"foo/bar\",\"campaign_id\":\"test\",\"times\":1,\"period_start\":{now},\"period_end\":{now}}}", now=now));
92
93 let visit2: Visit = serde_json::from_str(json.as_str()).unwrap();
94
95 assert_eq!(visit2, visit);
96 }
97}