1use comfy_table::{presets, Table};
2use penumbra_sdk_asset::{asset, Value};
3use penumbra_sdk_dex::lp::position::Position;
4
5pub(crate) fn render_positions(asset_cache: &asset::Cache, positions: &[Position]) -> String {
6 let mut table = Table::new();
7 table.load_preset(presets::NOTHING);
8 table.set_header(vec!["ID", "State", "Fee", "Sell Price", "Reserves"]);
9 table
10 .get_column_mut(2)
11 .expect("column 2 exists")
12 .set_cell_alignment(comfy_table::CellAlignment::Right);
13 table
14 .get_column_mut(3)
15 .expect("column 3 exists")
16 .set_cell_alignment(comfy_table::CellAlignment::Right);
17 table
18 .get_column_mut(4)
19 .expect("column 4 exists")
20 .set_cell_alignment(comfy_table::CellAlignment::Right);
21
22 for position in positions {
23 let trading_pair = position.phi.pair;
24 let denom_1 = asset_cache.get(&trading_pair.asset_1());
25 let denom_2 = asset_cache.get(&trading_pair.asset_2());
26
27 match (denom_1, denom_2) {
28 (Some(_), Some(_)) => {
29 if let Some(sell_order) = position.interpret_as_sell() {
30 table.add_row(vec![
31 position.id().to_string(),
32 position.state.to_string(),
33 format!("{}bps", position.phi.component.fee),
34 format!(
35 "{}",
36 sell_order.price_str(asset_cache).expect("assets are known"),
37 ),
38 sell_order.offered.format(asset_cache),
39 ]);
40 } else if let Some((sell_order_1, sell_order_2)) = position.interpret_as_mixed() {
41 table.add_row(vec![
42 position.id().to_string(),
43 position.state.to_string(),
44 format!("{}bps", position.phi.component.fee),
45 format!(
46 "{}",
47 sell_order_1
48 .price_str(asset_cache)
49 .expect("assets are known"),
50 ),
51 sell_order_1.offered.format(asset_cache),
52 ]);
53 table.add_row(vec![
54 "└──────────────────────────────────────────────────────────────▶"
56 .to_string(),
57 String::new(),
58 format!("{}bps", position.phi.component.fee),
59 format!(
60 "{}",
61 sell_order_2
62 .price_str(asset_cache)
63 .expect("assets are known"),
64 ),
65 sell_order_2.offered.format(asset_cache),
66 ]);
67 } else {
68 table.add_row(vec![
69 position.id().to_string(),
70 position.state.to_string(),
71 "Error interpreting position (this should not happen)".to_string(),
72 ]);
73 }
74 }
75 (_, _) => {
76 table.add_row(vec![
77 position.id().to_string(),
78 position.state.to_string(),
79 format!("{}bps", position.phi.component.fee),
80 format!("Unknown asset"),
81 Value {
82 amount: position.reserves.r1,
83 asset_id: position.phi.pair.asset_1(),
84 }
85 .format(asset_cache),
86 ]);
87 table.add_row(vec![
88 "└──────────────────────────────────────────────────────────────▶".to_string(),
90 String::new(),
91 format!("{}bps", position.phi.component.fee),
92 format!("Unknown asset"),
93 Value {
94 amount: position.reserves.r2,
95 asset_id: position.phi.pair.asset_2(),
96 }
97 .format(asset_cache),
98 ]);
99 }
100 }
101 }
102
103 format!("{table}")
104}