Skip to content

Commit

Permalink
feat: Add serialization and deserialization to AppPermission and AppI…
Browse files Browse the repository at this point in the history
…nfo structs, implement AppInstallMetadata and VAppAccountContent, and add methods to manage app installation and removal in MatrixManager
  • Loading branch information
S0c5 committed Feb 28, 2024
1 parent 72d9873 commit 6992a41
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 54 deletions.
4 changes: 2 additions & 2 deletions core/src/base/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{std::wallet::aggregate, utils};
use futures::executor;
use serde::{de::DeserializeOwned, Deserialize, Serialize};

#[derive(Serialize)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct AppPermission {
name: String,
description: String,
Expand All @@ -15,7 +15,7 @@ pub struct AppPermission {
events: Vec<String>,
}

#[derive(Serialize)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct AppInfo {
pub id: String,
pub name: String,
Expand Down
1 change: 1 addition & 0 deletions core/src/base/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use async_trait::async_trait;
#[derive(Debug)]
pub enum AppManagerError {
AlreadyInstalled,
Unknown,
CantInstall(String),
CantUninstall(String),
}
Expand Down
105 changes: 100 additions & 5 deletions core/src/base/matrix/manager.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,93 @@
use crate::utils::HashMap;

use async_trait::async_trait;
use matrix_sdk::{
ruma::{
api::client::room::create_room::v3::Request as CreateRoomRequest,
api::client::room::Visibility,
events::{room::encryption::RoomEncryptionEventContent, InitialStateEvent},
api::client::room::{create_room::v3::Request as CreateRoomRequest, Visibility},
events::{
macros::EventContent, room::encryption::RoomEncryptionEventContent, InitialStateEvent,
},
serde::Raw,
},
Client, Room,
};

use crate::base::{AppInfo, AppManagerError};
use serde::{Deserialize, Serialize};

use super::super::{AppManager, AppManagerResult};

struct MatrixManager {
client: Box<Client>,
}

#[derive(Serialize, Clone, Debug, Deserialize)]
pub struct AppInstallMetadata {
app_info: AppInfo,
room_id: String,
}

#[derive(Serialize, Clone, Debug, Default, Deserialize, EventContent)]
#[ruma_event(type = "m.virto.apps", kind = GlobalAccountData)]
pub struct VAppAccountContent {
apps: HashMap<String, AppInstallMetadata>,
}

impl MatrixManager {
fn new(client: Box<Client>) -> Self {
Self { client }
}

async fn reload_state(&self) -> Result<VAppAccountContent, AppManagerError> {
let account_data_vapp = self
.client
.account()
.account_data::<VAppAccountContent>()
.await
.map_err(|_| AppManagerError::Unknown)?;

let raw_vapp = account_data_vapp.unwrap_or(
Raw::new(&VAppAccountContent::default()).map_err(|_| AppManagerError::Unknown)?,
);

Ok(raw_vapp
.deserialize()
.map_err(|_| AppManagerError::Unknown)?)
}

async fn add_app(&self, app_info: &AppInfo, room: Room) -> Result<(), AppManagerError> {
let mut vapps = self.reload_state().await?;

vapps.apps.insert(
app_info.id.clone().into(),
AppInstallMetadata {
app_info: app_info.clone(),
room_id: room.room_id().to_string(),
},
);

self.client
.account()
.set_account_data(vapps)
.await
.map_err(|_| AppManagerError::Unknown)?;

Ok(())
}

async fn remove_app(&self, app_info: &AppInfo) -> Result<(), AppManagerError> {
let mut vapps = self.reload_state().await?;
vapps.apps.remove(&app_info.id);

self.client
.account()
.set_account_data(vapps)
.await
.map_err(|_| AppManagerError::Unknown)?;

Ok(())
}

fn get_room_id(&self, app_info: &AppInfo) -> String {
format!("app-{}", app_info.id)
}
Expand Down Expand Up @@ -56,6 +123,7 @@ impl AppManager for MatrixManager {
.await
.map_err(|_| AppManagerError::CantInstall("Erro Creating the Room".to_string()))?;

self.add_app(info, room).await?;
Ok(())
}

Expand All @@ -71,6 +139,8 @@ impl AppManager for MatrixManager {
room.forget()
.await
.map_err(|_| AppManagerError::CantUninstall("Can't forget the room".to_string()))?;

self.remove_app(info).await?;
Ok(())
}

Expand All @@ -91,8 +161,8 @@ mod manager_test {
use crate::{base::AppInfo, base::AppManager, SDKBuilder, SDKCore};
use async_once_cell::OnceCell;
use ctor::ctor;
use tokio::time::{sleep, Duration};
use tokio::test;
use tokio::time::{sleep, Duration};
use tracing_subscriber::fmt::init as InitLogger;

static mut SDK_CORE: OnceCell<SDKCore> = OnceCell::new();
Expand Down Expand Up @@ -175,7 +245,25 @@ mod manager_test {
}

#[tokio::test]
async fn app_2_uninstall() {
async fn app_3_read_state() {
let mut sdkCore = get_sdk().await;

let app_info = AppInfo {
description: "foo".into(),
name: "wallet".into(),
id: "com.virto.wallet".into(),
author: "[email protected]".into(),
version: "0.0.1".into(),
permission: vec![],
};
sdkCore.next_sync().await;
let manager = MatrixManager::new(sdkCore.client());
let state = manager.reload_state().await.expect("hello");
assert_eq!(state.apps.get(&app_info.id).unwrap().app_info, app_info);
}

#[tokio::test]
async fn app_99_uninstall() {
let mut sdkCore = get_sdk().await;

let app_info = AppInfo {
Expand All @@ -190,9 +278,16 @@ mod manager_test {
sdkCore.next_sync().await;

let manager = MatrixManager::new(sdkCore.client());

assert_eq!(
manager.uninstall(&app_info).await.expect("cant uninstall"),
()
);

sdkCore.next_sync().await;

let state = manager.reload_state().await.expect("cant get reload event");

assert!(state.apps.get(&app_info.id).is_none());
}
}
46 changes: 0 additions & 46 deletions core/src/base/matrix/mod.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,3 @@
mod manager;

pub use manager::*;

// impl<'sdk> AppManager for App<'sdk> {
// async fn is_installed(&self) -> bool {
// self.get_room().is_some()
// }

// async fn install(&self) -> Result<(), AppManagerError> {
// if self.is_installed().await {
// return Err(AppManagerError::AlreadyInstalled);
// }
// let mut room = CreateRoomRequest::new();

// room.visibility = Visibility::Private;
// room.name = Some(self.get_room_id());
// room.initial_state =
// vec![
// InitialStateEvent::new(RoomEncryptionEventContent::with_recommended_defaults())
// .to_raw_any(),
// ];

// let room = self
// .sdk
// .client()
// .create_room(room)
// .await
// .map_err(|_| AppManagerError::CantInstall("Erro Creating the Room".to_string()))?;

// Ok(())
// }

// async fn uninstall(&self) -> Result<(), AppManagerError> {
// let room = self.get_room().ok_or(AppManagerError::CantUninstall(
// "Can't get installed room".to_string(),
// ))?;

// room.leave()
// .await
// .map_err(|_| AppManagerError::CantUninstall("Can't leave the room".to_string()))?;

// room.forget()
// .await
// .map_err(|_| AppManagerError::CantUninstall("Can't forget the room".to_string()))?;
// Ok(())
// }

// }
2 changes: 1 addition & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl SDKCore {
}
self.inner.clone()
}

async fn next_sync(&mut self) -> Result<(), SDKError> {
let mut settings = SyncSettings::default();

Expand Down

0 comments on commit 6992a41

Please sign in to comment.