1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use crate::errors::*;
use crate::transport::Transport;
use crate::tcp::TcpTransport;
use crate::protocol::{MessageType, ReplyData, RequestData, Identity, Encapsulation};
use crate::encoding::FromBytes;

pub struct Proxy {
    pub transport: Box<dyn Transport + 'static>,
    pub request_id: i32
}

impl Proxy {
    pub fn new(proxy_string: &str) -> Result<Proxy, Box<dyn std::error::Error>> {
        // TODO: parse real proxy string
        Ok(Proxy {
            transport: Box::new(TcpTransport::new(proxy_string)?),
            request_id: 0
        })
    }

    pub fn create_request(&mut self, identity_name: &str, operation: &str, mode: u8, params: &Encapsulation) -> RequestData {
        self.request_id = self.request_id + 1;
        RequestData {
            request_id: self.request_id,
            id: Identity {
                name: String::from(identity_name),
                category: String::from("")
            },
            facet: Vec::new(),
            operation: String::from(operation),
            mode: mode,
            context: std::collections::HashMap::new(),
            params: params.clone()
        }
    }

    pub fn make_request<T: 'static + std::fmt::Debug + std::fmt::Display + FromBytes>(&mut self, request: &RequestData) -> Result<ReplyData, Box<dyn std::error::Error>>
    {
        self.transport.make_request(request)?;
        let reply = self.transport.read_message()?;
        match reply {
            MessageType::Reply(_header, reply) => {
                match reply.status {
                    1 => {
                        let mut read = 0;
                        Err(Box::new(UserError {
                            exception: T::from_bytes(&reply.body.data, &mut read)?
                        }))
                    }
                    _ => Ok(reply)
                }
            },
            _ => Err(Box::new(ProtocolError {}))
        }
    }
}