use std::collections::HashMap;
use prost_types::Any;
use serde::{Deserialize, Serialize};
use crate::api::{Metadata, Payload};
use crate::common::constants::INTERNAL_MODULE;
pub trait RequestTrait {
fn headers(&self) -> HashMap<String, String>;
fn request_type(&self) -> &'static str {
""
}
fn body(&self) -> Vec<u8>
where
Self: Serialize,
{
serde_json::to_vec(self).unwrap_or_default()
}
fn insert_headers(&mut self, headers: HashMap<String, String>);
fn request_id(&self) -> String {
String::default()
}
fn to_payload(&self, client_ip: &str) -> Payload
where
Self: Serialize,
{
let mut headers = self.headers();
headers.insert("requestId".to_string(), self.request_id());
Payload {
metadata: Some(Metadata {
r#type: self.request_type().to_string(),
client_ip: client_ip.to_string(),
headers,
}),
body: Some(Any {
type_url: String::new(),
value: self.body(),
}),
}
}
fn from_payload<T>(value: &Payload) -> T
where
T: for<'a> Deserialize<'a> + Default,
{
value
.body
.as_ref()
.and_then(|body| serde_json::from_slice::<T>(&body.value).ok())
.unwrap_or_default()
}
}
pub trait ResponseTrait {
fn response_type(&self) -> &'static str {
""
}
fn set_request_id(&mut self, request_id: String);
fn error_code(&self) -> i32 {
ResponseCode::Success.code()
}
fn result_code(&self) -> i32;
fn message(&self) -> String {
String::default()
}
fn is_success(&self) -> bool {
self.result_code() == ResponseCode::Success.code()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResponseCode {
Success = 200,
Fail = 500,
}
impl ResponseCode {
pub fn code(&self) -> i32 {
*self as i32
}
pub fn desc(&self) -> &'static str {
match self {
ResponseCode::Success => "Response ok",
ResponseCode::Fail => "Response fail",
}
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientAbilities {}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Request {
#[serde(skip)]
pub headers: HashMap<String, String>,
pub request_id: String,
}
impl Request {
pub fn new() -> Self {
Self {
headers: HashMap::new(),
request_id: crate::common::generate_request_id(),
}
}
}
impl RequestTrait for Request {
fn headers(&self) -> HashMap<String, String> {
self.headers.clone()
}
fn insert_headers(&mut self, headers: HashMap<String, String>) {
self.headers.extend(headers);
}
fn request_id(&self) -> String {
self.request_id.clone()
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InternalRequest {
#[serde(flatten)]
pub request: Request,
pub module: String,
}
impl InternalRequest {
pub fn new() -> Self {
Self {
request: Request::new(),
module: INTERNAL_MODULE.to_string(),
}
}
}
impl RequestTrait for InternalRequest {
fn headers(&self) -> HashMap<String, String> {
self.request.headers()
}
fn insert_headers(&mut self, headers: HashMap<String, String>) {
self.request.insert_headers(headers);
}
fn request_id(&self) -> String {
self.request.request_id.clone()
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Response {
pub result_code: i32,
pub error_code: i32,
pub success: bool,
pub message: String,
pub request_id: String,
}
impl Response {
pub fn new() -> Self {
Self {
result_code: ResponseCode::Success.code(),
success: true,
..Default::default()
}
}
}
impl ResponseTrait for Response {
fn set_request_id(&mut self, request_id: String) {
self.request_id = request_id;
}
fn error_code(&self) -> i32 {
self.error_code
}
fn result_code(&self) -> i32 {
self.result_code
}
fn message(&self) -> String {
self.message.clone()
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConnectionSetupRequest {
#[serde(flatten)]
pub internal_request: InternalRequest,
pub client_version: String,
pub tenant: String,
pub labels: HashMap<String, String>,
pub client_abilities: ClientAbilities,
}
impl ConnectionSetupRequest {
pub fn new() -> Self {
Self {
internal_request: InternalRequest::new(),
client_version: crate::common::CLIENT_VERSION.to_string(),
labels: HashMap::new(),
..Default::default()
}
}
pub fn with_labels(mut self, labels: HashMap<String, String>) -> Self {
self.labels = labels;
self
}
pub fn with_tenant(mut self, tenant: String) -> Self {
self.tenant = tenant;
self
}
}
impl RequestTrait for ConnectionSetupRequest {
fn headers(&self) -> HashMap<String, String> {
self.internal_request.headers()
}
fn request_type(&self) -> &'static str {
"ConnectionSetupRequest"
}
fn insert_headers(&mut self, headers: HashMap<String, String>) {
self.internal_request.insert_headers(headers);
}
fn request_id(&self) -> String {
self.internal_request.request_id()
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ServerCheckRequest {
#[serde(flatten)]
pub internal_request: InternalRequest,
}
impl ServerCheckRequest {
pub fn new() -> Self {
Self {
internal_request: InternalRequest::new(),
}
}
}
impl RequestTrait for ServerCheckRequest {
fn headers(&self) -> HashMap<String, String> {
self.internal_request.headers()
}
fn request_type(&self) -> &'static str {
"ServerCheckRequest"
}
fn insert_headers(&mut self, headers: HashMap<String, String>) {
self.internal_request.insert_headers(headers);
}
fn request_id(&self) -> String {
self.internal_request.request_id()
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ServerCheckResponse {
#[serde(flatten)]
pub response: Response,
pub connection_id: String,
pub support_ability_negotiation: bool,
}
impl ResponseTrait for ServerCheckResponse {
fn response_type(&self) -> &'static str {
"ServerCheckResponse"
}
fn set_request_id(&mut self, request_id: String) {
self.response.request_id = request_id;
}
fn error_code(&self) -> i32 {
self.response.error_code
}
fn result_code(&self) -> i32 {
self.response.result_code
}
fn message(&self) -> String {
self.response.message.clone()
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct HealthCheckRequest {
#[serde(flatten)]
pub internal_request: InternalRequest,
}
impl HealthCheckRequest {
pub fn new() -> Self {
Self {
internal_request: InternalRequest::new(),
}
}
}
impl RequestTrait for HealthCheckRequest {
fn headers(&self) -> HashMap<String, String> {
self.internal_request.headers()
}
fn request_type(&self) -> &'static str {
"HealthCheckRequest"
}
fn insert_headers(&mut self, headers: HashMap<String, String>) {
self.internal_request.insert_headers(headers);
}
fn request_id(&self) -> String {
self.internal_request.request_id()
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct HealthCheckResponse {
#[serde(flatten)]
pub response: Response,
}
impl ResponseTrait for HealthCheckResponse {
fn response_type(&self) -> &'static str {
"HealthCheckResponse"
}
fn set_request_id(&mut self, request_id: String) {
self.response.request_id = request_id;
}
fn error_code(&self) -> i32 {
self.response.error_code
}
fn result_code(&self) -> i32 {
self.response.result_code
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientDetectionRequest {
#[serde(flatten)]
pub internal_request: InternalRequest,
}
impl RequestTrait for ClientDetectionRequest {
fn headers(&self) -> HashMap<String, String> {
self.internal_request.headers()
}
fn request_type(&self) -> &'static str {
"ClientDetectionRequest"
}
fn insert_headers(&mut self, headers: HashMap<String, String>) {
self.internal_request.insert_headers(headers);
}
fn request_id(&self) -> String {
self.internal_request.request_id()
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientDetectionResponse {
#[serde(flatten)]
pub response: Response,
}
impl ClientDetectionResponse {
pub fn new() -> Self {
Self {
response: Response::new(),
}
}
}
impl ResponseTrait for ClientDetectionResponse {
fn response_type(&self) -> &'static str {
"ClientDetectionResponse"
}
fn set_request_id(&mut self, request_id: String) {
self.response.request_id = request_id;
}
fn error_code(&self) -> i32 {
self.response.error_code
}
fn result_code(&self) -> i32 {
self.response.result_code
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConnectResetRequest {
#[serde(flatten)]
pub internal_request: InternalRequest,
pub server_ip: String,
pub server_port: String,
}
impl RequestTrait for ConnectResetRequest {
fn headers(&self) -> HashMap<String, String> {
self.internal_request.headers()
}
fn request_type(&self) -> &'static str {
"ConnectResetRequest"
}
fn insert_headers(&mut self, headers: HashMap<String, String>) {
self.internal_request.insert_headers(headers);
}
fn request_id(&self) -> String {
self.internal_request.request_id()
}
}