1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::constants::ASSET_DELIMITER;
use crate::objects::AssetEntry;
use cosmwasm_std::StdError;
#[derive(
Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord, Default,
)]
pub struct LpToken {
pub dex_name: String,
pub assets: Vec<String>,
}
const DEX_TO_ASSETS_DELIMITER: &str = "/";
impl TryFrom<AssetEntry> for LpToken {
type Error = StdError;
fn try_from(asset: AssetEntry) -> Result<Self, Self::Error> {
let segments = asset
.as_str()
.split(DEX_TO_ASSETS_DELIMITER)
.collect::<Vec<_>>();
if segments.len() != 2 {
return Err(StdError::generic_err(format!(
"Invalid asset entry: {}",
asset
)));
}
let dex_name = segments[0].to_string();
let assets: Vec<String> = segments[1]
.split(ASSET_DELIMITER)
.map(|s| s.to_string())
.collect();
if assets.len() < 2 {
return Err(StdError::generic_err(format!(
"Must be at least 2 assets in an LP token: {}",
asset
)));
}
Ok(Self { dex_name, assets })
}
}
#[cfg(test)]
mod test {
use super::*;
use speculoos::prelude::*;
#[test]
fn test_from_asset_entry() {
let lp_token = LpToken::try_from(AssetEntry::new("junoswap/crab,junox")).unwrap();
assert_that!(lp_token.dex_name).is_equal_to("junoswap".to_string());
assert_that!(lp_token.assets).is_equal_to(vec!["crab".to_string(), "junox".to_string()]);
}
#[test]
fn test_from_invalid_asset_entry() {
let lp_token = LpToken::try_from(AssetEntry::new("junoswap/"));
assert_that!(&lp_token).is_err();
}
#[test]
fn test_fewer_than_two_assets() {
let lp_token = LpToken::try_from(AssetEntry::new("junoswap/crab"));
assert_that!(&lp_token).is_err();
}
}