1use std::fmt;
2
3pub const US_INGESTION_ENDPOINT: &str = "https://us.i.posthog.com";
5
6pub const EU_INGESTION_ENDPOINT: &str = "https://eu.i.posthog.com";
8
9pub const DEFAULT_HOST: &str = US_INGESTION_ENDPOINT;
11
12#[derive(Debug, Clone)]
14pub enum Endpoint {
15 Capture,
17 Batch,
19 Flags,
21 LocalEvaluation,
23}
24
25impl Endpoint {
26 pub fn path(&self) -> &str {
28 match self {
29 Endpoint::Capture => "/i/v0/e/",
30 Endpoint::Batch => "/batch/",
31 Endpoint::Flags => "/flags/?v=2",
32 Endpoint::LocalEvaluation => "/flags/definitions/?send_cohorts",
33 }
34 }
35}
36
37impl fmt::Display for Endpoint {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "{}", self.path())
40 }
41}
42
43#[derive(Debug, Clone)]
45pub struct EndpointManager {
46 base_host: String,
47 raw_host: String,
48}
49
50impl EndpointManager {
51 pub fn new(host: String) -> Self {
53 let base_host = Self::determine_server_host(&host);
54
55 Self {
56 base_host,
57 raw_host: host,
58 }
59 }
60
61 pub fn determine_server_host(host: &str) -> String {
64 let trimmed_host = host.trim_end_matches('/');
65
66 match trimmed_host {
67 "https://app.posthog.com" | "https://us.posthog.com" => {
68 US_INGESTION_ENDPOINT.to_string()
69 }
70 "https://eu.posthog.com" => EU_INGESTION_ENDPOINT.to_string(),
71 _ => trimmed_host.to_string(),
72 }
73 }
74
75 pub fn base_host(&self) -> &str {
77 &self.base_host
78 }
79
80 pub fn raw_host(&self) -> &str {
82 &self.raw_host
83 }
84
85 pub fn build_url(&self, endpoint: Endpoint) -> String {
87 format!(
88 "{}{}",
89 self.base_host.trim_end_matches('/'),
90 endpoint.path()
91 )
92 }
93
94 pub fn build_custom_url(&self, path: &str) -> String {
96 let normalized_path = if path.starts_with('/') {
97 path.to_string()
98 } else {
99 format!("/{path}")
100 };
101 format!(
102 "{}{}",
103 self.base_host.trim_end_matches('/'),
104 normalized_path
105 )
106 }
107
108 pub fn build_local_eval_url(&self, token: &str) -> String {
110 format!(
111 "{}/flags/definitions/?token={}&send_cohorts",
112 self.base_host.trim_end_matches('/'),
113 token
114 )
115 }
116
117 pub fn api_host(&self) -> String {
119 self.base_host.trim_end_matches('/').to_string()
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_determine_server_host() {
129 assert_eq!(
130 EndpointManager::determine_server_host("https://app.posthog.com"),
131 US_INGESTION_ENDPOINT
132 );
133
134 assert_eq!(
135 EndpointManager::determine_server_host("https://us.posthog.com"),
136 US_INGESTION_ENDPOINT
137 );
138
139 assert_eq!(
140 EndpointManager::determine_server_host("https://eu.posthog.com"),
141 EU_INGESTION_ENDPOINT
142 );
143
144 assert_eq!(
145 EndpointManager::determine_server_host("https://custom.domain.com"),
146 "https://custom.domain.com"
147 );
148
149 assert_eq!(
150 EndpointManager::determine_server_host("https://eu.posthog.com/"),
151 EU_INGESTION_ENDPOINT
152 );
153 }
154
155 #[test]
156 fn test_build_url() {
157 let manager = EndpointManager::new(DEFAULT_HOST.to_string());
158
159 assert_eq!(
160 manager.build_url(Endpoint::Capture),
161 format!("{}/i/v0/e/", US_INGESTION_ENDPOINT)
162 );
163
164 assert_eq!(
165 manager.build_url(Endpoint::Flags),
166 format!("{}/flags/?v=2", US_INGESTION_ENDPOINT)
167 );
168 }
169
170 #[test]
171 fn test_build_custom_url() {
172 let manager = EndpointManager::new("https://custom.com/".to_string());
173
174 assert_eq!(
175 manager.build_custom_url("/api/test"),
176 "https://custom.com/api/test"
177 );
178
179 assert_eq!(
180 manager.build_custom_url("api/test"),
181 "https://custom.com/api/test"
182 );
183 }
184}