Coverage Report

Created: 2022-11-10 19:56

/home/runner/work/creditcoin/creditcoin/pallets/creditcoin/src/types/loan_terms.rs
Line
Count
Source (jump to first uncovered line)
1
use core::ops::Deref;
2
3
use crate::CurrencyId;
4
5
use super::ExternalAmount;
6
use codec::{Decode, Encode, MaxEncodedLen};
7
use frame_support::RuntimeDebug;
8
use scale_info::TypeInfo;
9
use sp_std::convert::TryFrom;
10
11
pub type RatePerPeriod = u64;
12
pub type Decimals = u64;
13
2.24k
#[derive(
Clone1.45k
, Copy,
Encode1.30k
, Decode, Eq,
P627
artialE
q627
,
RuntimeDebug14
,
TypeInfo2
,
MaxEncodedLen14
)]
14
1
pub struct Duration {
15
  secs: u64,
16
  nanos: u32,
17
}
18
19
const MILLIS_PER_SEC: u64 = 1_000;
20
const NANOS_PER_MILLI: u32 = 1_000_000;
21
22
impl Duration {
23
1
  pub const fn new(secs: u64, nanos: u32) -> Self {
24
1
    Self { secs, nanos }
25
1
  }
26
456
  pub const fn from_millis(millis: u64) -> Self {
27
456
    Self {
28
456
      secs: millis / MILLIS_PER_SEC,
29
456
      nanos: ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI,
30
456
    }
31
456
  }
32
33
309
  pub const fn is_zero(&self) -> bool {
34
309
    self.secs == 0 && 
self.nanos == 01
35
309
  }
36
}
37
38
1.11k
#[derive(
Clone728
, Copy,
E646
ncod
e646
, Decode, Eq,
PartialEq315
,
R8
untimeDebu
g8
,
TypeInfo2
,
MaxEncodedLen8
)]
39
1
pub enum InterestType {
40
  Simple,
41
  Compound,
42
}
43
44
1.11k
#[derive(
Clone726
,
Encode645
, Decode, Eq,
P309
artialE
q309
,
RuntimeDebug7
,
TypeInfo4
,
MaxEncodedLen7
)]
45
1
pub struct InterestRate {
46
  pub rate_per_period: RatePerPeriod,
47
  pub decimals: Decimals,
48
  pub period: Duration,
49
  pub interest_type: InterestType,
50
}
51
52
1.10k
#[derive(
Clone724
,
Encode633
, Decode, Eq,
P48
artialE
q48
,
RuntimeDebug6
,
TypeInfo4
,
MaxEncodedLen6
)]
53
1
pub struct LoanTerms<Hash> {
54
  pub amount: ExternalAmount,
55
  pub interest_rate: InterestRate,
56
  pub term_length: Duration,
57
  pub currency: CurrencyId<Hash>,
58
}
59
60
403
#[derive(
Clone148
, Encode, Decode, Eq,
PartialEq16
,
RuntimeDebug2
,
TypeInfo1
,
MaxEncodedLen2
)]
61
192
pub struct AskTerms<Hash>(LoanTerms<Hash>);
62
63
impl<Hash> Deref for AskTerms<Hash> {
64
  type Target = LoanTerms<Hash>;
65
66
756
  fn deref(&self) -> &Self::Target {
67
756
    &self.0
68
756
  }
69
}
70
71
1
#[derive(Clone, Copy, RuntimeDebug)]
72
pub struct InvalidTermLengthError;
73
74
impl<T: crate::Config> From<InvalidTermLengthError> for crate::Error<T> {
75
1
  fn from(_: InvalidTermLengthError) -> Self {
76
1
    Self::InvalidTermLength
77
1
  }
78
}
79
80
impl<Hash> TryFrom<LoanTerms<Hash>> for AskTerms<Hash> {
81
  type Error = InvalidTermLengthError;
82
154
  fn try_from(terms: LoanTerms<Hash>) -> Result<Self, Self::Error> {
83
154
    if terms.term_length.is_zero() {
84
0
      return Err(InvalidTermLengthError);
85
154
    }
86
154
87
154
    Ok(Self(terms))
88
154
  }
89
}
90
91
impl<Hash> AskTerms<Hash> {
92
252
  pub fn match_with(&self, bid_terms: &BidTerms<Hash>) -> bool {
93
252
    self.amount == bid_terms.amount
94
252
      && self.interest_rate == bid_terms.interest_rate
95
252
      && self.term_length == bid_terms.term_length
96
252
  }
97
98
120
  pub fn agreed_terms(&self, bid_terms: BidTerms<Hash>) -> Option<LoanTerms<Hash>> {
99
120
    self.match_with(&bid_terms).then_some(bid_terms.0)
100
120
  }
101
}
102
103
403
#[derive(
Clone149
, Encode, Decode, Eq,
PartialEq16
,
RuntimeDebug2
,
TypeInfo1
,
MaxEncodedLen2
)]
104
192
pub struct BidTerms<Hash>(LoanTerms<Hash>);
105
106
impl<Hash> Deref for BidTerms<Hash> {
107
  type Target = LoanTerms<Hash>;
108
109
756
  fn deref(&self) -> &Self::Target {
110
756
    &self.0
111
756
  }
112
}
113
114
impl<Hash> TryFrom<LoanTerms<Hash>> for BidTerms<Hash> {
115
  type Error = InvalidTermLengthError;
116
155
  fn try_from(terms: LoanTerms<Hash>) -> Result<Self, Self::Error> {
117
155
    if terms.term_length.is_zero() {
118
1
      return Err(InvalidTermLengthError);
119
154
    }
120
154
121
154
    Ok(Self(terms))
122
155
  }
123
}
124
125
impl<Hash> BidTerms<Hash> {
126
1
  pub fn match_with(&self, ask_terms: &AskTerms<Hash>) -> bool {
127
1
    ask_terms.match_with(self)
128
1
  }
129
130
1
  pub fn agreed_terms(self, ask_terms: &AskTerms<Hash>) -> Option<LoanTerms<Hash>> {
131
1
    ask_terms.agreed_terms(self)
132
1
  }
133
}
134
135
#[cfg(test)]
136
impl Default for LoanTerms<sp_core::H256> {
137
182
  fn default() -> Self {
138
182
    Self {
139
182
      amount: Default::default(),
140
182
      interest_rate: InterestRate::default(),
141
182
      term_length: Duration::from_millis(100_000),
142
182
      currency: CurrencyId::new::<crate::mock::Test>(&crate::Currency::default()),
143
182
    }
144
182
  }
145
}
146
#[cfg(test)]
147
impl Default for InterestRate {
148
208
  fn default() -> Self {
149
208
    Self {
150
208
      rate_per_period: 0,
151
208
      decimals: 1,
152
208
      period: Duration::from_millis(100_000),
153
208
      interest_type: InterestType::Simple,
154
208
    }
155
208
  }
156
}