abstract_std/objects/entry/
ans_entry_convertor.rs1use crate::{
2 constants::{ASSET_DELIMITER, TYPE_DELIMITER},
3 objects::{
4 ans_host::{AnsHostError, AnsHostResult},
5 AssetEntry, DexAssetPairing, LpToken, PoolMetadata,
6 },
7};
8
9pub struct AnsEntryConvertor<T> {
11 entry: T,
12}
13
14impl<T> AnsEntryConvertor<T> {
15 pub fn new(entry: T) -> Self {
16 Self { entry }
17 }
18}
19
20impl AnsEntryConvertor<LpToken> {
22 pub fn asset_entry(self) -> AssetEntry {
23 AssetEntry::from(self.entry.to_string())
24 }
25
26 pub fn dex_asset_pairing(self) -> AnsHostResult<DexAssetPairing> {
27 let mut assets = self.entry.assets;
28 assets.sort();
30 assets.reverse();
31
32 Ok(DexAssetPairing::new(
33 assets.pop().unwrap(),
34 assets.pop().unwrap(),
35 self.entry.dex.as_str(),
36 ))
37 }
38}
39
40impl AnsEntryConvertor<PoolMetadata> {
41 pub fn lp_token(self) -> LpToken {
42 LpToken {
43 dex: self.entry.dex,
44 assets: self.entry.assets,
45 }
46 }
47
48 pub fn lp_token_asset(self) -> AssetEntry {
49 AnsEntryConvertor::new(self.lp_token()).asset_entry()
50 }
51}
52
53impl AnsEntryConvertor<AssetEntry> {
54 pub fn lp_token(self) -> AnsHostResult<LpToken> {
56 let segments = self
57 .entry
58 .as_str()
59 .split(TYPE_DELIMITER)
60 .collect::<Vec<_>>();
61
62 if segments.len() != 2 {
63 return Err(AnsHostError::FormattingError {
64 object: "lp token".to_string(),
65 expected: "type/asset1,asset2".to_string(),
66 actual: self.entry.to_string(),
67 });
68 }
69
70 let dex_name = segments[0].to_string();
72
73 let mut assets: Vec<AssetEntry> = segments[1]
75 .split(ASSET_DELIMITER)
76 .map(AssetEntry::from)
77 .collect();
78
79 assets.sort_unstable();
81
82 if assets.len() < 2 {
83 return Err(AnsHostError::FormattingError {
84 object: "lp token".into(),
85 expected: "at least 2 assets in LP token".into(),
86 actual: self.entry.to_string(),
87 });
88 }
89
90 Ok(LpToken {
91 dex: dex_name,
92 assets,
93 })
94 }
95}