use crate::message::Context;
use crate::runtime::{client, InVariable, Result, RobomotionError};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Credential {
#[serde(default)]
pub scope: String,
#[serde(default)]
pub name: Value,
#[serde(default, rename = "vaultId")]
pub vault_id: String,
#[serde(default, rename = "itemId")]
pub item_id: String,
}
#[derive(Debug, Clone, Deserialize)]
struct CredentialRef {
#[serde(rename = "vaultId")]
vault_id: String,
#[serde(rename = "itemId")]
item_id: String,
}
impl Credential {
pub async fn get(&self, ctx: &Context) -> Result<HashMap<String, Value>> {
if !self.vault_id.is_empty() && !self.item_id.is_empty() {
return client::get_vault_item(&self.vault_id, &self.item_id).await;
}
let creds = self.get_credential_ref(ctx).await?;
client::get_vault_item(&creds.vault_id, &creds.item_id).await
}
pub async fn set(&self, ctx: &Context, data: &[u8]) -> Result<HashMap<String, Value>> {
if !self.vault_id.is_empty() && !self.item_id.is_empty() {
return client::set_vault_item(&self.vault_id, &self.item_id, data).await;
}
let creds = self.get_credential_ref(ctx).await?;
client::set_vault_item(&creds.vault_id, &creds.item_id, data).await
}
async fn get_credential_ref(&self, ctx: &Context) -> Result<CredentialRef> {
let value = if self.scope == "Message" {
let name = self
.name
.as_str()
.ok_or_else(|| RobomotionError::Variable("Invalid credential name".to_string()))?;
let var: InVariable<Value> = InVariable::new(
self.scope.clone(),
Value::String(name.to_string()),
);
var.get(ctx).await?
} else {
self.name.clone()
};
serde_json::from_value(value).map_err(|e| {
RobomotionError::Variable(format!("Invalid credential reference: {}", e))
})
}
}