-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
client_config_default
function for easy client configuration (#111
) * [uniffi] Merge `FFICallbackError` into `Error` Part of the goal of mls-rs-uniffi is to present a small FFI API. Currently, it does not seem to be necessary to use a separate error type here. * [uniffi] Move `GroupStateStorage` wrapper to client This type is specific to our client type so it can be nicely grouped with it in the client module. * [uniffi] Add a `client_config_default` function This function returns a client config with some simple defaults. Right now, the default is in-memory storage. The new `GroupStateStorageAdapter` struct allows us to use any mls-rs group state storage, so we could easily surface the Sqlite storage as well now.
- Loading branch information
Showing
5 changed files
with
147 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,79 @@ | ||
use std::{fmt::Debug, sync::Arc}; | ||
use std::fmt::Debug; | ||
use std::sync::Arc; | ||
|
||
use mls_rs::{ | ||
client_builder::{self, WithGroupStateStorage}, | ||
identity::basic, | ||
storage_provider::in_memory::InMemoryGroupStateStorage, | ||
}; | ||
use mls_rs_core::error::IntoAnyError; | ||
use mls_rs_crypto_openssl::OpensslCryptoProvider; | ||
|
||
use self::group_state::{GroupStateStorage, GroupStateStorageWrapper}; | ||
use self::group_state::{GroupStateStorage, GroupStateStorageAdapter}; | ||
use crate::Error; | ||
|
||
pub mod group_state; | ||
|
||
#[derive(Debug, thiserror::Error, uniffi::Error)] | ||
#[uniffi(flat_error)] | ||
#[non_exhaustive] | ||
pub enum FFICallbackError { | ||
#[error("data preparation error")] | ||
DataPreparationError { | ||
#[from] | ||
inner: mls_rs_core::mls_rs_codec::Error, | ||
}, | ||
#[error("unexpected callback error")] | ||
UnexpectedCallbackError { | ||
#[from] | ||
inner: uniffi::UnexpectedUniFFICallbackError, | ||
}, | ||
#[derive(Debug, Clone)] | ||
pub(crate) struct ClientGroupStorage(Arc<dyn GroupStateStorage>); | ||
|
||
impl From<Arc<dyn GroupStateStorage>> for ClientGroupStorage { | ||
fn from(value: Arc<dyn GroupStateStorage>) -> Self { | ||
Self(value) | ||
} | ||
} | ||
|
||
impl IntoAnyError for FFICallbackError {} | ||
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] | ||
#[cfg_attr(mls_build_async, maybe_async::must_be_async)] | ||
impl mls_rs_core::group::GroupStateStorage for ClientGroupStorage { | ||
type Error = Error; | ||
|
||
async fn state(&self, group_id: &[u8]) -> Result<Option<Vec<u8>>, Self::Error> { | ||
self.0.state(group_id.to_vec()) | ||
} | ||
|
||
async fn epoch(&self, group_id: &[u8], epoch_id: u64) -> Result<Option<Vec<u8>>, Self::Error> { | ||
self.0.epoch(group_id.to_vec(), epoch_id) | ||
} | ||
|
||
async fn write( | ||
&mut self, | ||
state: mls_rs_core::group::GroupState, | ||
inserts: Vec<mls_rs_core::group::EpochRecord>, | ||
updates: Vec<mls_rs_core::group::EpochRecord>, | ||
) -> Result<(), Self::Error> { | ||
self.0.write( | ||
state.into(), | ||
inserts.into_iter().map(Into::into).collect(), | ||
updates.into_iter().map(Into::into).collect(), | ||
) | ||
} | ||
|
||
async fn max_epoch_id(&self, group_id: &[u8]) -> Result<Option<u64>, Self::Error> { | ||
self.0.max_epoch_id(group_id.to_vec()) | ||
} | ||
} | ||
|
||
pub type UniFFIConfig = client_builder::WithIdentityProvider< | ||
basic::BasicIdentityProvider, | ||
client_builder::WithCryptoProvider< | ||
OpensslCryptoProvider, | ||
WithGroupStateStorage<GroupStateStorageWrapper, client_builder::BaseConfig>, | ||
WithGroupStateStorage<ClientGroupStorage, client_builder::BaseConfig>, | ||
>, | ||
>; | ||
|
||
#[derive(Debug, Clone, uniffi::Record)] | ||
pub struct ClientConfig { | ||
pub group_state_storage: Arc<dyn GroupStateStorage>, | ||
} | ||
|
||
// TODO(mgeisler): turn into an associated function when UniFFI | ||
// supports them: https://github.com/mozilla/uniffi-rs/issues/1074. | ||
/// Create a client config with an in-memory group state storage. | ||
#[uniffi::export] | ||
pub fn client_config_default() -> ClientConfig { | ||
ClientConfig { | ||
group_state_storage: Arc::new(GroupStateStorageAdapter::new( | ||
InMemoryGroupStateStorage::new(), | ||
)), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from mls_rs_uniffi import Client, CipherSuite, generate_signature_keypair, client_config_default | ||
|
||
client_config = client_config_default() | ||
key = generate_signature_keypair(CipherSuite.CURVE25519_AES128) | ||
alice = Client(b'alice', key, client_config) | ||
|
||
group = alice.create_group(None) | ||
group.write_to_storage() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters