Skip to main content

finance_query/constants/enums/
frequency.rs

1use serde::{Deserialize, Serialize};
2
3/// Frequency for financial data (annual or quarterly)
4///
5/// The `alias`es mirror the shorthands [`FromStr`](std::str::FromStr) accepts, so
6/// deserializing (axum query extraction, JSON) takes the same spellings parsing does.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[serde(rename_all = "lowercase")]
9pub enum Frequency {
10    /// Annual financial data
11    #[serde(alias = "yearly", alias = "year")]
12    Annual,
13    /// Quarterly financial data
14    #[serde(alias = "quarter", alias = "q")]
15    Quarterly,
16}
17
18impl Frequency {
19    /// Convert frequency to string representation
20    pub fn as_str(&self) -> &'static str {
21        match self {
22            Frequency::Annual => "annual",
23            Frequency::Quarterly => "quarterly",
24        }
25    }
26
27    /// Build a fundamental type string with frequency prefix
28    ///
29    /// # Example
30    ///
31    /// ```
32    /// use finance_query::Frequency;
33    ///
34    /// let field = Frequency::Annual.prefix("TotalRevenue");
35    /// assert_eq!(field, "annualTotalRevenue");
36    /// ```
37    pub fn prefix(&self, field: &str) -> String {
38        format!("{}{}", self.as_str(), field)
39    }
40}
41
42impl std::str::FromStr for Frequency {
43    type Err = ();
44
45    /// Case-insensitive; accepts `as_str()`'s canonical form plus common
46    /// shorthands (`"year"`/`"yearly"`, `"quarter"`/`"q"`).
47    fn from_str(s: &str) -> Result<Self, Self::Err> {
48        match s.to_lowercase().as_str() {
49            "annual" | "yearly" | "year" => Ok(Frequency::Annual),
50            "quarterly" | "quarter" | "q" => Ok(Frequency::Quarterly),
51            _ => Err(()),
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn test_frequency_from_str_round_trips_as_str() {
62        for frequency in [Frequency::Annual, Frequency::Quarterly] {
63            assert_eq!(frequency.as_str().parse(), Ok(frequency));
64        }
65        assert_eq!("YEARLY".parse(), Ok(Frequency::Annual));
66        assert_eq!("q".parse(), Ok(Frequency::Quarterly));
67        assert_eq!("bogus".parse::<Frequency>(), Err(()));
68    }
69}