From 76f1c87663b144812adf33330a6a03ed6bbe0509 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sun, 12 May 2024 22:24:37 +0200 Subject: [PATCH] feat: abstract commander Signed-off-by: kjuulh --- crates/hyperlog-protos/proto/hyperlog.proto | 25 +++-- crates/hyperlog-server/src/external_grpc.rs | 10 ++ crates/hyperlog-tui/src/commander.rs | 100 +++--------------- crates/hyperlog-tui/src/commander/local.rs | 85 +++++++++++++++ crates/hyperlog-tui/src/commander/remote.rs | 98 +++++++++++++++++ .../hyperlog-tui/src/commands/create_item.rs | 10 +- crates/hyperlog-tui/src/core_state.rs | 23 ++-- crates/hyperlog-tui/src/querier.rs | 5 +- crates/hyperlog-tui/src/querier/remote.rs | 6 +- 9 files changed, 244 insertions(+), 118 deletions(-) create mode 100644 crates/hyperlog-tui/src/commander/local.rs create mode 100644 crates/hyperlog-tui/src/commander/remote.rs diff --git a/crates/hyperlog-protos/proto/hyperlog.proto b/crates/hyperlog-protos/proto/hyperlog.proto index 592d4fb..ffcd013 100644 --- a/crates/hyperlog-protos/proto/hyperlog.proto +++ b/crates/hyperlog-protos/proto/hyperlog.proto @@ -2,16 +2,6 @@ syntax = "proto3"; package hyperlog; -service Graph { - rpc GetAvailableRoots(GetAvailableRootsRequest) returns (GetAvailableRootsResponse); - rpc Get(GetRequest) returns (GetReply); -} - -message GetAvailableRootsRequest {} -message GetAvailableRootsResponse { - repeated string roots = 1; -} - message UserGraphItem { map items = 1; @@ -41,6 +31,17 @@ message GraphItem { } } +service Graph { + rpc GetAvailableRoots(GetAvailableRootsRequest) returns (GetAvailableRootsResponse); + rpc Get(GetRequest) returns (GetReply); + rpc CreateSection(CreateSectionRequest) returns (CreateSectionResponse); +} + +message GetAvailableRootsRequest {} +message GetAvailableRootsResponse { + repeated string roots = 1; +} + message GetRequest { string root = 1; repeated string paths = 2; @@ -50,3 +51,7 @@ message GetReply { GraphItem item = 1; } + +message CreateSectionRequest {} +message CreateSectionResponse {} + diff --git a/crates/hyperlog-server/src/external_grpc.rs b/crates/hyperlog-server/src/external_grpc.rs index eadf9d7..3c68f6c 100644 --- a/crates/hyperlog-server/src/external_grpc.rs +++ b/crates/hyperlog-server/src/external_grpc.rs @@ -64,6 +64,16 @@ impl Graph for Server { roots: vec!["kjuulh".into()], })) } + + async fn create_section( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> { + let req = request.into_inner(); + tracing::trace!("create section: req({:?})", req); + + Ok(Response::new(CreateSectionResponse {})) + } } pub trait ServerExt { diff --git a/crates/hyperlog-tui/src/commander.rs b/crates/hyperlog-tui/src/commander.rs index 7658320..1a9590b 100644 --- a/crates/hyperlog-tui/src/commander.rs +++ b/crates/hyperlog-tui/src/commander.rs @@ -1,8 +1,12 @@ use hyperlog_core::log::ItemState; use serde::Serialize; +use tonic::transport::Channel; use crate::{events::Events, shared_engine::SharedEngine, storage::Storage}; +mod local; +mod remote; + #[derive(Serialize, PartialEq, Eq, Debug, Clone)] pub enum Command { CreateRoot { @@ -40,6 +44,7 @@ pub enum Command { #[derive(Clone)] enum CommanderVariant { Local(local::Commander), + Remote(remote::Commander), } #[derive(Clone)] @@ -54,97 +59,16 @@ impl Commander { }) } + pub fn remote(channel: Channel) -> anyhow::Result { + Ok(Self { + variant: CommanderVariant::Remote(remote::Commander::new(channel)?), + }) + } + pub async fn execute(&self, cmd: Command) -> anyhow::Result<()> { match &self.variant { CommanderVariant::Local(commander) => commander.execute(cmd), - } - } -} - -mod local { - use std::collections::BTreeMap; - - use hyperlog_core::log::GraphItem; - - use crate::{events::Events, shared_engine::SharedEngine, storage::Storage}; - - use super::Command; - - #[derive(Clone)] - pub struct Commander { - engine: SharedEngine, - storage: Storage, - events: Events, - } - - impl Commander { - pub fn new(engine: SharedEngine, storage: Storage, events: Events) -> anyhow::Result { - Ok(Self { - engine, - storage, - events, - }) - } - - pub fn execute(&self, cmd: Command) -> anyhow::Result<()> { - tracing::debug!("executing event: {}", serde_json::to_string(&cmd)?); - - match cmd.clone() { - Command::CreateRoot { root } => { - self.engine.create_root(&root)?; - } - Command::CreateSection { root, path } => { - self.engine.create( - &root, - &path.iter().map(|p| p.as_str()).collect::>(), - GraphItem::Section(BTreeMap::default()), - )?; - } - Command::CreateItem { - root, - path, - title, - description, - state, - } => self.engine.create( - &root, - &path.iter().map(|p| p.as_str()).collect::>(), - GraphItem::Item { - title, - description, - state, - }, - )?, - Command::Move { root, src, dest } => self.engine.section_move( - &root, - &src.iter().map(|p| p.as_str()).collect::>(), - &dest.iter().map(|p| p.as_str()).collect::>(), - )?, - Command::ToggleItem { root, path } => self - .engine - .toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::>())?, - Command::UpdateItem { - root, - path, - title, - description, - state, - } => self.engine.update_item( - &root, - &path.iter().map(|p| p.as_str()).collect::>(), - GraphItem::Item { - title, - description, - state, - }, - )?, - } - - self.storage.store(&self.engine)?; - - self.events.enque_command(cmd)?; - - Ok(()) + CommanderVariant::Remote(commander) => commander.execute(cmd).await, } } } diff --git a/crates/hyperlog-tui/src/commander/local.rs b/crates/hyperlog-tui/src/commander/local.rs new file mode 100644 index 0000000..941f1ed --- /dev/null +++ b/crates/hyperlog-tui/src/commander/local.rs @@ -0,0 +1,85 @@ +use std::collections::BTreeMap; + +use hyperlog_core::log::GraphItem; + +use crate::{events::Events, shared_engine::SharedEngine, storage::Storage}; + +use super::Command; + +#[derive(Clone)] +pub struct Commander { + engine: SharedEngine, + storage: Storage, + events: Events, +} + +impl Commander { + pub fn new(engine: SharedEngine, storage: Storage, events: Events) -> anyhow::Result { + Ok(Self { + engine, + storage, + events, + }) + } + + pub fn execute(&self, cmd: Command) -> anyhow::Result<()> { + tracing::debug!("executing event: {}", serde_json::to_string(&cmd)?); + + match cmd.clone() { + Command::CreateRoot { root } => { + self.engine.create_root(&root)?; + } + Command::CreateSection { root, path } => { + self.engine.create( + &root, + &path.iter().map(|p| p.as_str()).collect::>(), + GraphItem::Section(BTreeMap::default()), + )?; + } + Command::CreateItem { + root, + path, + title, + description, + state, + } => self.engine.create( + &root, + &path.iter().map(|p| p.as_str()).collect::>(), + GraphItem::Item { + title, + description, + state, + }, + )?, + Command::Move { root, src, dest } => self.engine.section_move( + &root, + &src.iter().map(|p| p.as_str()).collect::>(), + &dest.iter().map(|p| p.as_str()).collect::>(), + )?, + Command::ToggleItem { root, path } => self + .engine + .toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::>())?, + Command::UpdateItem { + root, + path, + title, + description, + state, + } => self.engine.update_item( + &root, + &path.iter().map(|p| p.as_str()).collect::>(), + GraphItem::Item { + title, + description, + state, + }, + )?, + } + + self.storage.store(&self.engine)?; + + self.events.enque_command(cmd)?; + + Ok(()) + } +} diff --git a/crates/hyperlog-tui/src/commander/remote.rs b/crates/hyperlog-tui/src/commander/remote.rs new file mode 100644 index 0000000..c098ec7 --- /dev/null +++ b/crates/hyperlog-tui/src/commander/remote.rs @@ -0,0 +1,98 @@ +use hyperlog_protos::hyperlog::{graph_client::GraphClient, *}; +use tonic::transport::Channel; + +use super::Command; + +#[allow(dead_code, unused_variables)] +#[derive(Clone)] +pub struct Commander { + channel: Channel, +} + +#[allow(dead_code, unused_variables)] +impl Commander { + pub fn new(channel: Channel) -> anyhow::Result { + Ok(Self { channel }) + } + + pub async fn execute(&self, cmd: Command) -> anyhow::Result<()> { + tracing::debug!("executing event: {}", serde_json::to_string(&cmd)?); + + match cmd.clone() { + Command::CreateRoot { root } => { + todo!() + //self.engine.create_root(&root)?; + } + Command::CreateSection { root, path } => { + let channel = self.channel.clone(); + + let mut client = GraphClient::new(channel); + + let request = tonic::Request::new(CreateSectionRequest {}); + let response = client.create_section(request).await?; + let res = response.into_inner(); + + // self.engine.create( + // &root, + // &path.iter().map(|p| p.as_str()).collect::>(), + // GraphItem::Section(BTreeMap::default()), + // )?; + } + Command::CreateItem { + root, + path, + title, + description, + state, + } => { + todo!() + // self.engine.create( + // &root, + // &path.iter().map(|p| p.as_str()).collect::>(), + // GraphItem::Item { + // title, + // description, + // state, + // }, + // )? + } + Command::Move { root, src, dest } => { + todo!() + // self.engine.section_move( + // &root, + // &src.iter().map(|p| p.as_str()).collect::>(), + // &dest.iter().map(|p| p.as_str()).collect::>(), + // )? + } + Command::ToggleItem { root, path } => { + todo!() + // self + // .engine + // .toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::>())? + } + Command::UpdateItem { + root, + path, + title, + description, + state, + } => { + todo!() + // self.engine.update_item( + // &root, + // &path.iter().map(|p| p.as_str()).collect::>(), + // GraphItem::Item { + // title, + // description, + // state, + // }, + // )? + } + } + + // self.storage.store(&self.engine)?; + // self.events.enque_command(cmd)?; + + Ok(()) + } +} diff --git a/crates/hyperlog-tui/src/commands/create_item.rs b/crates/hyperlog-tui/src/commands/create_item.rs index 5028b15..eaa73f9 100644 --- a/crates/hyperlog-tui/src/commands/create_item.rs +++ b/crates/hyperlog-tui/src/commands/create_item.rs @@ -3,7 +3,7 @@ use itertools::Itertools; use crate::{ commander::{self, Commander}, - models::IOEvent, + models::{IOEvent, Msg}, state::SharedState, }; @@ -32,7 +32,7 @@ impl CreateItemCommand { super::Command::new(|dispatch| { tokio::spawn(async move { - dispatch.send(crate::models::Msg::ItemCreated(IOEvent::Initialized)); + dispatch.send(Msg::ItemCreated(IOEvent::Initialized)); match self .commander @@ -50,12 +50,10 @@ impl CreateItemCommand { { tokio::time::sleep(std::time::Duration::from_secs(1)).await; } - dispatch.send(crate::models::Msg::ItemCreated(IOEvent::Success(()))); + dispatch.send(Msg::ItemCreated(IOEvent::Success(()))); } Err(e) => { - dispatch.send(crate::models::Msg::ItemCreated(IOEvent::Failure( - e.to_string(), - ))); + dispatch.send(Msg::ItemCreated(IOEvent::Failure(e.to_string()))); } } }); diff --git a/crates/hyperlog-tui/src/core_state.rs b/crates/hyperlog-tui/src/core_state.rs index 2f7d275..e6578b8 100644 --- a/crates/hyperlog-tui/src/core_state.rs +++ b/crates/hyperlog-tui/src/core_state.rs @@ -1,3 +1,5 @@ +use tonic::transport::Channel; + use crate::{ commander::Commander, events::Events, querier::Querier, shared_engine::SharedEngine, storage::Storage, @@ -25,14 +27,21 @@ impl State { let events = Events::default(); let engine = SharedEngine::from(engine); - let querier = match backend { - Backend::Local => Querier::local(&engine), - Backend::Remote => Querier::remote().await?, - }; + let (querier, commander) = match backend { + Backend::Local => ( + Querier::local(&engine), + Commander::local(engine.clone(), storage.clone(), events.clone())?, + ), + Backend::Remote => { + let channel = Channel::from_static("http://localhost:4000") + .connect() + .await?; - let commander = match backend { - Backend::Local => Commander::local(engine.clone(), storage.clone(), events.clone())?, - Backend::Remote => todo!(), + ( + Querier::remote(channel.clone()).await?, + Commander::remote(channel)?, + ) + } }; Ok(Self { diff --git a/crates/hyperlog-tui/src/querier.rs b/crates/hyperlog-tui/src/querier.rs index c3ee698..46db6e4 100644 --- a/crates/hyperlog-tui/src/querier.rs +++ b/crates/hyperlog-tui/src/querier.rs @@ -1,4 +1,5 @@ use hyperlog_core::log::GraphItem; +use tonic::transport::Channel; use crate::shared_engine::SharedEngine; @@ -23,9 +24,9 @@ impl Querier { } } - pub async fn remote() -> anyhow::Result { + pub async fn remote(channel: Channel) -> anyhow::Result { Ok(Self { - variant: QuerierVariant::Remote(remote::Querier::new().await?), + variant: QuerierVariant::Remote(remote::Querier::new(channel).await?), }) } diff --git a/crates/hyperlog-tui/src/querier/remote.rs b/crates/hyperlog-tui/src/querier/remote.rs index d6e6368..39c19ee 100644 --- a/crates/hyperlog-tui/src/querier/remote.rs +++ b/crates/hyperlog-tui/src/querier/remote.rs @@ -15,11 +15,7 @@ pub struct Querier { #[allow(dead_code, unused_variables)] impl Querier { - pub async fn new() -> anyhow::Result { - let channel = Channel::from_static("http://localhost:4000") - .connect() - .await?; - + pub async fn new(channel: Channel) -> anyhow::Result { Ok(Self { channel }) }