Skip to main content

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}