lago_client/region.rs
1use lago_types::error::LagoError;
2
3/// Represents the different regions where the Lago API can be accessed
4///
5/// This enum defines the available regions for the Lago API, including
6/// predefined regions (US, EU) and custom endpoints.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum Region {
9 Us,
10 Eu,
11 Custom(String),
12}
13
14impl Region {
15 /// Returns the API endpoint URL for this region
16 ///
17 /// # Returns
18 /// The base URL string for the API endpoint
19 pub fn endpoint(&self) -> &str {
20 match self {
21 Region::Us => "https://api.getlago.com/api/v1",
22 Region::Eu => "https://api.eu.getlago.com/api/v1",
23 Region::Custom(url) => url,
24 }
25 }
26}
27
28impl Default for Region {
29 /// Returns the default region (US)
30 ///
31 /// # Returns
32 /// `Region::Us` as the default region
33 fn default() -> Self {
34 Region::Us
35 }
36}
37
38/// Trait for providing region information to the Lago client
39///
40/// This trait allows for different methods of region determination,
41/// such as static configuration, environment variables, or other sources.
42pub trait RegionProvider: Send + Sync {
43 /// Provides the region for API requests
44 ///
45 /// # Returns
46 /// A `Result` containing the `Region` or an error if the region cannot be determined
47 fn provider_region(&self) -> Result<Region, LagoError>;
48}
49
50/// A region provider that uses a static, pre-configured region
51///
52/// This provider holds a region that was provided at creation time
53/// and returns it on every request.
54#[derive(Clone)]
55pub struct StaticRegionProvider {
56 region: Region,
57}
58
59impl StaticRegionProvider {
60 /// Creates a new static region provider with the given region
61 ///
62 /// # Arguments
63 /// * `region` - The region to use for all requests
64 ///
65 /// # Returns
66 /// A new `StaticRegionProvider` instance
67 pub fn new(region: Region) -> Self {
68 Self { region }
69 }
70}
71
72impl RegionProvider for StaticRegionProvider {
73 /// Returns the static region
74 ///
75 /// # Returns
76 /// A `Result` containing a clone of the stored region
77 fn provider_region(&self) -> Result<Region, LagoError> {
78 Ok(self.region.clone())
79 }
80}
81
82/// A region provider that loads region information from environment variables
83///
84/// This provider attempts to load the region from the `LAGO_REGION` environment variable
85/// first, and falls back to `LAGO_API_URL` for custom endpoints. If neither is set,
86/// it returns the default region.
87pub struct EnvironmentRegionProvider;
88
89impl EnvironmentRegionProvider {
90 /// Creates a new environment region provider
91 ///
92 /// # Returns
93 /// A new `EnvironmentRegionProvider` instance
94 pub fn new() -> Self {
95 Self
96 }
97}
98
99impl Default for EnvironmentRegionProvider {
100 /// Creates a default environment region provider
101 ///
102 /// This is equivalent to calling `EnvironmentRegionProvider::new()`.
103 fn default() -> Self {
104 Self::new()
105 }
106}
107
108impl RegionProvider for EnvironmentRegionProvider {
109 /// Loads region information from environment variables
110 ///
111 /// This method first checks the `LAGO_REGION` environment variable for predefined
112 /// regions ("us", "eu") or treats other values as custom endpoints.
113 /// If `LAGO_REGION` is not set, it falls back to `LAGO_API_URL`.
114 /// If neither is set, it returns the default region.
115 ///
116 /// # Returns
117 /// A `Result` containing the determined `Region`
118 fn provider_region(&self) -> Result<Region, LagoError> {
119 match std::env::var("LAGO_REGION") {
120 Ok(region_str) => match region_str.to_lowercase().as_str() {
121 "us" => Ok(Region::Us),
122 "eu" => Ok(Region::Eu),
123 _ => Ok(Region::Custom(region_str)),
124 },
125 Err(_) => match std::env::var("LAGO_API_URL") {
126 Ok(url) => Ok(Region::Custom(url)),
127 Err(_) => Ok(Region::default()),
128 },
129 }
130 }
131}