use std::collections::BTreeMap;
use std::io::Cursor;
use std::sync::Arc;
use rmpv::Value;
use rpc_runtime_core::{InstanceId, MethodId};
use rpc_runtime_errors::{RuntimeError, RuntimeErrorCode};
use rpc_runtime_server::{
FactoryFuture, HandlerFuture, RpcCallContext, RpcServerBuilder, RpcServiceFactory,
RpcServiceHandler,
};
use super::activation::*;
use super::services::*;
use super::types::*;
pub type ArchiveServiceZipFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type ArchiveServiceUnzipFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub trait ArchiveServiceService: Send + Sync {
fn zip(&self, ctx: RpcCallContext, request: ZipRequest) -> ArchiveServiceZipFuture<'_>;
fn unzip(&self, ctx: RpcCallContext, request: UnzipRequest) -> ArchiveServiceUnzipFuture<'_>;
}
pub struct ArchiveServiceHandler<T: ?Sized> {
inner: Arc<T>,
}
impl<T: ?Sized> ArchiveServiceHandler<T> {
pub fn new(inner: Arc<T>) -> Self {
Self { inner }
}
}
impl<T: ArchiveServiceService + ?Sized + 'static> RpcServiceHandler for ArchiveServiceHandler<T> {
fn call(
&self,
ctx: RpcCallContext,
method_id: MethodId,
payload: rmpv::Value,
) -> HandlerFuture {
let inner = Arc::clone(&self.inner);
match method_id.get() {
1 => Box::pin(async move {
let request = decode_zip_request(&payload)?;
let response = inner.zip(ctx, request).await?;
Ok(encode_empty(&response))
}),
2 => Box::pin(async move {
let request = decode_unzip_request(&payload)?;
let response = inner.unzip(ctx, request).await?;
Ok(encode_empty(&response))
}),
_ => Box::pin(async move {
Err(RuntimeError::runtime(
RuntimeErrorCode::MethodNotFound,
"unknown generated method id",
))
}),
}
}
}
pub fn register_archive_service_named<T: ArchiveServiceService + 'static>(
builder: &mut RpcServerBuilder,
name: impl Into<String>,
service: Arc<T>,
) -> InstanceId {
builder.register_named_instance(
name,
archive_service_service_guid(),
archive_service_method_ids(),
Arc::new(ArchiveServiceHandler::new(service)),
)
}
pub fn register_archive_service_singleton<T: ArchiveServiceService + 'static>(
builder: &mut RpcServerBuilder,
service: Arc<T>,
) -> InstanceId {
builder.register_singleton(
archive_service_service_guid(),
archive_service_method_ids(),
Arc::new(ArchiveServiceHandler::new(service)),
)
}
pub fn register_archive_service_factory<TFactory: ArchiveServiceFactory + 'static>(
builder: &mut RpcServerBuilder,
factory: Arc<TFactory>,
) {
builder.register_factory(
archive_service_service_guid(),
archive_service_method_ids(),
Arc::new(ArchiveServiceFactoryAdapter { inner: factory }),
);
}
pub type ArchiveServiceFactoryFuture<'a> = std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<Arc<dyn ArchiveServiceService>, RuntimeError>>
+ Send
+ 'a,
>,
>;
pub trait ArchiveServiceFactory: Send + Sync {
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> ArchiveServiceFactoryFuture<'_>;
}
struct ArchiveServiceFactoryAdapter<TFactory> {
inner: Arc<TFactory>,
}
impl<TFactory: ArchiveServiceFactory + 'static> RpcServiceFactory
for ArchiveServiceFactoryAdapter<TFactory>
{
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> FactoryFuture {
let inner = Arc::clone(&self.inner);
Box::pin(async move {
let service = inner.create(ctx, create_payload, options).await?;
let handler: Arc<dyn RpcServiceHandler> = Arc::new(ArchiveServiceHandler::new(service));
Ok(handler)
})
}
}
pub type FileSystemServiceReadFileFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<BinaryPayload, RuntimeError>> + Send + 'a>,
>;
pub type FileSystemServiceWriteFileFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceAppendFileFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceMkdirFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceReadDirFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<Vec<DirEntry>, RuntimeError>> + Send + 'a>,
>;
pub type FileSystemServiceStatFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<FileStat, RuntimeError>> + Send + 'a>,
>;
pub type FileSystemServiceExistsFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<bool, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceRemoveFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceRenameFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceCopyFileFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceOpenFileFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<ResourceHandle, RuntimeError>> + Send + 'a>,
>;
pub type FileSystemServiceFileReadFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<BinaryPayload, RuntimeError>> + Send + 'a>,
>;
pub type FileSystemServiceFileWriteFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceFileFlushFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceFileSeekFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<FileSeekResult, RuntimeError>> + Send + 'a>,
>;
pub type FileSystemServiceFileSetLenFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type FileSystemServiceFileCloseFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub trait FileSystemServiceService: Send + Sync {
fn read_file(
&self,
ctx: RpcCallContext,
request: PathRequest,
) -> FileSystemServiceReadFileFuture<'_>;
fn write_file(
&self,
ctx: RpcCallContext,
request: WriteFileRequest,
) -> FileSystemServiceWriteFileFuture<'_>;
fn append_file(
&self,
ctx: RpcCallContext,
request: WriteFileRequest,
) -> FileSystemServiceAppendFileFuture<'_>;
fn mkdir(&self, ctx: RpcCallContext, request: MkdirRequest)
-> FileSystemServiceMkdirFuture<'_>;
fn read_dir(
&self,
ctx: RpcCallContext,
request: PathRequest,
) -> FileSystemServiceReadDirFuture<'_>;
fn stat(&self, ctx: RpcCallContext, request: PathRequest) -> FileSystemServiceStatFuture<'_>;
fn exists(
&self,
ctx: RpcCallContext,
request: PathRequest,
) -> FileSystemServiceExistsFuture<'_>;
fn remove(
&self,
ctx: RpcCallContext,
request: RemoveRequest,
) -> FileSystemServiceRemoveFuture<'_>;
fn rename(
&self,
ctx: RpcCallContext,
request: RenameRequest,
) -> FileSystemServiceRenameFuture<'_>;
fn copy_file(
&self,
ctx: RpcCallContext,
request: RenameRequest,
) -> FileSystemServiceCopyFileFuture<'_>;
fn open_file(
&self,
ctx: RpcCallContext,
request: OpenFileRequest,
) -> FileSystemServiceOpenFileFuture<'_>;
fn file_read(
&self,
ctx: RpcCallContext,
request: FileReadRequest,
) -> FileSystemServiceFileReadFuture<'_>;
fn file_write(
&self,
ctx: RpcCallContext,
request: FileWriteRequest,
) -> FileSystemServiceFileWriteFuture<'_>;
fn file_flush(
&self,
ctx: RpcCallContext,
request: ResourceHandle,
) -> FileSystemServiceFileFlushFuture<'_>;
fn file_seek(
&self,
ctx: RpcCallContext,
request: FileSeekRequest,
) -> FileSystemServiceFileSeekFuture<'_>;
fn file_set_len(
&self,
ctx: RpcCallContext,
request: FileSetLenRequest,
) -> FileSystemServiceFileSetLenFuture<'_>;
fn file_close(
&self,
ctx: RpcCallContext,
request: ResourceHandle,
) -> FileSystemServiceFileCloseFuture<'_>;
}
pub struct FileSystemServiceHandler<T: ?Sized> {
inner: Arc<T>,
}
impl<T: ?Sized> FileSystemServiceHandler<T> {
pub fn new(inner: Arc<T>) -> Self {
Self { inner }
}
}
impl<T: FileSystemServiceService + ?Sized + 'static> RpcServiceHandler
for FileSystemServiceHandler<T>
{
fn call(
&self,
ctx: RpcCallContext,
method_id: MethodId,
payload: rmpv::Value,
) -> HandlerFuture {
let inner = Arc::clone(&self.inner);
match method_id.get() {
1 => Box::pin(async move {
let request = decode_path_request(&payload)?;
let response = inner.read_file(ctx, request).await?;
Ok(encode_binary_payload(&response))
}),
2 => Box::pin(async move {
let request = decode_write_file_request(&payload)?;
let response = inner.write_file(ctx, request).await?;
Ok(encode_empty(&response))
}),
3 => Box::pin(async move {
let request = decode_write_file_request(&payload)?;
let response = inner.append_file(ctx, request).await?;
Ok(encode_empty(&response))
}),
4 => Box::pin(async move {
let request = decode_mkdir_request(&payload)?;
let response = inner.mkdir(ctx, request).await?;
Ok(encode_empty(&response))
}),
5 => Box::pin(async move {
let request = decode_path_request(&payload)?;
let response = inner.read_dir(ctx, request).await?;
Ok(Value::Array(
response
.iter()
.map(|item| encode_dir_entry(&item))
.collect(),
))
}),
6 => Box::pin(async move {
let request = decode_path_request(&payload)?;
let response = inner.stat(ctx, request).await?;
Ok(encode_file_stat(&response))
}),
7 => Box::pin(async move {
let request = decode_path_request(&payload)?;
let response = inner.exists(ctx, request).await?;
Ok(Value::Boolean(response))
}),
8 => Box::pin(async move {
let request = decode_remove_request(&payload)?;
let response = inner.remove(ctx, request).await?;
Ok(encode_empty(&response))
}),
9 => Box::pin(async move {
let request = decode_rename_request(&payload)?;
let response = inner.rename(ctx, request).await?;
Ok(encode_empty(&response))
}),
10 => Box::pin(async move {
let request = decode_rename_request(&payload)?;
let response = inner.copy_file(ctx, request).await?;
Ok(encode_empty(&response))
}),
11 => Box::pin(async move {
let request = decode_open_file_request(&payload)?;
let response = inner.open_file(ctx, request).await?;
Ok(encode_resource_handle(&response))
}),
12 => Box::pin(async move {
let request = decode_file_read_request(&payload)?;
let response = inner.file_read(ctx, request).await?;
Ok(encode_binary_payload(&response))
}),
13 => Box::pin(async move {
let request = decode_file_write_request(&payload)?;
let response = inner.file_write(ctx, request).await?;
Ok(encode_empty(&response))
}),
14 => Box::pin(async move {
let request = decode_resource_handle(&payload)?;
let response = inner.file_flush(ctx, request).await?;
Ok(encode_empty(&response))
}),
15 => Box::pin(async move {
let request = decode_file_seek_request(&payload)?;
let response = inner.file_seek(ctx, request).await?;
Ok(encode_file_seek_result(&response))
}),
16 => Box::pin(async move {
let request = decode_file_set_len_request(&payload)?;
let response = inner.file_set_len(ctx, request).await?;
Ok(encode_empty(&response))
}),
17 => Box::pin(async move {
let request = decode_resource_handle(&payload)?;
let response = inner.file_close(ctx, request).await?;
Ok(encode_empty(&response))
}),
_ => Box::pin(async move {
Err(RuntimeError::runtime(
RuntimeErrorCode::MethodNotFound,
"unknown generated method id",
))
}),
}
}
}
pub fn register_file_system_service_named<T: FileSystemServiceService + 'static>(
builder: &mut RpcServerBuilder,
name: impl Into<String>,
service: Arc<T>,
) -> InstanceId {
builder.register_named_instance(
name,
file_system_service_service_guid(),
file_system_service_method_ids(),
Arc::new(FileSystemServiceHandler::new(service)),
)
}
pub fn register_file_system_service_singleton<T: FileSystemServiceService + 'static>(
builder: &mut RpcServerBuilder,
service: Arc<T>,
) -> InstanceId {
builder.register_singleton(
file_system_service_service_guid(),
file_system_service_method_ids(),
Arc::new(FileSystemServiceHandler::new(service)),
)
}
pub fn register_file_system_service_factory<TFactory: FileSystemServiceFactory + 'static>(
builder: &mut RpcServerBuilder,
factory: Arc<TFactory>,
) {
builder.register_factory(
file_system_service_service_guid(),
file_system_service_method_ids(),
Arc::new(FileSystemServiceFactoryAdapter { inner: factory }),
);
}
pub type FileSystemServiceFactoryFuture<'a> = std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<Arc<dyn FileSystemServiceService>, RuntimeError>>
+ Send
+ 'a,
>,
>;
pub trait FileSystemServiceFactory: Send + Sync {
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> FileSystemServiceFactoryFuture<'_>;
}
struct FileSystemServiceFactoryAdapter<TFactory> {
inner: Arc<TFactory>,
}
impl<TFactory: FileSystemServiceFactory + 'static> RpcServiceFactory
for FileSystemServiceFactoryAdapter<TFactory>
{
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> FactoryFuture {
let inner = Arc::clone(&self.inner);
Box::pin(async move {
let service = inner.create(ctx, create_payload, options).await?;
let handler: Arc<dyn RpcServiceHandler> =
Arc::new(FileSystemServiceHandler::new(service));
Ok(handler)
})
}
}
pub type RuntimeServiceGetInfoFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<RuntimeInfo, RuntimeError>> + Send + 'a>,
>;
pub type RuntimeServiceListCapabilitiesFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<Vec<String>, RuntimeError>> + Send + 'a>,
>;
pub type RuntimeServiceDisposeResourcesFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub trait RuntimeServiceService: Send + Sync {
fn get_info(&self, ctx: RpcCallContext, request: Empty) -> RuntimeServiceGetInfoFuture<'_>;
fn list_capabilities(
&self,
ctx: RpcCallContext,
request: Empty,
) -> RuntimeServiceListCapabilitiesFuture<'_>;
fn dispose_resources(
&self,
ctx: RpcCallContext,
request: Empty,
) -> RuntimeServiceDisposeResourcesFuture<'_>;
}
pub struct RuntimeServiceHandler<T: ?Sized> {
inner: Arc<T>,
}
impl<T: ?Sized> RuntimeServiceHandler<T> {
pub fn new(inner: Arc<T>) -> Self {
Self { inner }
}
}
impl<T: RuntimeServiceService + ?Sized + 'static> RpcServiceHandler for RuntimeServiceHandler<T> {
fn call(
&self,
ctx: RpcCallContext,
method_id: MethodId,
payload: rmpv::Value,
) -> HandlerFuture {
let inner = Arc::clone(&self.inner);
match method_id.get() {
1 => Box::pin(async move {
let request = decode_empty(&payload)?;
let response = inner.get_info(ctx, request).await?;
Ok(encode_runtime_info(&response))
}),
2 => Box::pin(async move {
let request = decode_empty(&payload)?;
let response = inner.list_capabilities(ctx, request).await?;
Ok(Value::Array(
response
.iter()
.map(|item| Value::from(item.as_str()))
.collect(),
))
}),
3 => Box::pin(async move {
let request = decode_empty(&payload)?;
let response = inner.dispose_resources(ctx, request).await?;
Ok(encode_empty(&response))
}),
_ => Box::pin(async move {
Err(RuntimeError::runtime(
RuntimeErrorCode::MethodNotFound,
"unknown generated method id",
))
}),
}
}
}
pub fn register_runtime_service_named<T: RuntimeServiceService + 'static>(
builder: &mut RpcServerBuilder,
name: impl Into<String>,
service: Arc<T>,
) -> InstanceId {
builder.register_named_instance(
name,
runtime_service_service_guid(),
runtime_service_method_ids(),
Arc::new(RuntimeServiceHandler::new(service)),
)
}
pub fn register_runtime_service_singleton<T: RuntimeServiceService + 'static>(
builder: &mut RpcServerBuilder,
service: Arc<T>,
) -> InstanceId {
builder.register_singleton(
runtime_service_service_guid(),
runtime_service_method_ids(),
Arc::new(RuntimeServiceHandler::new(service)),
)
}
pub fn register_runtime_service_factory<TFactory: RuntimeServiceFactory + 'static>(
builder: &mut RpcServerBuilder,
factory: Arc<TFactory>,
) {
builder.register_factory(
runtime_service_service_guid(),
runtime_service_method_ids(),
Arc::new(RuntimeServiceFactoryAdapter { inner: factory }),
);
}
pub type RuntimeServiceFactoryFuture<'a> = std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<Arc<dyn RuntimeServiceService>, RuntimeError>>
+ Send
+ 'a,
>,
>;
pub trait RuntimeServiceFactory: Send + Sync {
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> RuntimeServiceFactoryFuture<'_>;
}
struct RuntimeServiceFactoryAdapter<TFactory> {
inner: Arc<TFactory>,
}
impl<TFactory: RuntimeServiceFactory + 'static> RpcServiceFactory
for RuntimeServiceFactoryAdapter<TFactory>
{
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> FactoryFuture {
let inner = Arc::clone(&self.inner);
Box::pin(async move {
let service = inner.create(ctx, create_payload, options).await?;
let handler: Arc<dyn RpcServiceHandler> = Arc::new(RuntimeServiceHandler::new(service));
Ok(handler)
})
}
}
pub type SqliteServiceOpenFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<ResourceHandle, RuntimeError>> + Send + 'a>,
>;
pub type SqliteServiceCloseFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type SqliteServiceExecuteBatchFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type SqliteServiceRunFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<SqliteRunResult, RuntimeError>> + Send + 'a>,
>;
pub type SqliteServiceQueryOneFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<Option<SqliteRow>, RuntimeError>> + Send + 'a>,
>;
pub type SqliteServiceQueryAllFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<Vec<SqliteRow>, RuntimeError>> + Send + 'a>,
>;
pub type SqliteServiceTransactionFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub trait SqliteServiceService: Send + Sync {
fn open(&self, ctx: RpcCallContext, request: SqliteOpenRequest) -> SqliteServiceOpenFuture<'_>;
fn close(&self, ctx: RpcCallContext, request: ResourceHandle) -> SqliteServiceCloseFuture<'_>;
fn execute_batch(
&self,
ctx: RpcCallContext,
request: SqliteStatementRequest,
) -> SqliteServiceExecuteBatchFuture<'_>;
fn run(
&self,
ctx: RpcCallContext,
request: SqliteStatementRequest,
) -> SqliteServiceRunFuture<'_>;
fn query_one(
&self,
ctx: RpcCallContext,
request: SqliteStatementRequest,
) -> SqliteServiceQueryOneFuture<'_>;
fn query_all(
&self,
ctx: RpcCallContext,
request: SqliteStatementRequest,
) -> SqliteServiceQueryAllFuture<'_>;
fn transaction(
&self,
ctx: RpcCallContext,
request: SqliteTransactionRequest,
) -> SqliteServiceTransactionFuture<'_>;
}
pub struct SqliteServiceHandler<T: ?Sized> {
inner: Arc<T>,
}
impl<T: ?Sized> SqliteServiceHandler<T> {
pub fn new(inner: Arc<T>) -> Self {
Self { inner }
}
}
impl<T: SqliteServiceService + ?Sized + 'static> RpcServiceHandler for SqliteServiceHandler<T> {
fn call(
&self,
ctx: RpcCallContext,
method_id: MethodId,
payload: rmpv::Value,
) -> HandlerFuture {
let inner = Arc::clone(&self.inner);
match method_id.get() {
1 => Box::pin(async move {
let request = decode_sqlite_open_request(&payload)?;
let response = inner.open(ctx, request).await?;
Ok(encode_resource_handle(&response))
}),
2 => Box::pin(async move {
let request = decode_resource_handle(&payload)?;
let response = inner.close(ctx, request).await?;
Ok(encode_empty(&response))
}),
3 => Box::pin(async move {
let request = decode_sqlite_statement_request(&payload)?;
let response = inner.execute_batch(ctx, request).await?;
Ok(encode_empty(&response))
}),
4 => Box::pin(async move {
let request = decode_sqlite_statement_request(&payload)?;
let response = inner.run(ctx, request).await?;
Ok(encode_sqlite_run_result(&response))
}),
5 => Box::pin(async move {
let request = decode_sqlite_statement_request(&payload)?;
let response = inner.query_one(ctx, request).await?;
Ok(match &response {
Some(value) => encode_sqlite_row(value),
None => Value::Nil,
})
}),
6 => Box::pin(async move {
let request = decode_sqlite_statement_request(&payload)?;
let response = inner.query_all(ctx, request).await?;
Ok(Value::Array(
response
.iter()
.map(|item| encode_sqlite_row(&item))
.collect(),
))
}),
7 => Box::pin(async move {
let request = decode_sqlite_transaction_request(&payload)?;
let response = inner.transaction(ctx, request).await?;
Ok(encode_empty(&response))
}),
_ => Box::pin(async move {
Err(RuntimeError::runtime(
RuntimeErrorCode::MethodNotFound,
"unknown generated method id",
))
}),
}
}
}
pub fn register_sqlite_service_named<T: SqliteServiceService + 'static>(
builder: &mut RpcServerBuilder,
name: impl Into<String>,
service: Arc<T>,
) -> InstanceId {
builder.register_named_instance(
name,
sqlite_service_service_guid(),
sqlite_service_method_ids(),
Arc::new(SqliteServiceHandler::new(service)),
)
}
pub fn register_sqlite_service_singleton<T: SqliteServiceService + 'static>(
builder: &mut RpcServerBuilder,
service: Arc<T>,
) -> InstanceId {
builder.register_singleton(
sqlite_service_service_guid(),
sqlite_service_method_ids(),
Arc::new(SqliteServiceHandler::new(service)),
)
}
pub fn register_sqlite_service_factory<TFactory: SqliteServiceFactory + 'static>(
builder: &mut RpcServerBuilder,
factory: Arc<TFactory>,
) {
builder.register_factory(
sqlite_service_service_guid(),
sqlite_service_method_ids(),
Arc::new(SqliteServiceFactoryAdapter { inner: factory }),
);
}
pub type SqliteServiceFactoryFuture<'a> = std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<Arc<dyn SqliteServiceService>, RuntimeError>>
+ Send
+ 'a,
>,
>;
pub trait SqliteServiceFactory: Send + Sync {
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> SqliteServiceFactoryFuture<'_>;
}
struct SqliteServiceFactoryAdapter<TFactory> {
inner: Arc<TFactory>,
}
impl<TFactory: SqliteServiceFactory + 'static> RpcServiceFactory
for SqliteServiceFactoryAdapter<TFactory>
{
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> FactoryFuture {
let inner = Arc::clone(&self.inner);
Box::pin(async move {
let service = inner.create(ctx, create_payload, options).await?;
let handler: Arc<dyn RpcServiceHandler> = Arc::new(SqliteServiceHandler::new(service));
Ok(handler)
})
}
}
pub type SystemServiceGetPowerCapabilitiesFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<Vec<String>, RuntimeError>> + Send + 'a>,
>;
pub type SystemServiceShutdownFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type SystemServiceRebootFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub trait SystemServiceService: Send + Sync {
fn get_power_capabilities(
&self,
ctx: RpcCallContext,
request: Empty,
) -> SystemServiceGetPowerCapabilitiesFuture<'_>;
fn shutdown(
&self,
ctx: RpcCallContext,
request: PowerOptions,
) -> SystemServiceShutdownFuture<'_>;
fn reboot(&self, ctx: RpcCallContext, request: PowerOptions) -> SystemServiceRebootFuture<'_>;
}
pub struct SystemServiceHandler<T: ?Sized> {
inner: Arc<T>,
}
impl<T: ?Sized> SystemServiceHandler<T> {
pub fn new(inner: Arc<T>) -> Self {
Self { inner }
}
}
impl<T: SystemServiceService + ?Sized + 'static> RpcServiceHandler for SystemServiceHandler<T> {
fn call(
&self,
ctx: RpcCallContext,
method_id: MethodId,
payload: rmpv::Value,
) -> HandlerFuture {
let inner = Arc::clone(&self.inner);
match method_id.get() {
1 => Box::pin(async move {
let request = decode_empty(&payload)?;
let response = inner.get_power_capabilities(ctx, request).await?;
Ok(Value::Array(
response
.iter()
.map(|item| Value::from(item.as_str()))
.collect(),
))
}),
2 => Box::pin(async move {
let request = decode_power_options(&payload)?;
let response = inner.shutdown(ctx, request).await?;
Ok(encode_empty(&response))
}),
3 => Box::pin(async move {
let request = decode_power_options(&payload)?;
let response = inner.reboot(ctx, request).await?;
Ok(encode_empty(&response))
}),
_ => Box::pin(async move {
Err(RuntimeError::runtime(
RuntimeErrorCode::MethodNotFound,
"unknown generated method id",
))
}),
}
}
}
pub fn register_system_service_named<T: SystemServiceService + 'static>(
builder: &mut RpcServerBuilder,
name: impl Into<String>,
service: Arc<T>,
) -> InstanceId {
builder.register_named_instance(
name,
system_service_service_guid(),
system_service_method_ids(),
Arc::new(SystemServiceHandler::new(service)),
)
}
pub fn register_system_service_singleton<T: SystemServiceService + 'static>(
builder: &mut RpcServerBuilder,
service: Arc<T>,
) -> InstanceId {
builder.register_singleton(
system_service_service_guid(),
system_service_method_ids(),
Arc::new(SystemServiceHandler::new(service)),
)
}
pub fn register_system_service_factory<TFactory: SystemServiceFactory + 'static>(
builder: &mut RpcServerBuilder,
factory: Arc<TFactory>,
) {
builder.register_factory(
system_service_service_guid(),
system_service_method_ids(),
Arc::new(SystemServiceFactoryAdapter { inner: factory }),
);
}
pub type SystemServiceFactoryFuture<'a> = std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<Arc<dyn SystemServiceService>, RuntimeError>>
+ Send
+ 'a,
>,
>;
pub trait SystemServiceFactory: Send + Sync {
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> SystemServiceFactoryFuture<'_>;
}
struct SystemServiceFactoryAdapter<TFactory> {
inner: Arc<TFactory>,
}
impl<TFactory: SystemServiceFactory + 'static> RpcServiceFactory
for SystemServiceFactoryAdapter<TFactory>
{
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> FactoryFuture {
let inner = Arc::clone(&self.inner);
Box::pin(async move {
let service = inner.create(ctx, create_payload, options).await?;
let handler: Arc<dyn RpcServiceHandler> = Arc::new(SystemServiceHandler::new(service));
Ok(handler)
})
}
}
pub type TcpServiceConnectFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<ResourceHandle, RuntimeError>> + Send + 'a>,
>;
pub type TcpServiceSocketWriteFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type TcpServiceSocketEndFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type TcpServiceSocketCloseFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type TcpServiceServerListenFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<ListenResult, RuntimeError>> + Send + 'a>,
>;
pub type TcpServiceServerCloseFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub trait TcpServiceService: Send + Sync {
fn connect(
&self,
ctx: RpcCallContext,
request: SocketConnectRequest,
) -> TcpServiceConnectFuture<'_>;
fn socket_write(
&self,
ctx: RpcCallContext,
request: SocketWriteRequest,
) -> TcpServiceSocketWriteFuture<'_>;
fn socket_end(
&self,
ctx: RpcCallContext,
request: ResourceHandle,
) -> TcpServiceSocketEndFuture<'_>;
fn socket_close(
&self,
ctx: RpcCallContext,
request: ResourceHandle,
) -> TcpServiceSocketCloseFuture<'_>;
fn server_listen(
&self,
ctx: RpcCallContext,
request: SocketListenRequest,
) -> TcpServiceServerListenFuture<'_>;
fn server_close(
&self,
ctx: RpcCallContext,
request: ResourceHandle,
) -> TcpServiceServerCloseFuture<'_>;
}
pub struct TcpServiceHandler<T: ?Sized> {
inner: Arc<T>,
}
impl<T: ?Sized> TcpServiceHandler<T> {
pub fn new(inner: Arc<T>) -> Self {
Self { inner }
}
}
impl<T: TcpServiceService + ?Sized + 'static> RpcServiceHandler for TcpServiceHandler<T> {
fn call(
&self,
ctx: RpcCallContext,
method_id: MethodId,
payload: rmpv::Value,
) -> HandlerFuture {
let inner = Arc::clone(&self.inner);
match method_id.get() {
1 => Box::pin(async move {
let request = decode_socket_connect_request(&payload)?;
let response = inner.connect(ctx, request).await?;
Ok(encode_resource_handle(&response))
}),
2 => Box::pin(async move {
let request = decode_socket_write_request(&payload)?;
let response = inner.socket_write(ctx, request).await?;
Ok(encode_empty(&response))
}),
3 => Box::pin(async move {
let request = decode_resource_handle(&payload)?;
let response = inner.socket_end(ctx, request).await?;
Ok(encode_empty(&response))
}),
4 => Box::pin(async move {
let request = decode_resource_handle(&payload)?;
let response = inner.socket_close(ctx, request).await?;
Ok(encode_empty(&response))
}),
5 => Box::pin(async move {
let request = decode_socket_listen_request(&payload)?;
let response = inner.server_listen(ctx, request).await?;
Ok(encode_listen_result(&response))
}),
6 => Box::pin(async move {
let request = decode_resource_handle(&payload)?;
let response = inner.server_close(ctx, request).await?;
Ok(encode_empty(&response))
}),
_ => Box::pin(async move {
Err(RuntimeError::runtime(
RuntimeErrorCode::MethodNotFound,
"unknown generated method id",
))
}),
}
}
}
pub fn register_tcp_service_named<T: TcpServiceService + 'static>(
builder: &mut RpcServerBuilder,
name: impl Into<String>,
service: Arc<T>,
) -> InstanceId {
builder.register_named_instance(
name,
tcp_service_service_guid(),
tcp_service_method_ids(),
Arc::new(TcpServiceHandler::new(service)),
)
}
pub fn register_tcp_service_singleton<T: TcpServiceService + 'static>(
builder: &mut RpcServerBuilder,
service: Arc<T>,
) -> InstanceId {
builder.register_singleton(
tcp_service_service_guid(),
tcp_service_method_ids(),
Arc::new(TcpServiceHandler::new(service)),
)
}
pub fn register_tcp_service_factory<TFactory: TcpServiceFactory + 'static>(
builder: &mut RpcServerBuilder,
factory: Arc<TFactory>,
) {
builder.register_factory(
tcp_service_service_guid(),
tcp_service_method_ids(),
Arc::new(TcpServiceFactoryAdapter { inner: factory }),
);
}
pub type TcpServiceFactoryFuture<'a> = std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<Arc<dyn TcpServiceService>, RuntimeError>>
+ Send
+ 'a,
>,
>;
pub trait TcpServiceFactory: Send + Sync {
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> TcpServiceFactoryFuture<'_>;
}
struct TcpServiceFactoryAdapter<TFactory> {
inner: Arc<TFactory>,
}
impl<TFactory: TcpServiceFactory + 'static> RpcServiceFactory
for TcpServiceFactoryAdapter<TFactory>
{
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> FactoryFuture {
let inner = Arc::clone(&self.inner);
Box::pin(async move {
let service = inner.create(ctx, create_payload, options).await?;
let handler: Arc<dyn RpcServiceHandler> = Arc::new(TcpServiceHandler::new(service));
Ok(handler)
})
}
}
pub type WebSocketServiceConnectFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<ResourceHandle, RuntimeError>> + Send + 'a>,
>;
pub type WebSocketServiceSendTextFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type WebSocketServiceSendBinaryFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type WebSocketServiceCloseFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub type WebSocketServiceServerListenFuture<'a> = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<ListenResult, RuntimeError>> + Send + 'a>,
>;
pub type WebSocketServiceServerCloseFuture<'a> =
std::pin::Pin<Box<dyn std::future::Future<Output = Result<Empty, RuntimeError>> + Send + 'a>>;
pub trait WebSocketServiceService: Send + Sync {
fn connect(
&self,
ctx: RpcCallContext,
request: WebSocketConnectRequest,
) -> WebSocketServiceConnectFuture<'_>;
fn send_text(
&self,
ctx: RpcCallContext,
request: WebSocketSendTextRequest,
) -> WebSocketServiceSendTextFuture<'_>;
fn send_binary(
&self,
ctx: RpcCallContext,
request: SocketWriteRequest,
) -> WebSocketServiceSendBinaryFuture<'_>;
fn close(
&self,
ctx: RpcCallContext,
request: ResourceHandle,
) -> WebSocketServiceCloseFuture<'_>;
fn server_listen(
&self,
ctx: RpcCallContext,
request: SocketListenRequest,
) -> WebSocketServiceServerListenFuture<'_>;
fn server_close(
&self,
ctx: RpcCallContext,
request: ResourceHandle,
) -> WebSocketServiceServerCloseFuture<'_>;
}
pub struct WebSocketServiceHandler<T: ?Sized> {
inner: Arc<T>,
}
impl<T: ?Sized> WebSocketServiceHandler<T> {
pub fn new(inner: Arc<T>) -> Self {
Self { inner }
}
}
impl<T: WebSocketServiceService + ?Sized + 'static> RpcServiceHandler
for WebSocketServiceHandler<T>
{
fn call(
&self,
ctx: RpcCallContext,
method_id: MethodId,
payload: rmpv::Value,
) -> HandlerFuture {
let inner = Arc::clone(&self.inner);
match method_id.get() {
1 => Box::pin(async move {
let request = decode_web_socket_connect_request(&payload)?;
let response = inner.connect(ctx, request).await?;
Ok(encode_resource_handle(&response))
}),
2 => Box::pin(async move {
let request = decode_web_socket_send_text_request(&payload)?;
let response = inner.send_text(ctx, request).await?;
Ok(encode_empty(&response))
}),
3 => Box::pin(async move {
let request = decode_socket_write_request(&payload)?;
let response = inner.send_binary(ctx, request).await?;
Ok(encode_empty(&response))
}),
4 => Box::pin(async move {
let request = decode_resource_handle(&payload)?;
let response = inner.close(ctx, request).await?;
Ok(encode_empty(&response))
}),
5 => Box::pin(async move {
let request = decode_socket_listen_request(&payload)?;
let response = inner.server_listen(ctx, request).await?;
Ok(encode_listen_result(&response))
}),
6 => Box::pin(async move {
let request = decode_resource_handle(&payload)?;
let response = inner.server_close(ctx, request).await?;
Ok(encode_empty(&response))
}),
_ => Box::pin(async move {
Err(RuntimeError::runtime(
RuntimeErrorCode::MethodNotFound,
"unknown generated method id",
))
}),
}
}
}
pub fn register_web_socket_service_named<T: WebSocketServiceService + 'static>(
builder: &mut RpcServerBuilder,
name: impl Into<String>,
service: Arc<T>,
) -> InstanceId {
builder.register_named_instance(
name,
web_socket_service_service_guid(),
web_socket_service_method_ids(),
Arc::new(WebSocketServiceHandler::new(service)),
)
}
pub fn register_web_socket_service_singleton<T: WebSocketServiceService + 'static>(
builder: &mut RpcServerBuilder,
service: Arc<T>,
) -> InstanceId {
builder.register_singleton(
web_socket_service_service_guid(),
web_socket_service_method_ids(),
Arc::new(WebSocketServiceHandler::new(service)),
)
}
pub fn register_web_socket_service_factory<TFactory: WebSocketServiceFactory + 'static>(
builder: &mut RpcServerBuilder,
factory: Arc<TFactory>,
) {
builder.register_factory(
web_socket_service_service_guid(),
web_socket_service_method_ids(),
Arc::new(WebSocketServiceFactoryAdapter { inner: factory }),
);
}
pub type WebSocketServiceFactoryFuture<'a> = std::pin::Pin<
Box<
dyn std::future::Future<Output = Result<Arc<dyn WebSocketServiceService>, RuntimeError>>
+ Send
+ 'a,
>,
>;
pub trait WebSocketServiceFactory: Send + Sync {
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> WebSocketServiceFactoryFuture<'_>;
}
struct WebSocketServiceFactoryAdapter<TFactory> {
inner: Arc<TFactory>,
}
impl<TFactory: WebSocketServiceFactory + 'static> RpcServiceFactory
for WebSocketServiceFactoryAdapter<TFactory>
{
fn create(
&self,
ctx: RpcCallContext,
create_payload: Option<Vec<u8>>,
options: BTreeMap<String, String>,
) -> FactoryFuture {
let inner = Arc::clone(&self.inner);
Box::pin(async move {
let service = inner.create(ctx, create_payload, options).await?;
let handler: Arc<dyn RpcServiceHandler> =
Arc::new(WebSocketServiceHandler::new(service));
Ok(handler)
})
}
}