Add file api

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent 4ca755c17c
commit 8b5af04075

@ -9,8 +9,8 @@ license = "gpl-3"
[dependencies]
tracing = "0.1.29"
thiserror = "1.0.30"
async-trait = {version = "0.1.51", optional=true}
rmp-ipc = {version = "0.7.2", optional=true}
tauri = {version = "1.0.0-beta.8", optional=true}
[dependencies.serde]
version = "1.0.130"
@ -20,6 +20,12 @@ features = ["serde_derive"]
version = "0.4.19"
features = ["serde"]
[dependencies.tauri]
version = "1.0.0-beta.8"
optional=true
default-features = false
features = []
[features]
tauri-plugin = ["client-api","tauri", "rmp-ipc"]
client-api = ["rmp-ipc"]
client-api = ["rmp-ipc", "async-trait"]

@ -0,0 +1,86 @@
use crate::client_api::error::ApiResult;
use crate::client_api::IPCApi;
use crate::types::files::{
FileMetadataResponse, FindFilesByTagsRequest, GetFileThumbnailsRequest, ReadFileRequest,
TagQuery, ThumbnailMetadataResponse,
};
use crate::types::identifier::FileIdentifier;
use async_trait::async_trait;
use rmp_ipc::prelude::Context;
#[derive(Clone)]
pub struct FileApi {
ctx: Context,
}
#[async_trait]
impl IPCApi for FileApi {
fn namespace() -> &'static str {
"files"
}
fn ctx(&self) -> &Context {
&self.ctx
}
}
impl FileApi {
/// Creates a new file api client
pub fn new(ctx: Context) -> Self {
Self { ctx }
}
/// Returns all known files
#[tracing::instrument(level = "debug", skip(self))]
pub async fn all_files(&self) -> ApiResult<Vec<FileMetadataResponse>> {
self.emit_and_get("all_files", ()).await
}
/// Searches for a file by a list of tags
#[tracing::instrument(level = "debug", skip(self))]
pub async fn find_files(&self, tags: Vec<String>) -> ApiResult<Vec<FileMetadataResponse>> {
let tags = tags
.into_iter()
.map(|tag| TagQuery {
name: tag,
negate: false,
})
.collect();
self.emit_and_get("find_files", FindFilesByTagsRequest { tags })
.await
}
/// Reads the file and returns its contents as bytes
#[tracing::instrument(level = "debug", skip(self))]
pub async fn read_file_by_hash(&self, hash: String) -> ApiResult<Vec<u8>> {
self.emit_and_get(
"read_file",
ReadFileRequest {
id: FileIdentifier::Hash(hash),
},
)
.await
}
/// Returns a list of all thumbnails of the file
#[tracing::instrument(level = "debug", skip(self))]
pub async fn get_file_thumbnails(
&self,
hash: String,
) -> ApiResult<Vec<ThumbnailMetadataResponse>> {
self.emit_and_get(
"get_thumbnails",
GetFileThumbnailsRequest {
id: FileIdentifier::Hash(hash),
},
)
.await
}
/// Reads the thumbnail of the file and returns its contents in bytes
#[tracing::instrument(level = "debug", skip(self))]
pub async fn read_thumbnail(&self, hash: String) -> ApiResult<Vec<u8>> {
self.emit_and_get("read_thumbnail", hash).await
}
}

@ -1,18 +1,49 @@
pub mod error;
pub mod file;
use std::fmt::Debug;
use rmp_ipc::ipc::context::Context;
use rmp_ipc::IPCBuilder;
use crate::client_api::error::ApiResult;
use crate::client_api::file::FileApi;
use crate::types::misc::InfoResponse;
use async_trait::async_trait;
use rmp_ipc::ipc::stream_emitter::EmitMetadata;
use rmp_ipc::payload::{EventReceivePayload, EventSendPayload};
#[async_trait]
pub trait IPCApi {
fn namespace() -> &'static str;
fn ctx(&self) -> &Context;
async fn emit<T: EventSendPayload + Debug + Send>(&self, event_name: &str, data: T) -> ApiResult<EmitMetadata> {
let ctx = self.ctx();
let meta = ctx.emitter.emit_to(Self::namespace(), event_name, data).await?;
Ok(meta)
}
async fn emit_and_get<T: EventSendPayload + Debug + Send, R: EventReceivePayload + Debug + Send>(&self, event_name: &str, data: T) -> ApiResult<R> {
let meta = self.emit(event_name, data).await?;
let response = meta.await_reply(self.ctx()).await?;
Ok(response.data()?)
}
}
#[derive(Clone)]
pub struct ApiClient {
ctx: Context,
pub file: FileApi,
}
impl ApiClient {
/// Creates a new client from an existing ipc context
pub fn new(ctx: Context) -> Self {
Self {ctx}
Self {
file: FileApi::new(ctx.clone()),
ctx
}
}
/// Connects to the ipc Socket
@ -21,4 +52,11 @@ impl ApiClient {
Ok(Self::new(ctx))
}
/// Returns information about the connected ipc server
#[tracing::instrument(level="debug", skip(self))]
pub async fn info(&self) -> ApiResult<InfoResponse> {
let res = self.ctx.emitter.emit("info", ()).await?.await_reply(&self.ctx).await?;
Ok(res.data::<InfoResponse>()?)
}
}
Loading…
Cancel
Save