use std::sync::atomic::{AtomicUsize, Ordering};
use actix::Message;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::proxy_error::ProxyResult;
static COUNT: AtomicUsize = AtomicUsize::new(1);
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct WrappedMessage<M>
where
M: Clone,
{
pub id: usize,
pub message: M,
}
impl<M> WrappedMessage<M>
where
M: Clone + Serialize + DeserializeOwned,
{
pub fn new(message: M) -> Self {
Self {
message,
id: COUNT.fetch_add(1, Ordering::Relaxed),
}
}
pub fn answer<A>(&self, message: A) -> WrappedMessage<A>
where
A: Clone + Serialize + DeserializeOwned,
{
WrappedMessage {
message,
id: self.id,
}
}
pub fn into_value(self) -> WrappedMessage<Value> {
WrappedMessage::<Value>::identified(serde_json::to_value(self.message).unwrap(), self.id)
}
pub fn into_specific<S>(self) -> ProxyResult<WrappedMessage<S>>
where
S: Clone + Serialize + DeserializeOwned,
{
let id = self.id;
let message: S = serde_json::from_value::<S>(self.into_value().message)?;
Ok(WrappedMessage::<S>::identified(message, id))
}
pub fn into_inner(self) -> M {
self.message
}
fn identified(message: M, id: usize) -> WrappedMessage<M> {
Self { message, id }
}
}
impl Message for WrappedMessage<ProxyRequest> {
type Result = ();
}
impl Message for WrappedMessage<ProxyResponse> {
type Result = ();
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ProxyRequest {
pub method: String,
pub url: String,
pub origin: String,
pub request_body: Value,
pub username: String,
pub password: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct ProxyResponse {
pub response: Value,
pub content_type: String,
}
pub struct WebsocketCommand(pub WebsocketSignal);
impl Message for WebsocketCommand {
type Result = ();
}
pub enum WebsocketSignal {
Close,
CheckPing,
Ping,
}