use std::fmt;
use crate::{
Client, Result,
endpoints::{
EndpointSpec, QueryEncoder, QueryParameters,
metadata::{EndpointBounds, EndpointMetadata},
},
query::RetrievalFrequency,
responses::statements::RevenueSegmentation,
types::Ticker,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SegmentationStructure {
Flat,
}
impl SegmentationStructure {
pub const fn as_str(self) -> &'static str {
match self {
Self::Flat => "flat",
}
}
}
impl fmt::Display for SegmentationStructure {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.as_str())
}
}
macro_rules! segmentation_query {
($docs:literal, $query:ident) => {
#[doc = $docs]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct $query {
symbol: Ticker,
period: Option<RetrievalFrequency>,
structure: Option<SegmentationStructure>,
}
impl $query {
pub fn new(symbol: Ticker) -> Self {
Self {
symbol,
period: None,
structure: None,
}
}
pub const fn with_period(mut self, period: RetrievalFrequency) -> Self {
self.period = Some(period);
self
}
pub const fn with_structure(mut self, structure: SegmentationStructure) -> Self {
self.structure = Some(structure);
self
}
pub fn symbol(&self) -> &Ticker {
&self.symbol
}
pub const fn period(&self) -> Option<RetrievalFrequency> {
self.period
}
pub const fn structure(&self) -> Option<SegmentationStructure> {
self.structure
}
}
impl From<Ticker> for $query {
fn from(symbol: Ticker) -> Self {
Self::new(symbol)
}
}
impl From<&Ticker> for $query {
fn from(symbol: &Ticker) -> Self {
Self::new(symbol.clone())
}
}
impl QueryParameters for $query {
fn encode(&self, encoder: &mut QueryEncoder<'_>) {
encoder.required("symbol", &self.symbol);
encoder.optional("period", self.period);
encoder.optional("structure", self.structure);
}
}
};
}
segmentation_query!(
"Query parameters for product revenue segmentation.",
RevenueProductSegmentationQuery
);
segmentation_query!(
"Query parameters for geographic revenue segmentation.",
RevenueGeographicSegmentationQuery
);
const SEGMENTATION_METADATA: EndpointMetadata =
EndpointMetadata::new().with_bounds(EndpointBounds::new().with_response_rows(1_000));
pub fn revenue_product_segmentation(
query: RevenueProductSegmentationQuery,
) -> EndpointSpec<RevenueProductSegmentationQuery, Vec<RevenueSegmentation>> {
EndpointSpec::get(
"revenue-product-segmentation",
"revenue-product-segmentation",
query,
)
.with_metadata(SEGMENTATION_METADATA)
}
pub fn revenue_geographic_segmentation(
query: RevenueGeographicSegmentationQuery,
) -> EndpointSpec<RevenueGeographicSegmentationQuery, Vec<RevenueSegmentation>> {
EndpointSpec::get(
"revenue-geographic-segmentation",
"revenue-geographic-segmentation",
query,
)
.with_metadata(SEGMENTATION_METADATA)
}
impl Client {
pub async fn revenue_product_segmentation(
&self,
query: impl Into<RevenueProductSegmentationQuery>,
) -> Result<Vec<RevenueSegmentation>> {
self.execute(&revenue_product_segmentation(query.into()))
.await
}
pub async fn revenue_geographic_segmentation(
&self,
query: impl Into<RevenueGeographicSegmentationQuery>,
) -> Result<Vec<RevenueSegmentation>> {
self.execute(&revenue_geographic_segmentation(query.into()))
.await
}
}