Terminal client
This commit is contained in:
+33
-20
@@ -1,5 +1,6 @@
|
||||
pub mod command;
|
||||
pub mod formatting;
|
||||
pub mod terminal;
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
@@ -270,26 +271,38 @@ impl App for PulseTradeApp {
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
pulse_ui::run(|ctx| PulseTradeApp {
|
||||
command: ctx.use_state(InputState::new()),
|
||||
watch_list: ctx.use_state(Vec::new()),
|
||||
active_positions: ctx.use_state(Vec::new()),
|
||||
signals: ctx.use_state(Vec::new()),
|
||||
logs: ctx.use_state(Vec::new()),
|
||||
inspect: ctx.use_state(InspectTarget::None),
|
||||
market_overview: ctx.use_state(MarketOverview {
|
||||
trend: pulse_wire::terminal::MarketTrend::Bullish,
|
||||
volatility: pulse_wire::terminal::Volatility::High,
|
||||
pressure: 0.324,
|
||||
alerts: Vec::new(),
|
||||
}),
|
||||
status: ctx.use_state(Status {
|
||||
feed: pulse_wire::terminal::Feed::Connected,
|
||||
exchange: "Binance".to_string(),
|
||||
dex: "DEX SCREENER".to_string(),
|
||||
latency: 18,
|
||||
}),
|
||||
async fn main() -> tokio::io::Result<()> {
|
||||
let mut client = terminal::TerminalClient::new().await?;
|
||||
|
||||
client
|
||||
.send(pulse_wire::terminal::TerminalClientMessage::ExecuteCommand(
|
||||
"Hello".to_string(),
|
||||
))
|
||||
.await?;
|
||||
|
||||
pulse_ui::run(|ctx| {
|
||||
client.use_app(PulseTradeApp {
|
||||
command: ctx.use_state(InputState::new()),
|
||||
watch_list: ctx.use_state(Vec::new()),
|
||||
active_positions: ctx.use_state(Vec::new()),
|
||||
signals: ctx.use_state(Vec::new()),
|
||||
logs: ctx.use_state(Vec::new()),
|
||||
inspect: ctx.use_state(InspectTarget::None),
|
||||
market_overview: ctx.use_state(MarketOverview {
|
||||
trend: pulse_wire::terminal::MarketTrend::Bullish,
|
||||
volatility: pulse_wire::terminal::Volatility::High,
|
||||
pressure: 0.324,
|
||||
alerts: Vec::new(),
|
||||
}),
|
||||
status: ctx.use_state(Status {
|
||||
feed: pulse_wire::terminal::Feed::Connected,
|
||||
exchange: "Binance".to_string(),
|
||||
dex: "DEX SCREENER".to_string(),
|
||||
latency: 18,
|
||||
}),
|
||||
})
|
||||
})
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
use pulse_wire::{PulseWire, server_path, terminal::TerminalServerMessage};
|
||||
use tokio::{
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
net::{
|
||||
UnixStream,
|
||||
unix::{OwnedReadHalf, OwnedWriteHalf},
|
||||
},
|
||||
};
|
||||
|
||||
use crate::PulseTradeApp;
|
||||
|
||||
pub struct TerminalClient {
|
||||
writer: OwnedWriteHalf,
|
||||
reader: Option<OwnedReadHalf>,
|
||||
}
|
||||
|
||||
impl TerminalClient {
|
||||
pub async fn new() -> tokio::io::Result<Self> {
|
||||
let (reader, writer) = UnixStream::connect(server_path()).await?.into_split();
|
||||
|
||||
Ok(Self {
|
||||
reader: Some(reader),
|
||||
writer,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn send(
|
||||
&mut self,
|
||||
message: pulse_wire::terminal::TerminalClientMessage,
|
||||
) -> tokio::io::Result<()> {
|
||||
self.writer.write(&message.to_com()).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn use_app(&mut self, app: PulseTradeApp) -> PulseTradeApp {
|
||||
let mut reader = None;
|
||||
|
||||
std::mem::swap(&mut self.reader, &mut reader);
|
||||
|
||||
let mut reader = reader.expect("Reader failed to swap");
|
||||
|
||||
let watch_list = app.watch_list.clone();
|
||||
let active_positions = app.active_positions.clone();
|
||||
let logs = app.logs.clone();
|
||||
let signals = app.signals.clone();
|
||||
let market_overview = app.market_overview.clone();
|
||||
let status = app.status.clone();
|
||||
let inspect = app.inspect.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
let len = reader
|
||||
.read(&mut buffer)
|
||||
.await
|
||||
.expect("Failed to read socket");
|
||||
|
||||
if len == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.truncate(len);
|
||||
|
||||
match TerminalServerMessage::from_com(&mut buffer) {
|
||||
TerminalServerMessage::WatchListUpdated(v) => {
|
||||
*watch_list.lock().await = v;
|
||||
}
|
||||
|
||||
TerminalServerMessage::PositionsUpdated(v) => {
|
||||
*active_positions.lock().await = v;
|
||||
}
|
||||
|
||||
TerminalServerMessage::OverviewUpdated(v) => {
|
||||
*market_overview.lock().await = v;
|
||||
}
|
||||
|
||||
TerminalServerMessage::SignalsUpdated(v) => {
|
||||
*signals.lock().await = v;
|
||||
}
|
||||
|
||||
TerminalServerMessage::Inspect(v) => {
|
||||
*inspect.lock().await = v;
|
||||
}
|
||||
|
||||
TerminalServerMessage::SetStatus(v) => {
|
||||
*status.lock().await = v;
|
||||
}
|
||||
|
||||
TerminalServerMessage::SetLogs(v) => {
|
||||
*logs.lock().await = v;
|
||||
}
|
||||
|
||||
TerminalServerMessage::AddLog(v) => {
|
||||
logs.lock().await.push(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user