ledger_models/fintekkers/wrappers/models/
security.rs

1use crate::fintekkers::models::security::{SecurityProto, SecurityTypeProto};
2use crate::fintekkers::wrappers::models::utils::datetime::LocalTimestampWrapper;
3use crate::fintekkers::wrappers::models::utils::errors::Error;
4use crate::fintekkers::wrappers::models::utils::uuid_wrapper::UUIDWrapper;
5
6//Imports below are for RawDataModelObject related macro. IDE might not complain if you remove
7//them but will fail at compile time
8use crate::fintekkers::wrappers::models::raw_datamodel_object::RawDataModelObject;
9use crate::raw_data_model_object_trait;
10use prost::Message;
11
12pub struct SecurityWrapper {
13    pub proto: SecurityProto,
14}
15
16impl SecurityWrapper {
17    pub fn new(proto: SecurityProto) -> Self {
18        SecurityWrapper { proto }
19    }
20
21    pub fn uuid_wrapper(&self) -> UUIDWrapper {
22        UUIDWrapper::new(self.proto.uuid.as_ref().unwrap().clone())
23    }
24}
25
26raw_data_model_object_trait!(SecurityWrapper);
27
28impl PartialEq for SecurityWrapper {
29    fn eq(&self, other: &Self) -> bool {
30        self.proto.uuid.as_ref() == other.proto.uuid.as_ref()
31    }
32}
33impl Eq for SecurityWrapper {}
34
35pub struct SecurityProtoBuilder {
36    as_of: LocalTimestampWrapper,
37    valid_from: LocalTimestampWrapper,
38    valid_to: Option<LocalTimestampWrapper>,
39
40    object_class: String,
41    version: String,
42    is_link: bool,
43
44    uuid: UUIDWrapper,
45    security_type: SecurityTypeProto,
46    asset_class: String,
47    issuer_name: String,
48    settlement_currency: String,
49}
50
51impl SecurityProtoBuilder {
52    pub fn new() -> Self {
53        Self {
54            as_of: LocalTimestampWrapper::now(),
55            valid_from: LocalTimestampWrapper::now(),
56            valid_to: None,
57            //This is currently hardcoded, this will change in future versions
58            object_class: "Security".to_string(),
59            //The version is hardcoded, this will change in future versions
60            version: "0.0.1".to_string(),
61            is_link: false,
62            uuid: UUIDWrapper::new_random(),
63            security_type: SecurityTypeProto::UnknownSecurityType,
64            asset_class: "Unknown".to_string(),
65            issuer_name: "Unknown Issue".to_string(),
66            settlement_currency: "Unknown settlement currency".to_string(),
67        }
68    }
69
70    pub fn as_of(mut self, as_of: LocalTimestampWrapper) -> Self {
71        self.as_of = as_of.into();
72        self
73    }
74
75    pub fn valid_from(mut self, valid_from: LocalTimestampWrapper) -> Self {
76        self.valid_from = valid_from.into();
77        self
78    }
79
80    pub fn valid_to(mut self, valid_to: LocalTimestampWrapper) -> Self {
81        self.valid_to = valid_to.into();
82        self
83    }
84
85    pub fn object_class(mut self, object_class: String) -> Self {
86        self.object_class = object_class;
87        self
88    }
89
90    pub fn version(mut self, version: String) -> Self {
91        self.version = version;
92        self
93    }
94
95    pub fn is_link(mut self, is_link: bool) -> Self {
96        self.is_link = is_link;
97        self
98    }
99
100    pub fn uuid(mut self, uuid: UUIDWrapper) -> Self {
101        self.uuid = uuid;
102        self
103    }
104
105    pub fn security_type(mut self, security_type: SecurityTypeProto) -> Self {
106        self.security_type = security_type;
107        self
108    }
109
110    pub fn asset_class(mut self, asset_class: String) -> Self {
111        self.asset_class = asset_class;
112        self
113    }
114
115    pub fn issuer_name(mut self, issuer_name: String) -> Self {
116        self.issuer_name = issuer_name;
117        self
118    }
119
120    pub fn settlement_currency(mut self, settlement_currency: String) -> Self {
121        self.settlement_currency = settlement_currency;
122        self
123    }
124
125    pub fn build(self) -> Result<SecurityProto, Error> {
126        let valid_to = match self.valid_to {
127            Some(..) => Some(self.valid_to.unwrap().proto),
128            None => None,
129        };
130
131        Ok(SecurityProto {
132            as_of: Some(self.as_of.into()),
133            valid_from: Some(self.valid_from.into()),
134            valid_to,
135
136            object_class: self.object_class,
137            version: self.version,
138            is_link: self.is_link,
139
140            uuid: Some(self.uuid.into()),
141            security_type: self.security_type.into(),
142            asset_class: self.asset_class,
143            issuer_name: self.issuer_name,
144            settlement_currency: None,
145            cash_id: "".to_string(),
146
147            quantity_type: 0,
148            identifier: None,
149            description: "".to_string(),
150
151            //Bond specific
152            face_value: None,
153            coupon_rate: None,
154            coupon_frequency: 0,
155            coupon_type: 0,
156            maturity_date: None,
157            dated_date: None,
158            issue_date: None,
159            issuance_info: vec![],
160        })
161    }
162}
163
164#[cfg(test)]
165mod test {
166    use super::*;
167
168    #[test]
169    fn test_proto_to_date() {
170        let result = SecurityProtoBuilder::new()
171            .settlement_currency("CAD".to_string())
172            .asset_class("Asset Class".to_string())
173            .build()
174            .unwrap(); //.expect("Could not build security");
175
176        assert!(result.asset_class.contains("Asset"));
177        // assert_eq!(result.settlement_currency.unwrap(), "CAD".to_string());
178    }
179}