Createde Cursive client for testing protocol stuff
This commit is contained in:
parent
fc402438f8
commit
f33bfd1a38
19
Cargo.toml
19
Cargo.toml
|
|
@ -2,10 +2,25 @@
|
|||
members = [
|
||||
'foundation',
|
||||
'server',
|
||||
'protocol'
|
||||
'protocol',
|
||||
'client',
|
||||
]
|
||||
|
||||
[workspace.dependencies]
|
||||
# common data types
|
||||
uuid = {version = "1.1.2", features = ["serde", "v4"]}
|
||||
|
||||
# maths
|
||||
rand = "0.8.5"
|
||||
|
||||
# serialisation
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
# async tokio
|
||||
tokio = { version = "1.9.0", features = ["full"] }
|
||||
|
||||
# protobuf
|
||||
bytes = "1.6.0"
|
||||
prost = "0.12"
|
||||
prost-build = { version = "0.12" }
|
||||
prost-build = { version = "0.12" }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
[package]
|
||||
name = "client"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tokio.workspace = true
|
||||
cursive = "0.20.0"
|
||||
rand.workspace = true
|
||||
|
||||
bytes.workspace = true
|
||||
prost.workspace = true
|
||||
|
||||
foundation = { path = '../foundation' }
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
use cursive::{
|
||||
view::Margins,
|
||||
views::{Dialog, LinearLayout, TextView},
|
||||
View,
|
||||
};
|
||||
|
||||
pub fn info_dialogue(name: String, owner: String) -> impl View {
|
||||
Dialog::new()
|
||||
.padding(Margins::lrtb(2, 2, 2, 2))
|
||||
.content(
|
||||
LinearLayout::vertical()
|
||||
.child(TextView::new("Got Info:"))
|
||||
.child(TextView::new(format!("name: {}", name)))
|
||||
.child(TextView::new(format!("owner: {}", owner))),
|
||||
)
|
||||
.button("Close", |s| {
|
||||
s.pop_layer();
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
mod info_dialogue;
|
||||
mod select_operation;
|
||||
mod settings;
|
||||
pub mod state;
|
||||
|
||||
use cursive::{
|
||||
event::Event,
|
||||
menu::Tree,
|
||||
views::{Menubar, Panel, TextView},
|
||||
Cursive,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
select_operation::methods_view,
|
||||
settings::settings_panel,
|
||||
state::State,
|
||||
};
|
||||
|
||||
enum MethodSelection {
|
||||
GetInfo,
|
||||
}
|
||||
|
||||
fn menu_bar(menu_bar: &mut Menubar) {
|
||||
menu_bar
|
||||
.add_subtree(
|
||||
"Chat Kit",
|
||||
Tree::new()
|
||||
.leaf("Settings", open_settings)
|
||||
.delimiter()
|
||||
.leaf("Quit", exit),
|
||||
)
|
||||
.add_subtree(
|
||||
"File",
|
||||
Tree::new().leaf("Main View", |s| s.add_layer(methods_view())),
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut scr = cursive::default();
|
||||
scr.set_fps(30);
|
||||
|
||||
let state = State::new();
|
||||
|
||||
scr.set_user_data(state);
|
||||
|
||||
menu_bar(scr.menubar());
|
||||
scr.add_global_callback(Event::Key(cursive::event::Key::Esc), |s| {
|
||||
s.select_menubar()
|
||||
});
|
||||
|
||||
scr.add_layer(methods_view());
|
||||
|
||||
scr.run()
|
||||
}
|
||||
|
||||
fn exit(s: &mut Cursive) {
|
||||
s.quit();
|
||||
}
|
||||
|
||||
fn open_settings(s: &mut Cursive) {
|
||||
let host = s.user_data::<State>().map(|s| s.get_host());
|
||||
s.add_layer(settings_panel(host));
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
use cursive::{
|
||||
view::Nameable,
|
||||
views::{Button, LinearLayout, PaddedView, Panel, SelectView, TextView},
|
||||
CbSink,
|
||||
Cursive,
|
||||
View,
|
||||
};
|
||||
use foundation::{
|
||||
networking::{read_message, write_message},
|
||||
prelude::{
|
||||
network_client_message,
|
||||
network_server_message,
|
||||
GetInfo,
|
||||
Info,
|
||||
NetworkClientMessage,
|
||||
NetworkServerMessage,
|
||||
},
|
||||
};
|
||||
use tokio::{net::TcpStream, process::Command};
|
||||
|
||||
use crate::{info_dialogue::info_dialogue, state::State, MethodSelection};
|
||||
|
||||
pub fn methods_view() -> impl View {
|
||||
let horizontal = LinearLayout::horizontal();
|
||||
Panel::new(PaddedView::lrtb(
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
LinearLayout::vertical()
|
||||
.child(TextView::new("Select option"))
|
||||
.child(
|
||||
SelectView::new()
|
||||
.item("Get Info", MethodSelection::GetInfo)
|
||||
.on_submit(execute)
|
||||
.with_name("method_selector"),
|
||||
)
|
||||
.child(horizontal.child(Button::new("Cancel", exit))),
|
||||
))
|
||||
.title("Select method")
|
||||
}
|
||||
|
||||
fn exit(s: &mut Cursive) {
|
||||
s.quit();
|
||||
}
|
||||
|
||||
fn execute(s: &mut Cursive, item: &MethodSelection) {
|
||||
let _sink = s.cb_sink().clone();
|
||||
|
||||
match item {
|
||||
MethodSelection::GetInfo => run_get_info(s),
|
||||
}
|
||||
|
||||
let rt = &s.user_data::<State>().unwrap().get_rt();
|
||||
|
||||
rt.spawn(async {});
|
||||
}
|
||||
|
||||
fn run_get_info(s: &mut Cursive) {
|
||||
let host = s.user_data::<State>().unwrap().get_host();
|
||||
let sink = s.cb_sink().clone();
|
||||
let rt = &s.user_data::<State>().unwrap().get_rt();
|
||||
|
||||
// _ = sink.send(Box::new(|s| s.add_layer(Dialog::new())));
|
||||
|
||||
rt.spawn(async move {
|
||||
let stream_res = TcpStream::connect(host).await;
|
||||
match stream_res {
|
||||
Ok(stream) => {
|
||||
get_request(stream, sink).await;
|
||||
}
|
||||
Err(_e) => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async fn get_request(mut stream: TcpStream, sink: CbSink) {
|
||||
let message = read_message::<NetworkServerMessage>(&mut stream).await;
|
||||
|
||||
if let Ok(NetworkServerMessage {
|
||||
message:
|
||||
Some(network_server_message::Message::Request(
|
||||
foundation::prelude::Request { a: true },
|
||||
)),
|
||||
}) = message
|
||||
{
|
||||
perform_get_info(stream, sink.clone()).await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn perform_get_info(mut stream: TcpStream, sink: CbSink) {
|
||||
let message = NetworkClientMessage {
|
||||
message: Some(network_client_message::Message::GetInfo(GetInfo {})),
|
||||
};
|
||||
|
||||
write_message(&mut stream, message).await.unwrap();
|
||||
|
||||
let message = read_message::<NetworkServerMessage>(&mut stream)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
if let NetworkServerMessage {
|
||||
message:
|
||||
Some(network_server_message::Message::GotInfo(Info { owner, server_name })),
|
||||
} = message
|
||||
{
|
||||
sink
|
||||
.send(segue_to_info_dialgue(server_name, owner))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn segue_to_info_dialgue(
|
||||
name: String,
|
||||
owner: String,
|
||||
) -> Box<dyn FnOnce(&mut Cursive) + Send> {
|
||||
Box::new(|s| {
|
||||
s.add_layer(info_dialogue(name, owner));
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
use cursive::{
|
||||
view::{Margins, Nameable, Resizable},
|
||||
views::{Button, EditView, LinearLayout, PaddedView, Panel},
|
||||
Cursive,
|
||||
View,
|
||||
XY,
|
||||
};
|
||||
|
||||
use crate::state::State;
|
||||
|
||||
pub fn settings_panel(host: Option<String>) -> impl View {
|
||||
Panel::new(PaddedView::new(
|
||||
Margins::lrtb(2, 2, 2, 2),
|
||||
LinearLayout::vertical()
|
||||
.child(
|
||||
EditView::new()
|
||||
.content(host.unwrap_or("localhost:6500".into()))
|
||||
.on_edit(set_host)
|
||||
.with_name("host_input"),
|
||||
)
|
||||
.child(Button::new("Close", |s| {
|
||||
s.pop_layer();
|
||||
}))
|
||||
.min_size(XY { x: 30, y: 8 }),
|
||||
))
|
||||
.title("Settings")
|
||||
}
|
||||
|
||||
fn set_host(s: &mut Cursive, host: &str, _: usize) {
|
||||
s.user_data::<State>().unwrap().set_host(host);
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
use tokio::runtime::Runtime;
|
||||
|
||||
pub struct State {
|
||||
runtime: Runtime,
|
||||
host: String,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
runtime: Runtime::new().unwrap(),
|
||||
host: "localhost:6500".into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_host(&self) -> String {
|
||||
self.host.clone()
|
||||
}
|
||||
|
||||
pub fn set_host<T: Into<String>>(&mut self, value: T) {
|
||||
self.host = value.into()
|
||||
}
|
||||
|
||||
pub fn get_rt(&mut self) -> &mut Runtime {
|
||||
&mut self.runtime
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue