interop/
util.rs

1// Wire
2// Copyright (C) 2022 Wire Swiss GmbH
3
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see http://www.gnu.org/licenses/.
16
17use core_crypto::MlsTransport;
18use core_crypto::prelude::MlsCommitBundle;
19use core_crypto_ffi::CommitBundle;
20use openmls::prelude::MlsMessageOut;
21use spinoff::Spinner;
22use tokio::sync::RwLock;
23
24pub(crate) struct RunningProcess {
25    spinner: Option<Spinner>,
26    is_task: bool,
27}
28
29impl std::fmt::Debug for RunningProcess {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        f.debug_struct("RunningProcess")
32            .field("is_task", &self.is_task)
33            .finish()
34    }
35}
36
37impl RunningProcess {
38    pub(crate) fn new(msg: impl AsRef<str> + std::fmt::Display, is_task: bool) -> Self {
39        let spinner = if std::env::var("CI").is_err() {
40            Some(Spinner::new(
41                spinoff::spinners::Aesthetic,
42                msg.as_ref().to_owned(),
43                if is_task {
44                    spinoff::Color::Green
45                } else {
46                    spinoff::Color::Blue
47                },
48            ))
49        } else {
50            if is_task {
51                log::info!("{msg}");
52            } else {
53                log::debug!("{msg}");
54            }
55
56            None
57        };
58
59        Self { spinner, is_task }
60    }
61
62    pub(crate) fn update(&mut self, msg: impl AsRef<str> + std::fmt::Display) {
63        if let Some(spinner) = &mut self.spinner {
64            spinner.update_text(msg.as_ref().to_owned());
65        } else if self.is_task {
66            log::info!("{msg}");
67        } else {
68            log::debug!("{msg}");
69        }
70    }
71
72    pub(crate) fn success(self, msg: impl AsRef<str> + std::fmt::Display) {
73        if let Some(mut spinner) = self.spinner {
74            spinner.success(msg.as_ref());
75        } else {
76            log::info!("{msg}");
77        }
78    }
79}
80
81#[async_trait::async_trait]
82pub trait MlsTransportTestExt: MlsTransport {
83    async fn latest_commit_bundle(&self) -> MlsCommitBundle;
84    async fn latest_welcome_message(&self) -> MlsMessageOut {
85        self.latest_commit_bundle().await.welcome.unwrap().clone()
86    }
87}
88
89#[derive(Debug, Default)]
90pub struct MlsTransportSuccessProvider {
91    latest_commit_bundle: RwLock<Option<MlsCommitBundle>>,
92    latest_message: RwLock<Option<Vec<u8>>>,
93}
94
95#[async_trait::async_trait]
96impl MlsTransport for MlsTransportSuccessProvider {
97    async fn send_commit_bundle(
98        &self,
99        commit_bundle: MlsCommitBundle,
100    ) -> core_crypto::Result<core_crypto::MlsTransportResponse> {
101        self.latest_commit_bundle.write().await.replace(commit_bundle);
102        Ok(core_crypto::MlsTransportResponse::Success)
103    }
104
105    async fn send_message(&self, mls_message: Vec<u8>) -> core_crypto::Result<core_crypto::MlsTransportResponse> {
106        self.latest_message.write().await.replace(mls_message);
107        Ok(core_crypto::MlsTransportResponse::Success)
108    }
109}
110
111#[async_trait::async_trait]
112impl MlsTransportTestExt for MlsTransportSuccessProvider {
113    async fn latest_commit_bundle(&self) -> MlsCommitBundle {
114        self.latest_commit_bundle
115            .read()
116            .await
117            .clone()
118            .expect("latest_commit_bundle")
119    }
120}
121
122#[async_trait::async_trait]
123impl core_crypto_ffi::MlsTransport for MlsTransportSuccessProvider {
124    async fn send_commit_bundle(&self, _commit_bundle: CommitBundle) -> core_crypto_ffi::MlsTransportResponse {
125        core_crypto_ffi::MlsTransportResponse::Success
126    }
127
128    async fn send_message(&self, mls_message: Vec<u8>) -> core_crypto_ffi::MlsTransportResponse {
129        self.latest_message.write().await.replace(mls_message);
130        core_crypto_ffi::MlsTransportResponse::Success
131    }
132}