use crate::protos::prelude::*;
use crate::protos::service;
pub struct ServiceMessage {
pub circuit: String,
pub service_id: String,
pub payload: ServiceMessagePayload,
}
pub enum ServiceMessagePayload {
ConnectRequest(ServiceConnectRequest),
ConnectResponse(ServiceConnectResponse),
DisconnectRequest(ServiceDisconnectRequest),
DisconnectResponse(ServiceDisconnectResponse),
ServiceProcessorMessage(ServiceProcessorMessage),
}
pub struct ServiceConnectRequest {
pub correlation_id: String,
}
pub struct ServiceConnectResponse {
pub correlation_id: String,
pub status: ConnectResponseStatus,
}
pub enum ConnectResponseStatus {
Ok,
CircuitDoesNotExist(String),
ServiceNotInCircuitRegistry(String),
ServiceAlreadyRegistered(String),
NotAnAllowedNode(String),
InternalError(String),
QueueFull,
}
pub struct ServiceDisconnectRequest {
pub correlation_id: String,
}
pub struct ServiceDisconnectResponse {
pub correlation_id: String,
pub status: DisconnectResponseStatus,
}
pub enum DisconnectResponseStatus {
Ok,
CircuitDoesNotExist(String),
ServiceNotInCircuitRegistry(String),
ServiceNotRegistered(String),
QueueFull,
InternalError(String),
}
pub struct ServiceProcessorMessage {
pub sender: String,
pub recipient: String,
pub payload: Vec<u8>,
}
impl FromProto<service::SMConnectRequest> for ServiceConnectRequest {
fn from_proto(mut req: service::SMConnectRequest) -> Result<Self, ProtoConversionError> {
Ok(Self {
correlation_id: req.take_correlation_id(),
})
}
}
impl FromNative<ServiceConnectRequest> for service::SMConnectRequest {
fn from_native(req: ServiceConnectRequest) -> Result<Self, ProtoConversionError> {
let mut proto_req = service::SMConnectRequest::new();
proto_req.set_correlation_id(req.correlation_id);
Ok(proto_req)
}
}
impl FromProto<service::SMConnectResponse> for ServiceConnectResponse {
fn from_proto(mut res: service::SMConnectResponse) -> Result<Self, ProtoConversionError> {
use service::SMConnectResponse_Status::*;
Ok(Self {
correlation_id: res.take_correlation_id(),
status: match res.get_status() {
OK => ConnectResponseStatus::Ok,
ERROR_CIRCUIT_DOES_NOT_EXIST => {
ConnectResponseStatus::CircuitDoesNotExist(res.take_error_message())
}
ERROR_SERVICE_NOT_IN_CIRCUIT_REGISTRY => {
ConnectResponseStatus::ServiceNotInCircuitRegistry(res.take_error_message())
}
ERROR_SERVICE_ALREADY_REGISTERED => {
ConnectResponseStatus::ServiceAlreadyRegistered(res.take_error_message())
}
ERROR_NOT_AN_ALLOWED_NODE => {
ConnectResponseStatus::NotAnAllowedNode(res.take_error_message())
}
ERROR_QUEUE_FULL => ConnectResponseStatus::QueueFull,
ERROR_INTERNAL_ERROR => {
ConnectResponseStatus::InternalError(res.take_error_message())
}
UNSET_STATUS => {
return Err(ProtoConversionError::InvalidTypeError(
"no status was set".into(),
))
}
},
})
}
}
impl FromNative<ServiceConnectResponse> for service::SMConnectResponse {
fn from_native(res: ServiceConnectResponse) -> Result<Self, ProtoConversionError> {
let mut proto_res = service::SMConnectResponse::new();
proto_res.set_correlation_id(res.correlation_id);
use service::SMConnectResponse_Status::*;
match res.status {
ConnectResponseStatus::Ok => proto_res.set_status(OK),
ConnectResponseStatus::CircuitDoesNotExist(msg) => {
proto_res.set_status(ERROR_CIRCUIT_DOES_NOT_EXIST);
proto_res.set_error_message(msg);
}
ConnectResponseStatus::ServiceNotInCircuitRegistry(msg) => {
proto_res.set_status(ERROR_SERVICE_NOT_IN_CIRCUIT_REGISTRY);
proto_res.set_error_message(msg);
}
ConnectResponseStatus::ServiceAlreadyRegistered(msg) => {
proto_res.set_status(ERROR_SERVICE_ALREADY_REGISTERED);
proto_res.set_error_message(msg);
}
ConnectResponseStatus::NotAnAllowedNode(msg) => {
proto_res.set_status(ERROR_NOT_AN_ALLOWED_NODE);
proto_res.set_error_message(msg);
}
ConnectResponseStatus::InternalError(msg) => {
proto_res.set_status(ERROR_INTERNAL_ERROR);
proto_res.set_error_message(msg);
}
ConnectResponseStatus::QueueFull => proto_res.set_status(ERROR_QUEUE_FULL),
}
Ok(proto_res)
}
}
impl FromProto<service::SMDisconnectRequest> for ServiceDisconnectRequest {
fn from_proto(mut req: service::SMDisconnectRequest) -> Result<Self, ProtoConversionError> {
Ok(Self {
correlation_id: req.take_correlation_id(),
})
}
}
impl FromNative<ServiceDisconnectRequest> for service::SMDisconnectRequest {
fn from_native(req: ServiceDisconnectRequest) -> Result<Self, ProtoConversionError> {
let mut proto_req = service::SMDisconnectRequest::new();
proto_req.set_correlation_id(req.correlation_id);
Ok(proto_req)
}
}
impl FromProto<service::SMDisconnectResponse> for ServiceDisconnectResponse {
fn from_proto(mut res: service::SMDisconnectResponse) -> Result<Self, ProtoConversionError> {
use service::SMDisconnectResponse_Status::*;
Ok(Self {
correlation_id: res.take_correlation_id(),
status: match res.get_status() {
OK => DisconnectResponseStatus::Ok,
ERROR_CIRCUIT_DOES_NOT_EXIST => {
DisconnectResponseStatus::CircuitDoesNotExist(res.take_error_message())
}
ERROR_SERVICE_NOT_IN_CIRCUIT_REGISTRY => {
DisconnectResponseStatus::ServiceNotInCircuitRegistry(res.take_error_message())
}
ERROR_SERVICE_NOT_REGISTERED => {
DisconnectResponseStatus::ServiceNotRegistered(res.take_error_message())
}
ERROR_INTERNAL_ERROR => {
DisconnectResponseStatus::InternalError(res.take_error_message())
}
ERROR_QUEUE_FULL => DisconnectResponseStatus::QueueFull,
UNSET_STATUS => {
return Err(ProtoConversionError::InvalidTypeError(
"no status was set".into(),
))
}
},
})
}
}
impl FromNative<ServiceDisconnectResponse> for service::SMDisconnectResponse {
fn from_native(res: ServiceDisconnectResponse) -> Result<Self, ProtoConversionError> {
let mut proto_res = service::SMDisconnectResponse::new();
proto_res.set_correlation_id(res.correlation_id);
use service::SMDisconnectResponse_Status::*;
match res.status {
DisconnectResponseStatus::Ok => proto_res.set_status(OK),
DisconnectResponseStatus::CircuitDoesNotExist(msg) => {
proto_res.set_status(ERROR_CIRCUIT_DOES_NOT_EXIST);
proto_res.set_error_message(msg);
}
DisconnectResponseStatus::ServiceNotInCircuitRegistry(msg) => {
proto_res.set_status(ERROR_SERVICE_NOT_IN_CIRCUIT_REGISTRY);
proto_res.set_error_message(msg);
}
DisconnectResponseStatus::ServiceNotRegistered(msg) => {
proto_res.set_status(ERROR_SERVICE_NOT_REGISTERED);
proto_res.set_error_message(msg);
}
DisconnectResponseStatus::InternalError(msg) => {
proto_res.set_status(ERROR_INTERNAL_ERROR);
proto_res.set_error_message(msg);
}
DisconnectResponseStatus::QueueFull => proto_res.set_status(ERROR_QUEUE_FULL),
}
Ok(proto_res)
}
}
impl FromProto<service::ServiceProcessorMessage> for ServiceProcessorMessage {
fn from_proto(mut msg: service::ServiceProcessorMessage) -> Result<Self, ProtoConversionError> {
Ok(Self {
sender: msg.take_sender(),
recipient: msg.take_recipient(),
payload: msg.take_payload(),
})
}
}
impl FromNative<ServiceProcessorMessage> for service::ServiceProcessorMessage {
fn from_native(msg: ServiceProcessorMessage) -> Result<Self, ProtoConversionError> {
let mut proto_msg = service::ServiceProcessorMessage::new();
proto_msg.set_sender(msg.sender);
proto_msg.set_recipient(msg.recipient);
proto_msg.set_payload(msg.payload);
Ok(proto_msg)
}
}
impl FromProto<service::ServiceMessage> for ServiceMessage {
fn from_proto(mut msg: service::ServiceMessage) -> Result<Self, ProtoConversionError> {
let circuit = msg.take_circuit();
let service_id = msg.take_service_id();
use service::ServiceMessageType::*;
let bytes = msg.get_payload();
let payload = match msg.get_message_type() {
SM_SERVICE_CONNECT_REQUEST => {
ServiceMessagePayload::ConnectRequest(
FromBytes::<service::SMConnectRequest>::from_bytes(bytes)?,
)
}
SM_SERVICE_CONNECT_RESPONSE => {
ServiceMessagePayload::ConnectResponse(
FromBytes::<service::SMConnectResponse>::from_bytes(bytes)?,
)
}
SM_SERVICE_DISCONNECT_REQUEST => {
ServiceMessagePayload::DisconnectRequest(
FromBytes::<service::SMDisconnectRequest>::from_bytes(bytes)?,
)
}
SM_SERVICE_DISCONNECT_RESPONSE => ServiceMessagePayload::DisconnectResponse(
FromBytes::<service::SMDisconnectResponse>::from_bytes(bytes)?,
),
SM_SERVICE_PROCESSOR_MESSAGE => {
ServiceMessagePayload::ServiceProcessorMessage(FromBytes::<
service::ServiceProcessorMessage,
>::from_bytes(bytes)?)
}
UNSET_SERVICE_MESSAGE_TYPE => {
return Err(ProtoConversionError::InvalidTypeError(
"missing message type".into(),
));
}
};
Ok(Self {
circuit,
service_id,
payload,
})
}
}
impl FromNative<ServiceMessage> for service::ServiceMessage {
fn from_native(msg: ServiceMessage) -> Result<Self, ProtoConversionError> {
let mut proto_msg = service::ServiceMessage::new();
proto_msg.set_circuit(msg.circuit);
proto_msg.set_service_id(msg.service_id);
use service::ServiceMessageType::*;
match msg.payload {
ServiceMessagePayload::ConnectRequest(req) => {
proto_msg.set_message_type(SM_SERVICE_CONNECT_REQUEST);
proto_msg.set_payload(IntoBytes::<service::SMConnectRequest>::into_bytes(req)?);
}
ServiceMessagePayload::ConnectResponse(req) => {
proto_msg.set_message_type(SM_SERVICE_CONNECT_RESPONSE);
proto_msg.set_payload(IntoBytes::<service::SMConnectResponse>::into_bytes(req)?);
}
ServiceMessagePayload::DisconnectRequest(req) => {
proto_msg.set_message_type(SM_SERVICE_DISCONNECT_REQUEST);
proto_msg.set_payload(IntoBytes::<service::SMDisconnectRequest>::into_bytes(req)?);
}
ServiceMessagePayload::DisconnectResponse(req) => {
proto_msg.set_message_type(SM_SERVICE_DISCONNECT_RESPONSE);
proto_msg.set_payload(IntoBytes::<service::SMDisconnectResponse>::into_bytes(req)?);
}
ServiceMessagePayload::ServiceProcessorMessage(msg) => {
proto_msg.set_message_type(SM_SERVICE_PROCESSOR_MESSAGE);
proto_msg.set_payload(IntoBytes::<service::ServiceProcessorMessage>::into_bytes(
msg,
)?);
}
}
Ok(proto_msg)
}
}