modio-logger 0.5.2

modio-logger Dbus service
Documentation
// Author: D.S. Ljungmark <spider@skuggor.se>, Modio AB
// SPDX-License-Identifier: AGPL-3.0-or-later
use crate::logger::LogErr;
use crate::timefail::Timefail;
use crate::types::Metadata;
use modio_logger_db::Datastore;

use log::{debug, info};
use zbus::dbus_interface;

mod builder;
pub use builder::Builder;

pub struct Submit1 {
    customer: bool,
    ds: Datastore,
    _timefail: Timefail,
}

impl Submit1 {
    pub async fn new(timefail: Timefail, ds: Datastore, customer: bool) -> Result<Self, LogErr> {
        if timefail.is_timefail() {
            info!("Failing all pending change requests due to TIMEFAIL");
            ds.transaction_fail_pending().await?;
        }
        Ok(Self {
            ds,
            _timefail: timefail,
            customer,
        })
    }

    #[must_use]
    pub fn builder() -> Builder {
        Builder::new()
    }
}

#[dbus_interface(name = "se.modio.logger.Submit1")]
impl Submit1 {
    /// Returns a vector of all metadata objects.
    pub(crate) async fn get_all_metadata(&mut self) -> Result<Vec<Metadata>, LogErr> {
        use std::convert::Into;

        debug!("Retrieving all metadata");
        let mut res = self.ds.get_all_metadata().await?;
        if self.customer {
            info!("Removing all n prefixed with modio");
            res.retain(|x| !x.n.starts_with("modio."));
        } else {
            info!("Keeping all n prefixed with modio");
            res.retain(|x| x.n.starts_with("modio."));
        };

        let arr: Vec<Metadata> = res.drain(..).map(Into::into).collect();
        debug!("Returning: {:?}", arr);
        Ok(arr)
    }
}

#[cfg(test)]
mod test {
    use crate::submit1::Submit1;
    use modio_logger_db::Datastore;
    use std::error::Error;

    #[async_std::test]
    async fn metadata_filters_for_modio() -> Result<(), Box<dyn Error>> {
        let _ = env_logger::builder().is_test(true).try_init();
        let ds = Datastore::temporary().await;
        ds.metadata_set_name("modio.key.key", "Internal only".to_string())
            .await?;
        ds.metadata_set_name("key.key.key.one", "Some Test Name".to_string())
            .await?;
        ds.metadata_set_name("key.key.key.two", "Some Test Name".to_string())
            .await?;
        ds.metadata_set_name("key.key.key.three", "Some Test Name".to_string())
            .await?;

        let mut submit1 = Submit1::builder()
            .development(true)
            .datastore(ds)
            .customer(false)
            .build()
            .await?;

        let res = submit1.get_all_metadata().await?;
        eprintln!("{:?}", res);
        // Should have 1 key
        assert_eq!(res.len(), 1);
        assert!(res[0].n.starts_with("modio."));
        Ok(())
    }

    #[async_std::test]
    async fn metadata_filters_on_customer() -> Result<(), Box<dyn Error>> {
        let _ = env_logger::builder().is_test(true).try_init();
        let ds = Datastore::temporary().await;
        ds.metadata_set_name("modio.key.key", "Internal only".to_string())
            .await?;
        ds.metadata_set_name("key.key.key.one", "Some Test Name".to_string())
            .await?;
        ds.metadata_set_name("key.key.key.two", "Some Test Name".to_string())
            .await?;
        ds.metadata_set_name("key.key.key.three", "Some Test Name".to_string())
            .await?;

        let mut submit1 = Submit1::builder()
            .development(true)
            .datastore(ds)
            .customer(true)
            .build()
            .await?;

        let res = submit1.get_all_metadata().await?;
        eprintln!("{:?}", res);
        // should have "key.key...." but not "modio...."
        assert_eq!(res.len(), 3);
        assert!(res[0].n.starts_with("key.key.key"));
        Ok(())
    }
}