use crate::{db_connectors, Client, Context};
use csml_interpreter::data::{csml_bot::CsmlBot, Message};
use curl::easy::Easy;
use serde::{Deserialize, Serialize};
use serde_json::Value;
pub const DEBUG: &str = "DEBUG";
pub const DISABLE_SSL_VERIFY: &str = "DISABLE_SSL_VERIFY";
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RunRequest {
pub bot: Option<CsmlBot>,
pub bot_id: Option<String>,
pub version_id: Option<String>,
pub fn_endpoint: Option<String>,
pub event: CsmlRequest,
}
impl RunRequest {
pub fn get_bot_opt(&self) -> Result<BotOpt, EngineError> {
match self.clone() {
RunRequest{
bot: Some(csml_bot),
..
} => Ok(BotOpt::CsmlBot(csml_bot)),
RunRequest{
version_id: Some(version_id),
bot_id: Some(bot_id),
fn_endpoint,
..
} => Ok(BotOpt::Id{ version_id, bot_id, fn_endpoint}),
RunRequest{
bot_id: Some(bot_id),
fn_endpoint,
..
} => Ok(BotOpt::BotId{bot_id, fn_endpoint}),
_ => Err(EngineError::Format("bot bad format".to_owned()))
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum BotOpt {
#[serde(rename = "bot")]
CsmlBot(CsmlBot),
#[serde(rename = "version_id")]
Id {
version_id: String,
bot_id: String,
fn_endpoint: Option<String>,
},
#[serde(rename = "bot_id")]
BotId {
bot_id: String,
fn_endpoint: Option<String>,
},
}
impl BotOpt {
pub fn search_bot(&self, db: &mut Database) -> CsmlBot {
match self {
BotOpt::CsmlBot(csml_bot) => csml_bot.to_owned(),
BotOpt::BotId {
bot_id,
fn_endpoint,
} => {
let mut bot_version = db_connectors::bot::get_last_bot_version(&bot_id, db)
.unwrap()
.unwrap();
bot_version.bot.fn_endpoint = fn_endpoint.to_owned();
bot_version.bot
}
BotOpt::Id {
version_id,
bot_id,
fn_endpoint,
} => {
let mut bot_version = db_connectors::bot::get_by_version_id(&version_id, &bot_id, db)
.unwrap()
.unwrap();
bot_version.bot.fn_endpoint = fn_endpoint.to_owned();
bot_version.bot
}
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CsmlRequest {
pub request_id: String,
pub client: Client,
pub callback_url: Option<String>,
pub payload: serde_json::Value,
pub metadata: serde_json::Value,
}
pub enum Database {
#[cfg(feature = "mongo")]
Mongo(mongodb::Database),
#[cfg(feature = "dynamo")]
Dynamodb(DynamoDbClient),
None,
}
#[cfg(feature = "dynamo")]
pub struct DynamoDbClient {
pub client: rusoto_dynamodb::DynamoDbClient,
pub runtime: tokio::runtime::Runtime,
}
#[cfg(feature = "dynamo")]
impl DynamoDbClient {
pub fn new(region: rusoto_core::Region) -> Self {
Self {
client: rusoto_dynamodb::DynamoDbClient::new(region),
runtime: { tokio::runtime::Runtime::new().unwrap() },
}
}
}
pub struct ConversationInfo {
pub request_id: String,
pub curl: Option<Easy>,
pub conversation_id: String,
pub interaction_id: String,
pub client: Client,
pub context: Context,
pub metadata: Value,
pub messages: Vec<Message>,
pub db: Database,
}
#[derive(Debug)]
pub enum Next {
Flow(String),
Step(String),
Hold, End,
Error,
}
#[derive(Debug)]
pub enum EngineError {
Serde(serde_json::Error),
Io(std::io::Error),
Manager(String),
Format(String),
Interpreter(String),
Time(std::time::SystemTimeError),
Openssl(openssl::error::ErrorStack),
Base64(base64::DecodeError),
#[cfg(any(feature = "mongo"))]
BsonDecoder(bson::DecoderError),
#[cfg(any(feature = "mongo"))]
BsonEncoder(bson::EncoderError),
#[cfg(any(feature = "mongo"))]
MongoDB(mongodb::error::Error),
#[cfg(any(feature = "dynamo"))]
Rusoto(String),
#[cfg(any(feature = "dynamo"))]
SerdeDynamodb(serde_dynamodb::Error),
}
impl From<serde_json::Error> for EngineError {
fn from(e: serde_json::Error) -> Self {
EngineError::Serde(e)
}
}
impl From<std::io::Error> for EngineError {
fn from(e: std::io::Error) -> Self {
EngineError::Io(e)
}
}
impl From<std::time::SystemTimeError> for EngineError {
fn from(e: std::time::SystemTimeError) -> Self {
EngineError::Time(e)
}
}
impl From<openssl::error::ErrorStack> for EngineError {
fn from(e: openssl::error::ErrorStack) -> Self {
EngineError::Openssl(e)
}
}
impl From<base64::DecodeError> for EngineError {
fn from(e: base64::DecodeError) -> Self {
EngineError::Base64(e)
}
}
#[cfg(any(feature = "mongo"))]
impl From<bson::EncoderError> for EngineError {
fn from(e: bson::EncoderError) -> Self {
EngineError::BsonEncoder(e)
}
}
#[cfg(any(feature = "mongo"))]
impl From<bson::DecoderError> for EngineError {
fn from(e: bson::DecoderError) -> Self {
EngineError::BsonDecoder(e)
}
}
#[cfg(any(feature = "mongo"))]
impl From<mongodb::error::Error> for EngineError {
fn from(e: mongodb::error::Error) -> Self {
EngineError::MongoDB(e)
}
}
#[cfg(any(feature = "dynamo"))]
impl<E: std::error::Error + 'static> From<rusoto_core::RusotoError<E>> for EngineError {
fn from(e: rusoto_core::RusotoError<E>) -> Self {
EngineError::Rusoto(e.to_string())
}
}
#[cfg(any(feature = "dynamo"))]
impl From<serde_dynamodb::Error> for EngineError {
fn from(e: serde_dynamodb::Error) -> Self {
EngineError::SerdeDynamodb(e)
}
}