rustpbx 0.3.19

A SIP PBX implementation in Rust
Documentation
use crate::config::CallRecordConfig;
use crate::storage::{Storage, StorageConfig};
use anyhow::{Context, Result};
use bytes::Bytes;
use std::path::PathBuf;

#[derive(Clone)]
pub struct CdrStorage {
    inner: Storage,
}

impl CdrStorage {
    pub fn new(storage: Storage) -> Self {
        Self { inner: storage }
    }

    pub fn is_local(&self) -> bool {
        self.inner.is_local()
    }

    pub fn local_full_path(&self, path: &str) -> Option<PathBuf> {
        self.inner.local_path(path)
    }

    pub fn path_for_metadata(&self, path: &str) -> String {
        if self.is_local() {
            self.inner
                .local_path(path)
                .unwrap()
                .to_string_lossy()
                .into_owned()
        } else {
            path.to_string()
        }
    }

    pub async fn write_bytes(&self, path: &str, bytes: &[u8]) -> Result<String> {
        self.inner
            .write(path, Bytes::copy_from_slice(bytes))
            .await?;
        Ok(path.to_string())
    }

    pub async fn read_bytes(&self, path: &str) -> Result<Vec<u8>> {
        let bytes = self.inner.read(path).await?;
        Ok(bytes.to_vec())
    }

    pub async fn read_to_string(&self, path: &str) -> Result<String> {
        let bytes = self.read_bytes(path).await?;
        Ok(String::from_utf8(bytes).with_context(|| format!("decode UTF-8 for {}", path))?)
    }
}

pub fn resolve_storage(config: Option<&CallRecordConfig>) -> Result<Option<CdrStorage>> {
    match config {
        Some(CallRecordConfig::Local { root }) => {
            let storage_config = StorageConfig::Local { path: root.clone() };
            let storage = Storage::new(&storage_config)?;
            Ok(Some(CdrStorage::new(storage)))
        }
        Some(CallRecordConfig::S3 {
            vendor,
            bucket,
            region,
            access_key,
            secret_key,
            endpoint,
            root,
            ..
        }) => {
            let storage_config = StorageConfig::S3 {
                vendor: vendor.clone(),
                bucket: bucket.clone(),
                region: region.clone(),
                access_key: access_key.clone(),
                secret_key: secret_key.clone(),
                endpoint: Some(endpoint.clone()),
                prefix: Some(root.clone()),
            };
            let storage = Storage::new(&storage_config)?;
            Ok(Some(CdrStorage::new(storage)))
        }
        Some(CallRecordConfig::Http { .. }) => Ok(None),
        None => Ok(None),
    }
}