feat: abstract commander
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
64d59e069f
commit
76f1c87663
@ -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<string, GraphItem> 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 {}
|
||||
|
||||
|
@ -64,6 +64,16 @@ impl Graph for Server {
|
||||
roots: vec!["kjuulh".into()],
|
||||
}))
|
||||
}
|
||||
|
||||
async fn create_section(
|
||||
&self,
|
||||
request: tonic::Request<CreateSectionRequest>,
|
||||
) -> std::result::Result<tonic::Response<CreateSectionResponse>, tonic::Status> {
|
||||
let req = request.into_inner();
|
||||
tracing::trace!("create section: req({:?})", req);
|
||||
|
||||
Ok(Response::new(CreateSectionResponse {}))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ServerExt {
|
||||
|
@ -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<Self> {
|
||||
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<Self> {
|
||||
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::<Vec<_>>(),
|
||||
GraphItem::Section(BTreeMap::default()),
|
||||
)?;
|
||||
}
|
||||
Command::CreateItem {
|
||||
root,
|
||||
path,
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
} => self.engine.create(
|
||||
&root,
|
||||
&path.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
GraphItem::Item {
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
},
|
||||
)?,
|
||||
Command::Move { root, src, dest } => self.engine.section_move(
|
||||
&root,
|
||||
&src.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
&dest.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
)?,
|
||||
Command::ToggleItem { root, path } => self
|
||||
.engine
|
||||
.toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::<Vec<_>>())?,
|
||||
Command::UpdateItem {
|
||||
root,
|
||||
path,
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
} => self.engine.update_item(
|
||||
&root,
|
||||
&path.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
GraphItem::Item {
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
},
|
||||
)?,
|
||||
}
|
||||
|
||||
self.storage.store(&self.engine)?;
|
||||
|
||||
self.events.enque_command(cmd)?;
|
||||
|
||||
Ok(())
|
||||
CommanderVariant::Remote(commander) => commander.execute(cmd).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
85
crates/hyperlog-tui/src/commander/local.rs
Normal file
85
crates/hyperlog-tui/src/commander/local.rs
Normal file
@ -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<Self> {
|
||||
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::<Vec<_>>(),
|
||||
GraphItem::Section(BTreeMap::default()),
|
||||
)?;
|
||||
}
|
||||
Command::CreateItem {
|
||||
root,
|
||||
path,
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
} => self.engine.create(
|
||||
&root,
|
||||
&path.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
GraphItem::Item {
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
},
|
||||
)?,
|
||||
Command::Move { root, src, dest } => self.engine.section_move(
|
||||
&root,
|
||||
&src.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
&dest.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
)?,
|
||||
Command::ToggleItem { root, path } => self
|
||||
.engine
|
||||
.toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::<Vec<_>>())?,
|
||||
Command::UpdateItem {
|
||||
root,
|
||||
path,
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
} => self.engine.update_item(
|
||||
&root,
|
||||
&path.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
GraphItem::Item {
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
},
|
||||
)?,
|
||||
}
|
||||
|
||||
self.storage.store(&self.engine)?;
|
||||
|
||||
self.events.enque_command(cmd)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
98
crates/hyperlog-tui/src/commander/remote.rs
Normal file
98
crates/hyperlog-tui/src/commander/remote.rs
Normal file
@ -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<Self> {
|
||||
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::<Vec<_>>(),
|
||||
// GraphItem::Section(BTreeMap::default()),
|
||||
// )?;
|
||||
}
|
||||
Command::CreateItem {
|
||||
root,
|
||||
path,
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
} => {
|
||||
todo!()
|
||||
// self.engine.create(
|
||||
// &root,
|
||||
// &path.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
// GraphItem::Item {
|
||||
// title,
|
||||
// description,
|
||||
// state,
|
||||
// },
|
||||
// )?
|
||||
}
|
||||
Command::Move { root, src, dest } => {
|
||||
todo!()
|
||||
// self.engine.section_move(
|
||||
// &root,
|
||||
// &src.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
// &dest.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
// )?
|
||||
}
|
||||
Command::ToggleItem { root, path } => {
|
||||
todo!()
|
||||
// self
|
||||
// .engine
|
||||
// .toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::<Vec<_>>())?
|
||||
}
|
||||
Command::UpdateItem {
|
||||
root,
|
||||
path,
|
||||
title,
|
||||
description,
|
||||
state,
|
||||
} => {
|
||||
todo!()
|
||||
// self.engine.update_item(
|
||||
// &root,
|
||||
// &path.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
|
||||
// GraphItem::Item {
|
||||
// title,
|
||||
// description,
|
||||
// state,
|
||||
// },
|
||||
// )?
|
||||
}
|
||||
}
|
||||
|
||||
// self.storage.store(&self.engine)?;
|
||||
// self.events.enque_command(cmd)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -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())));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -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 {
|
||||
|
@ -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<Self> {
|
||||
pub async fn remote(channel: Channel) -> anyhow::Result<Self> {
|
||||
Ok(Self {
|
||||
variant: QuerierVariant::Remote(remote::Querier::new().await?),
|
||||
variant: QuerierVariant::Remote(remote::Querier::new(channel).await?),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -15,11 +15,7 @@ pub struct Querier {
|
||||
|
||||
#[allow(dead_code, unused_variables)]
|
||||
impl Querier {
|
||||
pub async fn new() -> anyhow::Result<Self> {
|
||||
let channel = Channel::from_static("http://localhost:4000")
|
||||
.connect()
|
||||
.await?;
|
||||
|
||||
pub async fn new(channel: Channel) -> anyhow::Result<Self> {
|
||||
Ok(Self { channel })
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user