1use std::collections::HashMap;
2use serde_json::Value;
3
4#[derive(Debug, Clone, PartialEq)]
5pub struct RequestContext {
6 inner: HashMap<String, Value>,
7}
8
9pub const ATTR_USER_ID: &str = "user.id";
10pub const ATTR_USER_EMAIL: &str = "user.email";
11pub const ATTR_USER_ANONYMOUS: &str = "user.anonymous";
12pub const ATTR_COUNTRY_CODE: &str = "country_code";
13pub const ATTR_REGION: &str = "region";
14pub const ATTR_CITY: &str = "city";
15pub const ATTR_MANUFACTURER: &str = "manufacturer";
16pub const ATTR_DEVICE_TYPE: &str = "device_type";
17pub const ATTR_OS: &str = "os";
18pub const ATTR_OS_VERSION: &str = "os_version";
19pub const ATTR_BROWSER: &str = "browser";
20pub const ATTR_BROWSER_VERSION: &str = "browser_version";
21pub const ATTR_LANGUAGE: &str = "language";
22pub const ATTR_CONNECTION_TYPE: &str = "connection_type";
23pub const ATTR_AGE: &str = "age";
24pub const ATTR_GENDER: &str = "gender";
25pub const ATTR_IP: &str = "ip";
26pub const ATTR_APP_VERSION: &str = "app_version";
27pub const ATTR_PLATFORM: &str = "platform";
28
29impl RequestContext {
30 pub fn new() -> Self {
31 Self {
32 inner: HashMap::new(),
33 }
34 }
35
36 pub fn with_user_id(mut self, id: &str) -> Self {
37 self.inner.insert(ATTR_USER_ID.to_string(), Value::String(id.to_string()));
38 self
39 }
40
41 pub fn with_user_email(mut self, email: &str) -> Self {
42 self.inner.insert(ATTR_USER_EMAIL.to_string(), Value::String(email.to_string()));
43 self
44 }
45
46 pub fn with_user_anonymous(mut self, anonymous: bool) -> Self {
47 self.inner.insert(ATTR_USER_ANONYMOUS.to_string(), Value::Bool(anonymous));
48 self
49 }
50
51 pub fn with_country_code(mut self, code: &str) -> Self {
52 self.inner.insert(ATTR_COUNTRY_CODE.to_string(), Value::String(code.to_string()));
53 self
54 }
55
56 pub fn with_region(mut self, region: &str) -> Self {
57 self.inner.insert(ATTR_REGION.to_string(), Value::String(region.to_string()));
58 self
59 }
60
61 pub fn with_city(mut self, city: &str) -> Self {
62 self.inner.insert(ATTR_CITY.to_string(), Value::String(city.to_string()));
63 self
64 }
65
66 pub fn with_manufacturer(mut self, manufacturer: &str) -> Self {
67 self.inner.insert(ATTR_MANUFACTURER.to_string(), Value::String(manufacturer.to_string()));
68 self
69 }
70
71 pub fn with_device_type(mut self, device_type: &str) -> Self {
72 self.inner.insert(ATTR_DEVICE_TYPE.to_string(), Value::String(device_type.to_string()));
73 self
74 }
75
76 pub fn with_os(mut self, os: &str) -> Self {
77 self.inner.insert(ATTR_OS.to_string(), Value::String(os.to_string()));
78 self
79 }
80
81 pub fn with_os_version(mut self, version: &str) -> Self {
82 self.inner.insert(ATTR_OS_VERSION.to_string(), Value::String(version.to_string()));
83 self
84 }
85
86 pub fn with_browser(mut self, browser: &str) -> Self {
87 self.inner.insert(ATTR_BROWSER.to_string(), Value::String(browser.to_string()));
88 self
89 }
90
91 pub fn with_browser_version(mut self, version: &str) -> Self {
92 self.inner.insert(ATTR_BROWSER_VERSION.to_string(), Value::String(version.to_string()));
93 self
94 }
95
96 pub fn with_language(mut self, language: &str) -> Self {
97 self.inner.insert(ATTR_LANGUAGE.to_string(), Value::String(language.to_string()));
98 self
99 }
100
101 pub fn with_connection_type(mut self, connection_type: &str) -> Self {
102 self.inner.insert(ATTR_CONNECTION_TYPE.to_string(), Value::String(connection_type.to_string()));
103 self
104 }
105
106 pub fn with_age(mut self, age: i32) -> Self {
107 self.inner.insert(ATTR_AGE.to_string(), Value::Number(age.into()));
108 self
109 }
110
111 pub fn with_gender(mut self, gender: &str) -> Self {
112 self.inner.insert(ATTR_GENDER.to_string(), Value::String(gender.to_string()));
113 self
114 }
115
116 pub fn with_ip(mut self, ip: &str) -> Self {
117 self.inner.insert(ATTR_IP.to_string(), Value::String(ip.to_string()));
118 self
119 }
120
121 pub fn with_app_version(mut self, version: &str) -> Self {
122 self.inner.insert(ATTR_APP_VERSION.to_string(), Value::String(version.to_string()));
123 self
124 }
125
126 pub fn with_platform(mut self, platform: &str) -> Self {
127 self.inner.insert(ATTR_PLATFORM.to_string(), Value::String(platform.to_string()));
128 self
129 }
130
131 pub fn set(mut self, key: &str, value: Value) -> Self {
132 self.inner.insert(key.to_string(), value);
133 self
134 }
135
136 pub fn set_many(mut self, values: HashMap<String, Value>) -> Self {
137 for (key, value) in values {
138 self.inner.insert(key, value);
139 }
140 self
141 }
142
143 pub fn is_empty(&self) -> bool {
144 self.inner.is_empty()
145 }
146
147 pub fn to_map(&self) -> HashMap<String, Value> {
148 self.inner.clone()
149 }
150}
151
152impl RequestContext {
153 pub fn default() -> Self {
154 Self::new()
155 }
156}