1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
use super::error::{Error, StorageError};
use num_traits::FromPrimitive;
use serde::{Deserialize, Serialize};
use serde_json;
use std::collections::HashMap;

#[link(wasm_import_module = "storage_response")]
extern "C" {
    fn storage_response_get_body(err_ptr: *mut i32) -> i32;
    fn storage_response_get_headers(err_ptr: *mut i32) -> i32;
}

/// Response to the [`crate::storage::get`] request.
///
/// [get]: super::storage::get
#[derive(Debug, Clone)]
pub struct StorageResponse {
    headers: HashMap<String, String>,
    body: Option<Vec<u8>>,
}

/// Represents the attributes associated with a stored file.
///
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct FileAttributes {
    pub properties: Option<HashMap<String, String>>,
    #[serde(rename = "defaultVersion")]
    pub default_version: Option<String>,
}

impl FileAttributes {
    pub fn new(
        properties: Option<HashMap<String, String>>,
        default_version: Option<String>,
    ) -> Self {
        FileAttributes {
            properties,
            default_version,
        }
    }
    pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, StorageError> {
        let attr: FileAttributes = serde_json::from_slice(&bytes)?;
        Ok(attr)
    }
}

impl StorageResponse {
    pub fn new() -> Result<StorageResponse, StorageError> {
        let headers: HashMap<String, String>;
        let body: Option<Vec<u8>>;
        headers = get_all_headers_from_host()?;
        body = Some(get_body_from_host()?);

        Ok(StorageResponse {
            headers: headers,
            body: body,
        })
    }

    /// Returns the metadata associated with the storage object.
    pub fn headers(&self) -> &HashMap<String, String> {
        return &self.headers;
    }

    /// Returns the bytes of the storage object.
    pub fn body(&mut self) -> Vec<u8> {
        match &self.body {
            Some(body_vec) => body_vec.clone(),
            None => Vec::new(),
        }
    }
}

fn get_body_from_host() -> Result<Vec<u8>, StorageError> {
    let mut err: i32 = 0;
    let response = unsafe { storage_response_get_body(&mut err) };

    if response > 0 {
        Ok(super::result::get_result_bytes(response).unwrap())
    } else if response == 0 {
        Ok(Vec::with_capacity(0))
    } else {
        return Err(StorageError::from(Error::from_i32(err).unwrap()));
    }
}

fn get_all_headers_from_host() -> Result<HashMap<String, String>, StorageError> {
    let mut err: i32 = 0;
    let result_size = unsafe { storage_response_get_headers(&mut err) };

    if result_size > 0 {
        let result = super::result::get_result_bytes(result_size).unwrap();
        let res: HashMap<String, String> = serde_json::from_slice(&result).unwrap();
        Ok(res)
    } else if result_size == 0 {
        return Ok(HashMap::new());
    } else {
        return Err(StorageError::from(Error::from_i32(err).unwrap()));
    }
}