Convert project to workspace with Tonic for gRPC.
This commit adds an RPC service to the dicebot, allowing external applications to control it. The project was converted to a cargo workspace to house the protobuf definitions in a common crate (tenebrous-rpc), so that clients and servers can make use of these protobuf definitions.
This commit is contained in:
parent
b4321721c4
commit
2f60bbc643
|
@ -101,6 +101,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.6"
|
||||
|
@ -119,6 +125,27 @@ version = "1.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002"
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625"
|
||||
dependencies = [
|
||||
"async-stream-impl",
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stream-impl"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.50"
|
||||
|
@ -529,6 +556,12 @@ version = "0.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -991,6 +1024,15 @@ version = "2.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.0"
|
||||
|
@ -1263,6 +1305,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multimap"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.7"
|
||||
|
@ -1462,6 +1510,16 @@ version = "2.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.8.0"
|
||||
|
@ -1618,6 +1676,57 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e6984d2f1a23009bd270b8bb56d0926810a3d483f59c987d77969e9d8e840b2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-build"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32d3ebd75ac2679c2af3a92246639f9fcc8a442ee420719cc4fe195b98dd5fa3"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"heck",
|
||||
"itertools 0.9.0",
|
||||
"log",
|
||||
"multimap",
|
||||
"petgraph",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"tempfile",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "169a15f3008ecb5160cba7d37bcd690a7601b6d30cfb87a117d45e59d52af5d4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.9.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b518d7cdd93dab1d1122cf07fa9a60771836c668dde9d9e2a139f957f0d9f1bb"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
|
@ -2557,11 +2666,12 @@ dependencies = [
|
|||
"futures",
|
||||
"html2text",
|
||||
"indoc",
|
||||
"itertools",
|
||||
"itertools 0.10.0",
|
||||
"log",
|
||||
"matrix-sdk",
|
||||
"nom 5.1.2",
|
||||
"phf",
|
||||
"prost",
|
||||
"rand 0.8.3",
|
||||
"refinery",
|
||||
"rust-argon2",
|
||||
|
@ -2569,13 +2679,25 @@ dependencies = [
|
|||
"sqlx",
|
||||
"substring",
|
||||
"tempfile",
|
||||
"tenebrous-rpc",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
"tracing-subscriber",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tenebrous-rpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"prost",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.24"
|
||||
|
@ -2743,6 +2865,73 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ac42cd97ac6bd2339af5bcabf105540e21e45636ec6fa6aae5e85d44db31be0"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"base64",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost",
|
||||
"prost-derive",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tonic-build"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c695de27302f4697191dda1c7178131a8cb805463dda02864acb80fe1322fdcf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"prost-build",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f60422bc7fefa2f3ec70359b8ff1caff59d785877eb70595904605bcc412470f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"indexmap",
|
||||
"pin-project",
|
||||
"rand 0.8.3",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.1"
|
||||
|
@ -2756,6 +2945,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
|
@ -3055,6 +3245,16 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe"
|
||||
dependencies = [
|
||||
"either",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "1.1.2"
|
||||
|
|
51
Cargo.toml
51
Cargo.toml
|
@ -1,47 +1,6 @@
|
|||
[package]
|
||||
name = "tenebrous-dicebot"
|
||||
version = "0.10.0"
|
||||
authors = ["Taylor C. Richberger <taywee@gmx.com>", "projectmoon <projectmoon@agnos.is>"]
|
||||
edition = "2018"
|
||||
license = 'AGPL-3.0-or-later'
|
||||
description = 'An async Matrix dice bot for role-playing games'
|
||||
readme = 'README.md'
|
||||
repository = 'https://git.agnos.is/projectmoon/matrix-dicebot'
|
||||
keywords = ["games", "dice", "matrix", "bot"]
|
||||
categories = ["games"]
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
tracing-subscriber = "0.2"
|
||||
toml = "0.5"
|
||||
nom = "5"
|
||||
rand = "0.8"
|
||||
rust-argon2 = "0.8"
|
||||
thiserror = "1.0"
|
||||
itertools = "0.10"
|
||||
async-trait = "0.1"
|
||||
url = "2.1"
|
||||
dirs = "3.0"
|
||||
indoc = "1.0"
|
||||
combine = "4.5"
|
||||
futures = "0.3"
|
||||
html2text = "0.2"
|
||||
phf = { version = "0.8", features = ["macros"] }
|
||||
matrix-sdk = { git = "https://github.com/matrix-org/matrix-rust-sdk", branch = "master" }
|
||||
refinery = { version = "0.5", features = ["rusqlite"]}
|
||||
barrel = { version = "0.6", features = ["sqlite3"] }
|
||||
tempfile = "3"
|
||||
substring = "1.4"
|
||||
fuse-rust = "0.2"
|
||||
|
||||
[dependencies.sqlx]
|
||||
version = "0.5"
|
||||
features = [ "offline", "sqlite", "runtime-tokio-native-tls" ]
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
features = ['derive']
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "1"
|
||||
features = [ "full" ]
|
||||
members = [
|
||||
"dicebot",
|
||||
"rpc",
|
||||
]
|
|
@ -0,0 +1,53 @@
|
|||
[package]
|
||||
name = "tenebrous-dicebot"
|
||||
version = "0.10.0"
|
||||
authors = ["Taylor C. Richberger <taywee@gmx.com>", "projectmoon <projectmoon@agnos.is>"]
|
||||
edition = "2018"
|
||||
license = 'AGPL-3.0-or-later'
|
||||
description = 'An async Matrix dice bot for role-playing games'
|
||||
readme = 'README.md'
|
||||
repository = 'https://git.agnos.is/projectmoon/matrix-dicebot'
|
||||
keywords = ["games", "dice", "matrix", "bot"]
|
||||
categories = ["games"]
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.4"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
tracing-subscriber = "0.2"
|
||||
toml = "0.5"
|
||||
nom = "5"
|
||||
rand = "0.8"
|
||||
rust-argon2 = "0.8"
|
||||
thiserror = "1.0"
|
||||
itertools = "0.10"
|
||||
async-trait = "0.1"
|
||||
url = "2.1"
|
||||
dirs = "3.0"
|
||||
indoc = "1.0"
|
||||
combine = "4.5"
|
||||
futures = "0.3"
|
||||
html2text = "0.2"
|
||||
phf = { version = "0.8", features = ["macros"] }
|
||||
matrix-sdk = { git = "https://github.com/matrix-org/matrix-rust-sdk", branch = "master" }
|
||||
refinery = { version = "0.5", features = ["rusqlite"]}
|
||||
barrel = { version = "0.6", features = ["sqlite3"] }
|
||||
tempfile = "3"
|
||||
substring = "1.4"
|
||||
fuse-rust = "0.2"
|
||||
tonic = "0.4"
|
||||
prost = "0.7"
|
||||
tenebrous-rpc = { path = "../rpc" }
|
||||
|
||||
[dependencies.sqlx]
|
||||
version = "0.5"
|
||||
features = [ "offline", "sqlite", "runtime-tokio-native-tls" ]
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
features = ['derive']
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "1"
|
||||
features = [ "full" ]
|
|
@ -1,5 +1,6 @@
|
|||
//Needed for nested Result handling from tokio. Probably can go away after 1.47.0.
|
||||
#![type_length_limit = "7605144"]
|
||||
use futures::try_join;
|
||||
use log::error;
|
||||
use std::env;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
@ -7,15 +8,27 @@ use tenebrous_dicebot::bot::DiceBot;
|
|||
use tenebrous_dicebot::config::*;
|
||||
use tenebrous_dicebot::db::sqlite::Database;
|
||||
use tenebrous_dicebot::error::BotError;
|
||||
use tenebrous_dicebot::rpc;
|
||||
use tenebrous_dicebot::state::DiceBotState;
|
||||
use tracing_subscriber::filter::EnvFilter;
|
||||
|
||||
/// Attempt to create config object and ddatabase connection pool from
|
||||
/// the given config path. An error is returned if config creation or
|
||||
/// database pool creation fails for some reason.
|
||||
async fn init(config_path: &str) -> Result<(Arc<Config>, Database), BotError> {
|
||||
let cfg = read_config(config_path)?;
|
||||
let cfg = Arc::new(cfg);
|
||||
let sqlite_path = format!("{}/dicebot.sqlite", cfg.database_path());
|
||||
let db = Database::new(&sqlite_path).await?;
|
||||
Ok((cfg, db))
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
async fn main() -> Result<(), BotError> {
|
||||
let filter = if env::var("RUST_LOG").is_ok() {
|
||||
EnvFilter::from_default_env()
|
||||
} else {
|
||||
EnvFilter::new("tenebrous_dicebot=info,dicebot=info,refinery=info")
|
||||
EnvFilter::new("tonic=info,tenebrous_dicebot=info,dicebot=info,refinery=info")
|
||||
};
|
||||
|
||||
tracing_subscriber::fmt().with_env_filter(filter).init();
|
||||
|
@ -23,7 +36,9 @@ async fn main() {
|
|||
match run().await {
|
||||
Ok(_) => (),
|
||||
Err(e) => error!("Error: {}", e),
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run() -> Result<(), BotError> {
|
||||
|
@ -32,12 +47,22 @@ async fn run() -> Result<(), BotError> {
|
|||
.next()
|
||||
.expect("Need a config as an argument");
|
||||
|
||||
let cfg = Arc::new(read_config(config_path)?);
|
||||
let sqlite_path = format!("{}/dicebot.sqlite", cfg.database_path());
|
||||
let db = Database::new(&sqlite_path).await?;
|
||||
let (cfg, db) = init(&config_path).await?;
|
||||
let grpc = rpc::serve_grpc(&cfg, &db);
|
||||
let bot = run_bot(&cfg, &db);
|
||||
|
||||
match try_join!(bot, grpc) {
|
||||
Ok(_) => (),
|
||||
Err(e) => error!("Error: {}", e),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run_bot(cfg: &Arc<Config>, db: &Database) -> Result<(), BotError> {
|
||||
let state = Arc::new(RwLock::new(DiceBotState::new(&cfg)));
|
||||
|
||||
match DiceBot::new(&cfg, &state, &db) {
|
||||
match DiceBot::new(cfg, &state, db) {
|
||||
Ok(bot) => bot.run().await?,
|
||||
Err(e) => println!("Error connecting: {:?}", e),
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
use tenebrous_rpc::protos::dicebot::dicebot_client::DicebotClient;
|
||||
use tenebrous_rpc::protos::dicebot::UserIdRequest;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut client = DicebotClient::connect("http://0.0.0.0:9090").await?;
|
||||
|
||||
let request = tonic::Request::new(UserIdRequest {
|
||||
user_id: "Tonic".into(),
|
||||
});
|
||||
|
||||
let response = client.rooms_for_user(request).await?.into_inner();
|
||||
|
||||
println!("RESPONSE={:?}", response);
|
||||
println!("User friendly response is: {:?}", response.room_ids);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -4,10 +4,6 @@ use std::fs;
|
|||
use std::path::PathBuf;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Shortcut to defining db migration versions. Will probably
|
||||
/// eventually be moved to a config file.
|
||||
const MIGRATION_VERSION: u32 = 5;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ConfigError {
|
||||
#[error("i/o error: {0}")]
|
||||
|
@ -57,6 +53,10 @@ fn db_path_from_env() -> String {
|
|||
struct BotConfig {
|
||||
/// How far back from current time should we process a message?
|
||||
oldest_message_age: Option<u64>,
|
||||
|
||||
/// What address and port to run the RPC service on. If not
|
||||
/// specified, RPC will not be enabled.
|
||||
rpc_addr: Option<String>,
|
||||
}
|
||||
|
||||
/// The "database" section of the config file.
|
||||
|
@ -84,6 +84,12 @@ impl BotConfig {
|
|||
self.oldest_message_age
|
||||
.unwrap_or(DEFAULT_OLDEST_MESSAGE_AGE)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn rpc_addr(&self) -> Option<String> {
|
||||
self.rpc_addr.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the toml config file for the dicebot. The sections of
|
||||
|
@ -128,15 +134,6 @@ impl Config {
|
|||
.unwrap_or_else(|| db_path_from_env())
|
||||
}
|
||||
|
||||
/// The current migration version we expect of the database. If
|
||||
/// this number is higher than the one in the database, we will
|
||||
/// execute migrations to update the data.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn migration_version(&self) -> u32 {
|
||||
MIGRATION_VERSION
|
||||
}
|
||||
|
||||
/// Figure out the allowed oldest message age, in seconds. This will
|
||||
/// be the defined oldest message age in the bot config, if the bot
|
||||
/// configuration and associated "oldest_message_age" setting are
|
||||
|
@ -150,6 +147,12 @@ impl Config {
|
|||
.map(|bc| bc.oldest_message_age())
|
||||
.unwrap_or(DEFAULT_OLDEST_MESSAGE_AGE)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn rpc_addr(&self) -> Option<String> {
|
||||
self.bot.as_ref().and_then(|bc| bc.rpc_addr())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
|
@ -1,3 +1,5 @@
|
|||
use std::net::AddrParseError;
|
||||
|
||||
use crate::commands::CommandError;
|
||||
use crate::config::ConfigError;
|
||||
use crate::db::errors::DataError;
|
||||
|
@ -93,6 +95,12 @@ pub enum BotError {
|
|||
|
||||
#[error("room name or id does not exist")]
|
||||
RoomDoesNotExist,
|
||||
|
||||
#[error("tonic transport error: {0}")]
|
||||
TonicTransportError(#[from] tonic::transport::Error),
|
||||
|
||||
#[error("address parsing error: {0}")]
|
||||
AddressParseError(#[from] AddrParseError),
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
|
@ -12,4 +12,5 @@ pub mod logic;
|
|||
pub mod matrix;
|
||||
pub mod models;
|
||||
mod parser;
|
||||
pub mod rpc;
|
||||
pub mod state;
|
|
@ -0,0 +1,77 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::error::BotError;
|
||||
use crate::{config::Config, db::sqlite::Database};
|
||||
use log::info;
|
||||
use tenebrous_rpc::protos::dicebot::{
|
||||
dicebot_server::{Dicebot, DicebotServer},
|
||||
GetAllVariablesReply, GetAllVariablesRequest, RoomsListReply, SetVariableReply,
|
||||
SetVariableRequest, UserIdRequest,
|
||||
};
|
||||
use tenebrous_rpc::protos::dicebot::{GetVariableReply, GetVariableRequest};
|
||||
use tonic::{transport::Server, Request, Response, Status};
|
||||
|
||||
pub struct DicebotRpcService {
|
||||
config: Arc<Config>,
|
||||
db: Database,
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl Dicebot for DicebotRpcService {
|
||||
async fn set_variable(
|
||||
&self,
|
||||
request: Request<SetVariableRequest>,
|
||||
) -> Result<Response<SetVariableReply>, Status> {
|
||||
Ok(Response::new(SetVariableReply { success: true }))
|
||||
}
|
||||
|
||||
async fn get_variable(
|
||||
&self,
|
||||
request: Request<GetVariableRequest>,
|
||||
) -> Result<Response<GetVariableReply>, Status> {
|
||||
Ok(Response::new(GetVariableReply { value: 1 }))
|
||||
}
|
||||
|
||||
async fn get_all_variables(
|
||||
&self,
|
||||
request: Request<GetAllVariablesRequest>,
|
||||
) -> Result<Response<GetAllVariablesReply>, Status> {
|
||||
Ok(Response::new(GetAllVariablesReply {
|
||||
variables: std::collections::HashMap::new(),
|
||||
}))
|
||||
}
|
||||
|
||||
async fn rooms_for_user(
|
||||
&self,
|
||||
request: Request<UserIdRequest>,
|
||||
) -> Result<Response<RoomsListReply>, Status> {
|
||||
Ok(Response::new(RoomsListReply {
|
||||
room_ids: Vec::new(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn serve_grpc(config: &Arc<Config>, db: &Database) -> Result<(), BotError> {
|
||||
match config.rpc_addr() {
|
||||
Some(addr) => {
|
||||
let addr = addr.parse()?;
|
||||
let rpc_service = DicebotRpcService {
|
||||
db: db.clone(),
|
||||
config: config.clone(),
|
||||
};
|
||||
|
||||
info!("Serving Dicebot gRPC service on {}", addr);
|
||||
Server::builder()
|
||||
.add_service(DicebotServer::new(rpc_service))
|
||||
.serve(addr)
|
||||
.await
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
_ => noop().await,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn noop() -> Result<(), BotError> {
|
||||
info!("RPC address not specified. Not enabling gRPC.");
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "tenebrous-rpc"
|
||||
version = "0.1.0"
|
||||
authors = ["projectmoon <projectmoon@agnos.is>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.4"
|
||||
|
||||
[dependencies]
|
||||
tonic = "0.4"
|
||||
prost = "0.7"
|
|
@ -0,0 +1,4 @@
|
|||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tonic_build::compile_protos("protos/dicebot.proto")?;
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
syntax = "proto3";
|
||||
package dicebot;
|
||||
|
||||
service Dicebot {
|
||||
rpc GetVariable(GetVariableRequest) returns (GetVariableReply);
|
||||
rpc GetAllVariables(GetAllVariablesRequest) returns (GetAllVariablesReply);
|
||||
rpc SetVariable(SetVariableRequest) returns (SetVariableReply);
|
||||
rpc RoomsForUser(UserIdRequest) returns (RoomsListReply);
|
||||
}
|
||||
|
||||
message GetVariableRequest {
|
||||
string user_id = 1;
|
||||
string room_id = 2;
|
||||
string variable_name = 3;
|
||||
}
|
||||
|
||||
message GetVariableReply {
|
||||
int32 value = 1;
|
||||
}
|
||||
|
||||
message GetAllVariablesRequest {
|
||||
string user_id = 1;
|
||||
string room_id = 2;
|
||||
}
|
||||
|
||||
message GetAllVariablesReply {
|
||||
map<string, int32> variables = 1;
|
||||
}
|
||||
|
||||
message SetVariableRequest {
|
||||
string user_id = 1;
|
||||
string room_id = 2;
|
||||
string variable_name = 3;
|
||||
int32 value = 4;
|
||||
}
|
||||
|
||||
message SetVariableReply {
|
||||
bool success = 1;
|
||||
}
|
||||
|
||||
message UserIdRequest {
|
||||
string user_id = 1;
|
||||
}
|
||||
|
||||
message RoomsListReply {
|
||||
repeated string room_ids = 1;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
pub mod protos {
|
||||
pub mod dicebot {
|
||||
tonic::include_proto!("dicebot");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
Loading…
Reference in New Issue