Add built-in back implementations for USDPL services, disable code gen for them by default (only usdpl-back needs to generate them)

This commit is contained in:
NGnius (Graham) 2023-09-04 11:59:35 -04:00
parent 44298f660f
commit 1ad6205067
8 changed files with 88 additions and 12 deletions

6
usdpl-back/build.rs Normal file
View file

@ -0,0 +1,6 @@
fn main() {
usdpl_build::back::build_with_custom_builtins(
[].into_iter(),
[].into_iter(),
)
}

View file

@ -12,6 +12,7 @@ mod api_common;
mod api_decky; mod api_decky;
mod rpc; mod rpc;
mod services_impl;
//mod errors; //mod errors;
mod websockets; mod websockets;
@ -19,6 +20,13 @@ mod websockets;
pub use websockets::WebsocketServer as Server; pub use websockets::WebsocketServer as Server;
//pub use errors::{ServerError, ServerResult}; //pub use errors::{ServerError, ServerResult};
#[allow(missing_docs)]
#[allow(dead_code)]
pub(crate) mod services {
include!(concat!(env!("OUT_DIR"), "/mod.rs"));
}
/// USDPL backend API. /// USDPL backend API.
/// This contains functionality used exclusively by the back-end. /// This contains functionality used exclusively by the back-end.
pub mod api { pub mod api {

View file

@ -12,15 +12,6 @@ pub struct ServiceRegistry<'a> {
} }
impl<'a> ServiceRegistry<'a> { impl<'a> ServiceRegistry<'a> {
/*pub async fn call(&self, package: &str, service: &str, method: &str, data: bytes::Bytes) -> Result<bytes::Bytes, ServiceError> {
let key = Self::descriptor(package, service);
self.call_descriptor(&key, method, data).await
}
fn descriptor(package: &str, service: &str) -> String {
format!("{}.{}", package, service)
}*/
pub async fn call_descriptor<'b: 'a>( pub async fn call_descriptor<'b: 'a>(
&mut self, &mut self,
descriptor: &str, descriptor: &str,
@ -43,7 +34,10 @@ impl<'a> ServiceRegistry<'a> {
self self
} }
pub fn new() -> Self { pub fn with_builtins() -> Self {
Self::default() let mut reg = Self::default();
reg.register(crate::services::usdpl::DevToolsServer::new(crate::services_impl::DevTools{}))
.register(crate::services::usdpl::TranslationsServer::new(crate::services_impl::Translations{}));
reg
} }
} }

View file

@ -0,0 +1,22 @@
use crate::services::usdpl as generated;
/// Built-in dev tools service implementation
pub(crate) struct DevTools {}
#[async_trait::async_trait]
impl<'a> generated::IDevTools<'a> for DevTools {
async fn log(
&mut self,
input: generated::LogMessage,
) -> Result<generated::Empty, Box<dyn std::error::Error + Send>> {
match input.level {
lvl if lvl == generated::LogLevel::Trace as _ => log::trace!("{}", input.msg),
lvl if lvl == generated::LogLevel::Debug as _ => log::debug!("{}", input.msg),
lvl if lvl == generated::LogLevel::Info as _ => log::info!("{}", input.msg),
lvl if lvl == generated::LogLevel::Warn as _ => log::warn!("{}", input.msg),
lvl if lvl == generated::LogLevel::Error as _ => log::error!("{}", input.msg),
lvl => return Err(Box::<dyn std::error::Error + Send + Sync>::from(format!("Unexpected input log level {}", lvl)))
}
Ok(generated::Empty{ ok: true })
}
}

View file

@ -0,0 +1,5 @@
mod dev_tools;
pub(crate) use dev_tools::DevTools;
mod translations;
pub(crate) use translations::Translations;

View file

@ -0,0 +1,31 @@
use crate::services::usdpl as generated;
/// Built-in translation service implementation
pub(crate) struct Translations {}
#[async_trait::async_trait]
impl<'a> generated::ITranslations<'a> for Translations {
async fn get_language(
&mut self,
input: generated::LanguageRequest,
) -> Result<generated::TranslationsReply, Box<dyn std::error::Error + Send>> {
let catalog = load_locale(&input.lang).map_err(|e| Box::new(e) as _)?;
let catalog_map = catalog.nalltext();
let mut map = std::collections::HashMap::with_capacity(catalog_map.len());
for (key, val) in catalog_map.into_iter() {
if val.len() > 1 {
log::warn!("Translations key {} for language {} has plural entries which aren't currently supported", key, input.lang);
}
if let Some(val_0) = val.get(0) {
map.insert(key.to_owned(), val_0.to_owned());
}
}
Ok(generated::TranslationsReply { translations: map })
}
}
fn load_locale(lang: &str) -> Result<gettext_ng::Catalog, gettext_ng::Error> {
let path = crate::api::dirs::plugin().unwrap_or_else(|| "".into()).join("translations").join(format!("{}.mo", lang));
let file = std::fs::File::open(path).map_err(|e| gettext_ng::Error::Io(e))?;
gettext_ng::Catalog::parse(file)
}

View file

@ -21,7 +21,7 @@ impl WebsocketServer {
/// Initialise an instance of the back-end websocket server /// Initialise an instance of the back-end websocket server
pub fn new(port_usdpl: u16) -> Self { pub fn new(port_usdpl: u16) -> Self {
Self { Self {
services: StaticServiceRegistry::new(), services: StaticServiceRegistry::with_builtins(),
port: port_usdpl, port: port_usdpl,
} }
} }

View file

@ -1,6 +1,16 @@
pub fn build( pub fn build(
custom_protos: impl Iterator<Item = String>, custom_protos: impl Iterator<Item = String>,
custom_dirs: impl Iterator<Item = String>, custom_dirs: impl Iterator<Item = String>,
) {
nrpc_build::compile_servers(
custom_protos,
crate::proto_out_paths(custom_dirs),
)
}
pub fn build_with_custom_builtins(
custom_protos: impl Iterator<Item = String>,
custom_dirs: impl Iterator<Item = String>,
) { ) {
crate::dump_protos_out().unwrap(); crate::dump_protos_out().unwrap();
nrpc_build::compile_servers( nrpc_build::compile_servers(