Skip to main content

ferric_fred/
ids.rs

1/// A FRED series identifier, e.g. `GNPCA` or `UNRATE`.
2///
3/// A newtype over `String` so a series id can't be silently swapped for another
4/// kind of identifier or an arbitrary string (see ADR-0005). Construction does
5/// no validation for now — FRED rejects malformed ids — but the newtype gives
6/// us a place to add it later without changing call sites.
7#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
8#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
9pub struct SeriesId(String);
10
11impl SeriesId {
12    /// Wrap a string as a [`SeriesId`].
13    pub fn new(id: impl Into<String>) -> Self {
14        Self(id.into())
15    }
16
17    /// Borrow the identifier as a string slice.
18    pub fn as_str(&self) -> &str {
19        &self.0
20    }
21}
22
23impl std::fmt::Display for SeriesId {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        f.write_str(&self.0)
26    }
27}
28
29impl From<&str> for SeriesId {
30    fn from(s: &str) -> Self {
31        Self(s.to_owned())
32    }
33}
34
35impl From<String> for SeriesId {
36    fn from(s: String) -> Self {
37        Self(s)
38    }
39}
40
41/// A FRED category identifier — a numeric node in the category tree (the root is
42/// [`CategoryId::ROOT`], id `0`).
43///
44/// A `Copy` newtype over `u32` so a category id can't be silently swapped for a
45/// parent id, a count, or an arbitrary number (ADR-0005). `#[serde(transparent)]`
46/// carries it on the wire as the bare integer FRED sends.
47#[derive(
48    Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize,
49)]
50#[serde(transparent)]
51#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
52pub struct CategoryId(u32);
53
54impl CategoryId {
55    /// The root of the FRED category tree (id `0`).
56    pub const ROOT: Self = Self(0);
57
58    /// Wrap a numeric id as a [`CategoryId`].
59    pub fn new(id: u32) -> Self {
60        Self(id)
61    }
62
63    /// The underlying numeric id.
64    pub fn get(self) -> u32 {
65        self.0
66    }
67}
68
69impl std::fmt::Display for CategoryId {
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        write!(f, "{}", self.0)
72    }
73}
74
75impl From<u32> for CategoryId {
76    fn from(id: u32) -> Self {
77        Self(id)
78    }
79}
80
81/// A FRED release identifier — the numeric id of a data release (a publication
82/// such as "Gross Domestic Product").
83///
84/// A `Copy` newtype over `u32`, mirroring [`CategoryId`]; `#[serde(transparent)]`
85/// carries it as the bare integer FRED sends (ADR-0005).
86#[derive(
87    Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize,
88)]
89#[serde(transparent)]
90#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
91pub struct ReleaseId(u32);
92
93impl ReleaseId {
94    /// Wrap a numeric id as a [`ReleaseId`].
95    pub fn new(id: u32) -> Self {
96        Self(id)
97    }
98
99    /// The underlying numeric id.
100    pub fn get(self) -> u32 {
101        self.0
102    }
103}
104
105impl std::fmt::Display for ReleaseId {
106    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107        write!(f, "{}", self.0)
108    }
109}
110
111impl From<u32> for ReleaseId {
112    fn from(id: u32) -> Self {
113        Self(id)
114    }
115}
116
117/// A FRED release-table element identifier — the numeric id of a node in a
118/// release's table tree (a section, table, or series row; see
119/// `fred/release/tables`).
120///
121/// A `Copy` newtype over `u32`, mirroring [`ReleaseId`]; `#[serde(transparent)]`
122/// carries it as the bare integer FRED sends (ADR-0005). `Ord` lets the table
123/// deserializer order its roots deterministically by id.
124#[derive(
125    Debug,
126    Clone,
127    Copy,
128    PartialEq,
129    Eq,
130    PartialOrd,
131    Ord,
132    Hash,
133    Default,
134    serde::Serialize,
135    serde::Deserialize,
136)]
137#[serde(transparent)]
138#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
139pub struct ReleaseElementId(u32);
140
141impl ReleaseElementId {
142    /// Wrap a numeric id as a [`ReleaseElementId`].
143    pub fn new(id: u32) -> Self {
144        Self(id)
145    }
146
147    /// The underlying numeric id.
148    pub fn get(self) -> u32 {
149        self.0
150    }
151}
152
153impl std::fmt::Display for ReleaseElementId {
154    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155        write!(f, "{}", self.0)
156    }
157}
158
159impl From<u32> for ReleaseElementId {
160    fn from(id: u32) -> Self {
161        Self(id)
162    }
163}
164
165/// A FRED source identifier — the numeric id of a data source (the organization
166/// that produces a release, e.g. the Bureau of Economic Analysis).
167///
168/// A `Copy` newtype over `u32`, mirroring [`ReleaseId`]; `#[serde(transparent)]`
169/// carries it as the bare integer FRED sends (ADR-0005).
170#[derive(
171    Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize,
172)]
173#[serde(transparent)]
174#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
175pub struct SourceId(u32);
176
177impl SourceId {
178    /// Wrap a numeric id as a [`SourceId`].
179    pub fn new(id: u32) -> Self {
180        Self(id)
181    }
182
183    /// The underlying numeric id.
184    pub fn get(self) -> u32 {
185        self.0
186    }
187}
188
189impl std::fmt::Display for SourceId {
190    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
191        write!(f, "{}", self.0)
192    }
193}
194
195impl From<u32> for SourceId {
196    fn from(id: u32) -> Self {
197        Self(id)
198    }
199}