use crate::model::enums::{ExchCode, MarketSecDesc, SecurityType, SecurityType2};
use serde::{Deserialize, Serialize};
pub trait FigiData {
fn figi_data(&self) -> &[FigiResult];
fn next_page(&self) -> Option<&str> {
None
}
fn total_results(&self) -> Option<usize> {
None
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ResponseResult<T> {
Success(T),
Error(ResponseError),
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ResponseError {
pub error: String,
}
impl<T: FigiData> ResponseResult<T> {
#[must_use]
pub fn is_success(&self) -> bool {
matches!(self, ResponseResult::Success(_))
}
#[must_use]
pub fn is_error(&self) -> bool {
matches!(self, ResponseResult::Error(_))
}
#[must_use]
pub fn data(&self) -> Option<&[FigiResult]> {
match self {
ResponseResult::Success(success) => Some(success.figi_data()),
ResponseResult::Error(_) => None,
}
}
#[must_use]
pub fn next_page(&self) -> Option<&str> {
match self {
ResponseResult::Success(success) => success.next_page(),
ResponseResult::Error(_) => None,
}
}
#[must_use]
pub fn total_results(&self) -> Option<usize> {
match self {
ResponseResult::Success(success) => success.total_results(),
ResponseResult::Error(_) => None,
}
}
#[must_use]
pub fn error(&self) -> Option<&str> {
match self {
ResponseResult::Success(_) => None,
ResponseResult::Error(error) => Some(&error.error),
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FigiResult {
pub figi: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub security_type: Option<SecurityType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub market_sector: Option<MarketSecDesc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ticker: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exch_code: Option<ExchCode>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "shareClassFIGI")]
pub share_class_figi: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "compositeFIGI")]
pub composite_figi: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub security_type2: Option<SecurityType2>,
#[serde(skip_serializing_if = "Option::is_none")]
pub security_description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<String>,
}
impl FigiResult {
#[must_use]
pub fn has_composite_figi(&self) -> bool {
self.composite_figi.is_some()
}
#[must_use]
pub fn has_share_class_figi(&self) -> bool {
self.share_class_figi.is_some()
}
#[must_use]
pub fn display_name(&self) -> &str {
self.name
.as_deref()
.unwrap_or_else(|| self.ticker.as_deref().unwrap_or(&self.figi))
}
}