ng_net/actors/app/
request.rs

1/*
2 * Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
3 * All rights reserved.
4 * Licensed under the Apache License, Version 2.0
5 * <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
6 * or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
7 * at your option. All files in the project carrying such
8 * notice may not be copied, modified, or distributed except
9 * according to those terms.
10*/
11
12use std::sync::Arc;
13
14use async_std::sync::Mutex;
15
16use ng_repo::errors::*;
17use ng_repo::log::*;
18
19use crate::app_protocol::*;
20use crate::broker::BROKER;
21use crate::connection::NoiseFSM;
22use crate::types::*;
23use crate::{actor::*, types::ProtocolMessage};
24
25impl AppRequest {
26    pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {
27        Actor::<AppRequest, AppResponse>::new_responder(id)
28    }
29}
30
31impl TryFrom<ProtocolMessage> for AppRequest {
32    type Error = ProtocolError;
33    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
34        if let AppMessageContentV0::Request(req) = msg.try_into()? {
35            Ok(req)
36        } else {
37            log_debug!("INVALID AppMessageContentV0::Request");
38            Err(ProtocolError::InvalidValue)
39        }
40    }
41}
42
43impl From<AppRequest> for ProtocolMessage {
44    fn from(request: AppRequest) -> ProtocolMessage {
45        AppMessageContentV0::Request(request).into()
46    }
47}
48
49impl From<AppMessageContentV0> for ProtocolMessage {
50    fn from(content: AppMessageContentV0) -> ProtocolMessage {
51        AppMessage::V0(AppMessageV0 {
52            content,
53            id: 0,
54            result: 0,
55        })
56        .into()
57    }
58}
59
60impl TryFrom<ProtocolMessage> for AppResponse {
61    type Error = ProtocolError;
62    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
63        if let AppMessageContentV0::Response(res) = msg.try_into()? {
64            Ok(res)
65        } else {
66            log_err!("INVALID AppMessageContentV0::Response");
67            Err(ProtocolError::InvalidValue)
68        }
69    }
70}
71
72impl TryFrom<ProtocolMessage> for AppMessageContentV0 {
73    type Error = ProtocolError;
74    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
75        if let ProtocolMessage::AppMessage(AppMessage::V0(AppMessageV0 {
76            content, result, ..
77        })) = msg
78        {
79            let err = ServerError::try_from(result).unwrap();
80            if !err.is_err() {
81                Ok(content)
82            } else {
83                Err(ProtocolError::ServerError)
84            }
85        } else {
86            log_err!("INVALID AppMessageContentV0 {:?}", msg);
87            Err(ProtocolError::InvalidValue)
88        }
89    }
90}
91
92impl From<AppResponse> for AppMessage {
93    fn from(response: AppResponse) -> AppMessage {
94        AppMessage::V0(AppMessageV0 {
95            content: AppMessageContentV0::Response(response),
96            id: 0,
97            result: 0,
98        })
99    }
100}
101
102impl From<AppResponse> for ProtocolMessage {
103    fn from(response: AppResponse) -> ProtocolMessage {
104        let app_msg: AppMessage = response.into();
105        app_msg.into()
106    }
107}
108
109impl Actor<'_, AppRequest, AppResponse> {}
110
111#[async_trait::async_trait]
112impl EActor for Actor<'_, AppRequest, AppResponse> {
113    async fn respond(
114        &mut self,
115        msg: ProtocolMessage,
116        fsm: Arc<Mutex<NoiseFSM>>,
117    ) -> Result<(), ProtocolError> {
118        let req = AppRequest::try_from(msg)?;
119        let res = {
120            let sb = { BROKER.read().await.get_server_broker()? };
121            let lock = sb.read().await;
122            lock.app_process_request(req, self.id(), &fsm).await
123        };
124        if res.is_err() {
125            let server_err: ServerError = res.unwrap_err().into();
126            let app_message: AppMessage = server_err.into();
127            fsm.lock()
128                .await
129                .send_in_reply_to(app_message.into(), self.id())
130                .await?;
131        }
132        Ok(())
133    }
134}