Grpc-manager #22

Merged
michael-bailey merged 28 commits from grpc-manager into master 2024-05-30 19:42:42 +00:00
7 changed files with 293 additions and 2 deletions
Showing only changes of commit f33bfd1a38 - Show all commits

View File

@ -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" }

16
client/Cargo.toml Normal file
View File

@ -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' }

View File

@ -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();
})
}

63
client/src/main.rs Normal file
View File

@ -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));
}

View File

@ -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));
})
}

31
client/src/settings.rs Normal file
View File

@ -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);
}

27
client/src/state.rs Normal file
View File

@ -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
}
}